aboutsummaryrefslogtreecommitdiffstats
path: root/include/lldb/Target
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-01-02 19:26:05 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-01-02 19:26:05 +0000
commit14f1b3e8826ce43b978db93a62d1166055db5394 (patch)
tree0a00ad8d3498783fe0193f3b656bca17c4c8697d /include/lldb/Target
parent4ee8c119c71a06dcad1e0fecc8c675e480e59337 (diff)
downloadsrc-14f1b3e8826ce43b978db93a62d1166055db5394.tar.gz
src-14f1b3e8826ce43b978db93a62d1166055db5394.zip
Vendor import of lldb trunk r290819:vendor/lldb/lldb-trunk-r290819
Notes
Notes: svn path=/vendor/lldb/dist/; revision=311128 svn path=/vendor/lldb/lldb-trunk-r290819/; revision=311129; tag=vendor/lldb/lldb-trunk-r290819
Diffstat (limited to 'include/lldb/Target')
-rw-r--r--include/lldb/Target/ABI.h236
-rw-r--r--include/lldb/Target/CPPLanguageRuntime.h51
-rw-r--r--include/lldb/Target/DynamicLoader.h527
-rw-r--r--include/lldb/Target/ExecutionContext.h1297
-rw-r--r--include/lldb/Target/ExecutionContextScope.h48
-rw-r--r--include/lldb/Target/FileAction.h71
-rw-r--r--include/lldb/Target/InstrumentationRuntime.h99
-rw-r--r--include/lldb/Target/InstrumentationRuntimeStopInfo.h46
-rw-r--r--include/lldb/Target/JITLoader.h94
-rw-r--r--include/lldb/Target/JITLoaderList.h33
-rw-r--r--include/lldb/Target/Language.h409
-rw-r--r--include/lldb/Target/LanguageRuntime.h292
-rw-r--r--include/lldb/Target/Memory.h309
-rw-r--r--include/lldb/Target/MemoryHistory.h26
-rw-r--r--include/lldb/Target/MemoryRegionInfo.h232
-rw-r--r--include/lldb/Target/ObjCLanguageRuntime.h796
-rw-r--r--include/lldb/Target/OperatingSystem.h120
-rw-r--r--include/lldb/Target/PathMappingList.h252
-rw-r--r--include/lldb/Target/Platform.h2443
-rw-r--r--include/lldb/Target/Process.h6328
-rw-r--r--include/lldb/Target/ProcessInfo.h251
-rw-r--r--include/lldb/Target/ProcessLaunchInfo.h356
-rw-r--r--include/lldb/Target/Queue.h305
-rw-r--r--include/lldb/Target/QueueItem.h324
-rw-r--r--include/lldb/Target/QueueList.h196
-rw-r--r--include/lldb/Target/RegisterCheckpoint.h88
-rw-r--r--include/lldb/Target/RegisterContext.h438
-rw-r--r--include/lldb/Target/SectionLoadHistory.h130
-rw-r--r--include/lldb/Target/SectionLoadList.h85
-rw-r--r--include/lldb/Target/StackFrame.h998
-rw-r--r--include/lldb/Target/StackFrameList.h203
-rw-r--r--include/lldb/Target/StackID.h176
-rw-r--r--include/lldb/Target/StopInfo.h394
-rw-r--r--include/lldb/Target/StructuredDataPlugin.h188
-rw-r--r--include/lldb/Target/SystemRuntime.h593
-rw-r--r--include/lldb/Target/Target.h2711
-rw-r--r--include/lldb/Target/TargetList.h429
-rw-r--r--include/lldb/Target/Thread.h2701
-rw-r--r--include/lldb/Target/ThreadCollection.h85
-rw-r--r--include/lldb/Target/ThreadList.h282
-rw-r--r--include/lldb/Target/ThreadPlan.h1029
-rw-r--r--include/lldb/Target/ThreadPlanBase.h53
-rw-r--r--include/lldb/Target/ThreadPlanCallFunction.h292
-rw-r--r--include/lldb/Target/ThreadPlanCallFunctionUsingABI.h34
-rw-r--r--include/lldb/Target/ThreadPlanCallOnFunctionExit.h56
-rw-r--r--include/lldb/Target/ThreadPlanCallUserExpression.h79
-rw-r--r--include/lldb/Target/ThreadPlanPython.h54
-rw-r--r--include/lldb/Target/ThreadPlanRunToAddress.h72
-rw-r--r--include/lldb/Target/ThreadPlanShouldStopHere.h216
-rw-r--r--include/lldb/Target/ThreadPlanStepInRange.h171
-rw-r--r--include/lldb/Target/ThreadPlanStepInstruction.h58
-rw-r--r--include/lldb/Target/ThreadPlanStepOut.h135
-rw-r--r--include/lldb/Target/ThreadPlanStepOverBreakpoint.h53
-rw-r--r--include/lldb/Target/ThreadPlanStepOverRange.h50
-rw-r--r--include/lldb/Target/ThreadPlanStepRange.h119
-rw-r--r--include/lldb/Target/ThreadPlanStepThrough.h70
-rw-r--r--include/lldb/Target/ThreadPlanStepUntil.h82
-rw-r--r--include/lldb/Target/ThreadPlanTracer.h152
-rw-r--r--include/lldb/Target/ThreadSpec.h217
-rw-r--r--include/lldb/Target/UnixSignals.h167
-rw-r--r--include/lldb/Target/Unwind.h129
-rw-r--r--include/lldb/Target/UnwindAssembly.h51
62 files changed, 12984 insertions, 14997 deletions
diff --git a/include/lldb/Target/ABI.h b/include/lldb/Target/ABI.h
index cd0b57e61ff8..8a1243613616 100644
--- a/include/lldb/Target/ABI.h
+++ b/include/lldb/Target/ABI.h
@@ -22,145 +22,125 @@
#include "llvm/ADT/ArrayRef.h"
// forward define the llvm::Type class
-namespace llvm { class Type; }
+namespace llvm {
+class Type;
+}
namespace lldb_private {
-class ABI :
- public PluginInterface
-{
+class ABI : public PluginInterface {
public:
-
- struct CallArgument
- {
- enum eType
- {
- HostPointer = 0, /* pointer to host data */
- TargetValue , /* value is on the target or literal */
- };
- eType type; /* value of eType */
- size_t size; /* size in bytes of this argument */
-
- lldb::addr_t value; /* literal value */
- std::unique_ptr<uint8_t[]> data_ap; /* host data pointer */
+ struct CallArgument {
+ enum eType {
+ HostPointer = 0, /* pointer to host data */
+ TargetValue, /* value is on the target or literal */
};
+ eType type; /* value of eType */
+ size_t size; /* size in bytes of this argument */
+
+ lldb::addr_t value; /* literal value */
+ std::unique_ptr<uint8_t[]> data_ap; /* host data pointer */
+ };
+
+ ~ABI() override;
+
+ virtual size_t GetRedZoneSize() const = 0;
+
+ virtual bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp,
+ lldb::addr_t functionAddress,
+ lldb::addr_t returnAddress,
+ llvm::ArrayRef<lldb::addr_t> args) const = 0;
+
+ // Prepare trivial call used from ThreadPlanFunctionCallUsingABI
+ // AD:
+ // . Because i don't want to change other ABI's this is not declared pure
+ // virtual.
+ // The dummy implementation will simply fail. Only HexagonABI will
+ // currently
+ // use this method.
+ // . Two PrepareTrivialCall's is not good design so perhaps this should be
+ // combined.
+ //
+ virtual bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp,
+ lldb::addr_t functionAddress,
+ lldb::addr_t returnAddress,
+ llvm::Type &prototype,
+ llvm::ArrayRef<CallArgument> args) const;
+
+ virtual bool GetArgumentValues(Thread &thread, ValueList &values) const = 0;
+
+ lldb::ValueObjectSP GetReturnValueObject(Thread &thread, CompilerType &type,
+ bool persistent = true) const;
+
+ // specialized to work with llvm IR types
+ lldb::ValueObjectSP GetReturnValueObject(Thread &thread, llvm::Type &type,
+ bool persistent = true) const;
+
+ // Set the Return value object in the current frame as though a function with
+ virtual Error SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value) = 0;
- ~ABI() override;
-
- virtual size_t
- GetRedZoneSize () const = 0;
-
- virtual bool
- PrepareTrivialCall ( lldb_private::Thread &thread,
- lldb::addr_t sp,
- lldb::addr_t functionAddress,
- lldb::addr_t returnAddress,
- llvm::ArrayRef<lldb::addr_t> args) const = 0;
-
- // Prepare trivial call used from ThreadPlanFunctionCallUsingABI
- // AD:
- // . Because i don't want to change other ABI's this is not declared pure virtual.
- // The dummy implementation will simply fail. Only HexagonABI will currently
- // use this method.
- // . Two PrepareTrivialCall's is not good design so perhaps this should be combined.
- //
- virtual bool
- PrepareTrivialCall ( lldb_private::Thread &thread,
- lldb::addr_t sp,
- lldb::addr_t functionAddress,
- lldb::addr_t returnAddress,
- llvm::Type &prototype,
- llvm::ArrayRef<CallArgument> args) const;
-
- virtual bool
- GetArgumentValues (Thread &thread,
- ValueList &values) const = 0;
-
- lldb::ValueObjectSP
- GetReturnValueObject (Thread &thread,
- CompilerType &type,
- bool persistent = true) const;
-
- // specialized to work with llvm IR types
- lldb::ValueObjectSP
- GetReturnValueObject (Thread &thread,
- llvm::Type &type,
- bool persistent = true) const;
-
- // Set the Return value object in the current frame as though a function with
- virtual Error
- SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) = 0;
-
-protected:
- // This is the method the ABI will call to actually calculate the return value.
- // Don't put it in a persistent value object, that will be done by the ABI::GetReturnValueObject.
- virtual lldb::ValueObjectSP
- GetReturnValueObjectImpl (Thread &thread, CompilerType &ast_type) const = 0;
-
- // specialized to work with llvm IR types
- virtual lldb::ValueObjectSP
- GetReturnValueObjectImpl( Thread &thread, llvm::Type &ir_type ) const;
+protected:
+ // This is the method the ABI will call to actually calculate the return
+ // value.
+ // Don't put it in a persistent value object, that will be done by the
+ // ABI::GetReturnValueObject.
+ virtual lldb::ValueObjectSP
+ GetReturnValueObjectImpl(Thread &thread, CompilerType &ast_type) const = 0;
+
+ // specialized to work with llvm IR types
+ virtual lldb::ValueObjectSP
+ GetReturnValueObjectImpl(Thread &thread, llvm::Type &ir_type) const;
public:
- virtual bool
- CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan) = 0;
-
- virtual bool
- CreateDefaultUnwindPlan (UnwindPlan &unwind_plan) = 0;
-
- virtual bool
- RegisterIsVolatile (const RegisterInfo *reg_info) = 0;
-
- virtual bool
- GetFallbackRegisterLocation (const RegisterInfo *reg_info,
- UnwindPlan::Row::RegisterLocation &unwind_regloc);
-
- // Should take a look at a call frame address (CFA) which is just the stack
- // pointer value upon entry to a function. ABIs usually impose alignment
- // restrictions (4, 8 or 16 byte aligned), and zero is usually not allowed.
- // This function should return true if "cfa" is valid call frame address for
- // the ABI, and false otherwise. This is used by the generic stack frame unwinding
- // code to help determine when a stack ends.
- virtual bool
- CallFrameAddressIsValid (lldb::addr_t cfa) = 0;
-
- // Validates a possible PC value and returns true if an opcode can be at "pc".
- virtual bool
- CodeAddressIsValid (lldb::addr_t pc) = 0;
-
- virtual lldb::addr_t
- FixCodeAddress (lldb::addr_t pc)
- {
- // Some targets might use bits in a code address to indicate
- // a mode switch. ARM uses bit zero to signify a code address is
- // thumb, so any ARM ABI plug-ins would strip those bits.
- return pc;
- }
-
- virtual const RegisterInfo *
- GetRegisterInfoArray (uint32_t &count) = 0;
-
- bool
- GetRegisterInfoByName (const ConstString &name, RegisterInfo &info);
-
- bool
- GetRegisterInfoByKind (lldb::RegisterKind reg_kind,
- uint32_t reg_num,
- RegisterInfo &info);
-
- static lldb::ABISP
- FindPlugin (const ArchSpec &arch);
-
-protected:
+ virtual bool CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) = 0;
- //------------------------------------------------------------------
- // Classes that inherit from ABI can see and modify these
- //------------------------------------------------------------------
- ABI();
+ virtual bool CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) = 0;
-private:
+ virtual bool RegisterIsVolatile(const RegisterInfo *reg_info) = 0;
+
+ virtual bool
+ GetFallbackRegisterLocation(const RegisterInfo *reg_info,
+ UnwindPlan::Row::RegisterLocation &unwind_regloc);
+
+ // Should take a look at a call frame address (CFA) which is just the stack
+ // pointer value upon entry to a function. ABIs usually impose alignment
+ // restrictions (4, 8 or 16 byte aligned), and zero is usually not allowed.
+ // This function should return true if "cfa" is valid call frame address for
+ // the ABI, and false otherwise. This is used by the generic stack frame
+ // unwinding
+ // code to help determine when a stack ends.
+ virtual bool CallFrameAddressIsValid(lldb::addr_t cfa) = 0;
+
+ // Validates a possible PC value and returns true if an opcode can be at "pc".
+ virtual bool CodeAddressIsValid(lldb::addr_t pc) = 0;
+
+ virtual lldb::addr_t FixCodeAddress(lldb::addr_t pc) {
+ // Some targets might use bits in a code address to indicate
+ // a mode switch. ARM uses bit zero to signify a code address is
+ // thumb, so any ARM ABI plug-ins would strip those bits.
+ return pc;
+ }
- DISALLOW_COPY_AND_ASSIGN (ABI);
+ virtual const RegisterInfo *GetRegisterInfoArray(uint32_t &count) = 0;
+
+ bool GetRegisterInfoByName(const ConstString &name, RegisterInfo &info);
+
+ bool GetRegisterInfoByKind(lldb::RegisterKind reg_kind, uint32_t reg_num,
+ RegisterInfo &info);
+
+ virtual bool GetPointerReturnRegister(const char *&name) { return false; }
+
+ static lldb::ABISP FindPlugin(const ArchSpec &arch);
+
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from ABI can see and modify these
+ //------------------------------------------------------------------
+ ABI();
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(ABI);
};
} // namespace lldb_private
diff --git a/include/lldb/Target/CPPLanguageRuntime.h b/include/lldb/Target/CPPLanguageRuntime.h
index 788f4e60a493..aae85f420ef7 100644
--- a/include/lldb/Target/CPPLanguageRuntime.h
+++ b/include/lldb/Target/CPPLanguageRuntime.h
@@ -1,4 +1,5 @@
-//===-- CPPLanguageRuntime.h ---------------------------------------------------*- C++ -*-===//
+//===-- CPPLanguageRuntime.h
+//---------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,42 +17,34 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Core/PluginInterface.h"
-#include "lldb/lldb-private.h"
#include "lldb/Target/LanguageRuntime.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
-class CPPLanguageRuntime :
- public LanguageRuntime
-{
+class CPPLanguageRuntime : public LanguageRuntime {
public:
- ~CPPLanguageRuntime() override;
-
- lldb::LanguageType
- GetLanguageType() const override
- {
- return lldb::eLanguageTypeC_plus_plus;
- }
-
- virtual bool
- IsVTableName (const char *name) = 0;
-
- bool
- GetObjectDescription(Stream &str, ValueObject &object) override;
-
- bool
- GetObjectDescription(Stream &str, Value &value, ExecutionContextScope *exe_scope) override;
-
-protected:
+ ~CPPLanguageRuntime() override;
- //------------------------------------------------------------------
- // Classes that inherit from CPPLanguageRuntime can see and modify these
- //------------------------------------------------------------------
- CPPLanguageRuntime(Process *process);
+ lldb::LanguageType GetLanguageType() const override {
+ return lldb::eLanguageTypeC_plus_plus;
+ }
-private:
+ virtual bool IsVTableName(const char *name) = 0;
+
+ bool GetObjectDescription(Stream &str, ValueObject &object) override;
- DISALLOW_COPY_AND_ASSIGN (CPPLanguageRuntime);
+ bool GetObjectDescription(Stream &str, Value &value,
+ ExecutionContextScope *exe_scope) override;
+
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from CPPLanguageRuntime can see and modify these
+ //------------------------------------------------------------------
+ CPPLanguageRuntime(Process *process);
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(CPPLanguageRuntime);
};
} // namespace lldb_private
diff --git a/include/lldb/Target/DynamicLoader.h b/include/lldb/Target/DynamicLoader.h
index 2c4956829b29..071cbe69d880 100644
--- a/include/lldb/Target/DynamicLoader.h
+++ b/include/lldb/Target/DynamicLoader.h
@@ -11,9 +11,10 @@
#define liblldb_DynamicLoader_h_
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/PluginInterface.h"
+#include "lldb/Core/UUID.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
@@ -32,285 +33,313 @@ namespace lldb_private {
///
/// Breakpoints can also be set in the process which can register
/// functions that get called using:
-/// Process::BreakpointSetCallback (lldb::user_id_t, BreakpointHitCallback, void *).
+/// Process::BreakpointSetCallback (lldb::user_id_t, BreakpointHitCallback, void
+/// *).
/// These breakpoint callbacks return a boolean value that indicates if
/// the process should continue or halt and should return the global
/// setting for this using:
/// DynamicLoader::StopWhenImagesChange() const.
//----------------------------------------------------------------------
-class DynamicLoader :
- public PluginInterface
-{
+class DynamicLoader : public PluginInterface {
public:
- //------------------------------------------------------------------
- /// Find a dynamic loader plugin for a given process.
- ///
- /// Scans the installed DynamicLoader plug-ins and tries to find
- /// an instance that can be used to track image changes in \a
- /// process.
- ///
- /// @param[in] process
- /// The process for which to try and locate a dynamic loader
- /// plug-in instance.
- ///
- /// @param[in] plugin_name
- /// An optional name of a specific dynamic loader plug-in that
- /// should be used. If NULL, pick the best plug-in.
- //------------------------------------------------------------------
- static DynamicLoader*
- FindPlugin (Process *process, const char *plugin_name);
+ //------------------------------------------------------------------
+ /// Find a dynamic loader plugin for a given process.
+ ///
+ /// Scans the installed DynamicLoader plug-ins and tries to find
+ /// an instance that can be used to track image changes in \a
+ /// process.
+ ///
+ /// @param[in] process
+ /// The process for which to try and locate a dynamic loader
+ /// plug-in instance.
+ ///
+ /// @param[in] plugin_name
+ /// An optional name of a specific dynamic loader plug-in that
+ /// should be used. If NULL, pick the best plug-in.
+ //------------------------------------------------------------------
+ static DynamicLoader *FindPlugin(Process *process, const char *plugin_name);
- //------------------------------------------------------------------
- /// Construct with a process.
- //------------------------------------------------------------------
- DynamicLoader (Process *process);
+ //------------------------------------------------------------------
+ /// Construct with a process.
+ //------------------------------------------------------------------
+ DynamicLoader(Process *process);
- //------------------------------------------------------------------
- /// Destructor.
- ///
- /// The destructor is virtual since this class is designed to be
- /// inherited from by the plug-in instance.
- //------------------------------------------------------------------
- virtual ~DynamicLoader() override;
+ //------------------------------------------------------------------
+ /// Destructor.
+ ///
+ /// The destructor is virtual since this class is designed to be
+ /// inherited from by the plug-in instance.
+ //------------------------------------------------------------------
+ virtual ~DynamicLoader() override;
- //------------------------------------------------------------------
- /// Called after attaching a process.
- ///
- /// Allow DynamicLoader plug-ins to execute some code after
- /// attaching to a process.
- //------------------------------------------------------------------
- virtual void
- DidAttach () = 0;
+ //------------------------------------------------------------------
+ /// Called after attaching a process.
+ ///
+ /// Allow DynamicLoader plug-ins to execute some code after
+ /// attaching to a process.
+ //------------------------------------------------------------------
+ virtual void DidAttach() = 0;
- //------------------------------------------------------------------
- /// Called after launching a process.
- ///
- /// Allow DynamicLoader plug-ins to execute some code after
- /// the process has stopped for the first time on launch.
- //------------------------------------------------------------------
- virtual void
- DidLaunch () = 0;
-
-
- //------------------------------------------------------------------
- /// Helper function that can be used to detect when a process has
- /// called exec and is now a new and different process. This can
- /// be called when necessary to try and detect the exec. The process
- /// might be able to answer this question, but sometimes it might
- /// not be able and the dynamic loader often knows what the program
- /// entry point is. So the process and the dynamic loader can work
- /// together to detect this.
- //------------------------------------------------------------------
- virtual bool
- ProcessDidExec ()
- {
- return false;
- }
- //------------------------------------------------------------------
- /// Get whether the process should stop when images change.
- ///
- /// When images (executables and shared libraries) get loaded or
- /// unloaded, often debug sessions will want to try and resolve or
- /// unresolve breakpoints that are set in these images. Any
- /// breakpoints set by DynamicLoader plug-in instances should
- /// return this value to ensure consistent debug session behaviour.
- ///
- /// @return
- /// Returns \b true if the process should stop when images
- /// change, \b false if the process should resume.
- //------------------------------------------------------------------
- bool
- GetStopWhenImagesChange () const;
+ //------------------------------------------------------------------
+ /// Called after launching a process.
+ ///
+ /// Allow DynamicLoader plug-ins to execute some code after
+ /// the process has stopped for the first time on launch.
+ //------------------------------------------------------------------
+ virtual void DidLaunch() = 0;
- //------------------------------------------------------------------
- /// Set whether the process should stop when images change.
- ///
- /// When images (executables and shared libraries) get loaded or
- /// unloaded, often debug sessions will want to try and resolve or
- /// unresolve breakpoints that are set in these images. The default
- /// is set so that the process stops when images change, but this
- /// can be overridden using this function callback.
- ///
- /// @param[in] stop
- /// Boolean value that indicates whether the process should stop
- /// when images change.
- //------------------------------------------------------------------
- void
- SetStopWhenImagesChange (bool stop);
+ //------------------------------------------------------------------
+ /// Helper function that can be used to detect when a process has
+ /// called exec and is now a new and different process. This can
+ /// be called when necessary to try and detect the exec. The process
+ /// might be able to answer this question, but sometimes it might
+ /// not be able and the dynamic loader often knows what the program
+ /// entry point is. So the process and the dynamic loader can work
+ /// together to detect this.
+ //------------------------------------------------------------------
+ virtual bool ProcessDidExec() { return false; }
+ //------------------------------------------------------------------
+ /// Get whether the process should stop when images change.
+ ///
+ /// When images (executables and shared libraries) get loaded or
+ /// unloaded, often debug sessions will want to try and resolve or
+ /// unresolve breakpoints that are set in these images. Any
+ /// breakpoints set by DynamicLoader plug-in instances should
+ /// return this value to ensure consistent debug session behaviour.
+ ///
+ /// @return
+ /// Returns \b true if the process should stop when images
+ /// change, \b false if the process should resume.
+ //------------------------------------------------------------------
+ bool GetStopWhenImagesChange() const;
- //------------------------------------------------------------------
- /// Provides a plan to step through the dynamic loader trampoline
- /// for the current state of \a thread.
- ///
- ///
- /// @param[in] stop_others
- /// Whether the plan should be set to stop other threads.
- ///
- /// @return
- /// A pointer to the plan (caller owned) or NULL if we are not at such
- /// a trampoline.
- //------------------------------------------------------------------
- virtual lldb::ThreadPlanSP
- GetStepThroughTrampolinePlan (Thread &thread, bool stop_others) = 0;
+ //------------------------------------------------------------------
+ /// Set whether the process should stop when images change.
+ ///
+ /// When images (executables and shared libraries) get loaded or
+ /// unloaded, often debug sessions will want to try and resolve or
+ /// unresolve breakpoints that are set in these images. The default
+ /// is set so that the process stops when images change, but this
+ /// can be overridden using this function callback.
+ ///
+ /// @param[in] stop
+ /// Boolean value that indicates whether the process should stop
+ /// when images change.
+ //------------------------------------------------------------------
+ void SetStopWhenImagesChange(bool stop);
+ //------------------------------------------------------------------
+ /// Provides a plan to step through the dynamic loader trampoline
+ /// for the current state of \a thread.
+ ///
+ ///
+ /// @param[in] stop_others
+ /// Whether the plan should be set to stop other threads.
+ ///
+ /// @return
+ /// A pointer to the plan (caller owned) or NULL if we are not at such
+ /// a trampoline.
+ //------------------------------------------------------------------
+ virtual lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread,
+ bool stop_others) = 0;
- //------------------------------------------------------------------
- /// Some dynamic loaders provide features where there are a group of symbols "equivalent to"
- /// a given symbol one of which will be chosen when the symbol is bound. If you want to
- /// set a breakpoint on one of these symbols, you really need to set it on all the
- /// equivalent symbols.
- ///
- ///
- /// @param[in] original_symbol
- /// The symbol for which we are finding equivalences.
- ///
- /// @param[in] module_list
- /// The set of modules in which to search.
- ///
- /// @param[out] equivalent_symbols
- /// The equivalent symbol list - any equivalent symbols found are appended to this list.
- ///
- /// @return
- /// Number of equivalent symbols found.
- //------------------------------------------------------------------
- virtual size_t
- FindEquivalentSymbols (Symbol *original_symbol, ModuleList &module_list, SymbolContextList &equivalent_symbols)
- {
- return 0;
- }
+ //------------------------------------------------------------------
+ /// Some dynamic loaders provide features where there are a group of symbols
+ /// "equivalent to"
+ /// a given symbol one of which will be chosen when the symbol is bound. If
+ /// you want to
+ /// set a breakpoint on one of these symbols, you really need to set it on all
+ /// the
+ /// equivalent symbols.
+ ///
+ ///
+ /// @param[in] original_symbol
+ /// The symbol for which we are finding equivalences.
+ ///
+ /// @param[in] module_list
+ /// The set of modules in which to search.
+ ///
+ /// @param[out] equivalent_symbols
+ /// The equivalent symbol list - any equivalent symbols found are appended
+ /// to this list.
+ ///
+ /// @return
+ /// Number of equivalent symbols found.
+ //------------------------------------------------------------------
+ virtual size_t FindEquivalentSymbols(Symbol *original_symbol,
+ ModuleList &module_list,
+ SymbolContextList &equivalent_symbols) {
+ return 0;
+ }
- //------------------------------------------------------------------
- /// Ask if it is ok to try and load or unload an shared library
- /// (image).
- ///
- /// The dynamic loader often knows when it would be ok to try and
- /// load or unload a shared library. This function call allows the
- /// dynamic loader plug-ins to check any current dyld state to make
- /// sure it is an ok time to load a shared library.
- ///
- /// @return
- /// \b true if it is currently ok to try and load a shared
- /// library into the process, \b false otherwise.
- //------------------------------------------------------------------
- virtual Error
- CanLoadImage () = 0;
+ //------------------------------------------------------------------
+ /// Ask if it is ok to try and load or unload an shared library
+ /// (image).
+ ///
+ /// The dynamic loader often knows when it would be ok to try and
+ /// load or unload a shared library. This function call allows the
+ /// dynamic loader plug-ins to check any current dyld state to make
+ /// sure it is an ok time to load a shared library.
+ ///
+ /// @return
+ /// \b true if it is currently ok to try and load a shared
+ /// library into the process, \b false otherwise.
+ //------------------------------------------------------------------
+ virtual Error CanLoadImage() = 0;
- //------------------------------------------------------------------
- /// Ask if the eh_frame information for the given SymbolContext should
- /// be relied on even when it's the first frame in a stack unwind.
- ///
- /// The CFI instructions from the eh_frame section are normally only
- /// valid at call sites -- places where a program could throw an
- /// exception and need to unwind out. But some Modules may be known
- /// to the system as having reliable eh_frame information at all call
- /// sites. This would be the case if the Module's contents are largely
- /// hand-written assembly with hand-written eh_frame information.
- /// Normally when unwinding from a function at the beginning of a stack
- /// unwind lldb will examine the assembly instructions to understand
- /// how the stack frame is set up and where saved registers are stored.
- /// But with hand-written assembly this is not reliable enough -- we need
- /// to consult those function's hand-written eh_frame information.
- ///
- /// @return
- /// \b True if the symbol context should use eh_frame instructions
- /// unconditionally when unwinding from this frame. Else \b false,
- /// the normal lldb unwind behavior of only using eh_frame when the
- /// function appears in the middle of the stack.
- //------------------------------------------------------------------
- virtual bool
- AlwaysRelyOnEHUnwindInfo (SymbolContext &sym_ctx)
- {
- return false;
- }
+ //------------------------------------------------------------------
+ /// Ask if the eh_frame information for the given SymbolContext should
+ /// be relied on even when it's the first frame in a stack unwind.
+ ///
+ /// The CFI instructions from the eh_frame section are normally only
+ /// valid at call sites -- places where a program could throw an
+ /// exception and need to unwind out. But some Modules may be known
+ /// to the system as having reliable eh_frame information at all call
+ /// sites. This would be the case if the Module's contents are largely
+ /// hand-written assembly with hand-written eh_frame information.
+ /// Normally when unwinding from a function at the beginning of a stack
+ /// unwind lldb will examine the assembly instructions to understand
+ /// how the stack frame is set up and where saved registers are stored.
+ /// But with hand-written assembly this is not reliable enough -- we need
+ /// to consult those function's hand-written eh_frame information.
+ ///
+ /// @return
+ /// \b True if the symbol context should use eh_frame instructions
+ /// unconditionally when unwinding from this frame. Else \b false,
+ /// the normal lldb unwind behavior of only using eh_frame when the
+ /// function appears in the middle of the stack.
+ //------------------------------------------------------------------
+ virtual bool AlwaysRelyOnEHUnwindInfo(SymbolContext &sym_ctx) {
+ return false;
+ }
- //------------------------------------------------------------------
- /// Retrieves the per-module TLS block for a given thread.
- ///
- /// @param[in] module
- /// The module to query TLS data for.
- ///
- /// @param[in] thread
- /// The specific thread to query TLS data for.
- ///
- /// @return
- /// If the given thread has TLS data allocated for the
- /// module, the address of the TLS block. Otherwise
- /// LLDB_INVALID_ADDRESS is returned.
- //------------------------------------------------------------------
- virtual lldb::addr_t
- GetThreadLocalData(const lldb::ModuleSP module, const lldb::ThreadSP thread, lldb::addr_t tls_file_addr)
- {
- return LLDB_INVALID_ADDRESS;
- }
+ //------------------------------------------------------------------
+ /// Retrieves the per-module TLS block for a given thread.
+ ///
+ /// @param[in] module
+ /// The module to query TLS data for.
+ ///
+ /// @param[in] thread
+ /// The specific thread to query TLS data for.
+ ///
+ /// @return
+ /// If the given thread has TLS data allocated for the
+ /// module, the address of the TLS block. Otherwise
+ /// LLDB_INVALID_ADDRESS is returned.
+ //------------------------------------------------------------------
+ virtual lldb::addr_t GetThreadLocalData(const lldb::ModuleSP module,
+ const lldb::ThreadSP thread,
+ lldb::addr_t tls_file_addr) {
+ return LLDB_INVALID_ADDRESS;
+ }
- /// Locates or creates a module given by @p file and updates/loads the
- /// resulting module at the virtual base address @p base_addr.
- virtual lldb::ModuleSP
- LoadModuleAtAddress(const lldb_private::FileSpec &file,
- lldb::addr_t link_map_addr,
- lldb::addr_t base_addr,
- bool base_addr_is_offset);
+ /// Locates or creates a module given by @p file and updates/loads the
+ /// resulting module at the virtual base address @p base_addr.
+ virtual lldb::ModuleSP LoadModuleAtAddress(const lldb_private::FileSpec &file,
+ lldb::addr_t link_map_addr,
+ lldb::addr_t base_addr,
+ bool base_addr_is_offset);
+
+ //------------------------------------------------------------------
+ /// Get information about the shared cache for a process, if possible.
+ ///
+ /// On some systems (e.g. Darwin based systems), a set of libraries
+ /// that are common to most processes may be put in a single region
+ /// of memory and mapped into every process, this is called the
+ /// shared cache, as a performance optimization.
+ ///
+ /// Many targets will not have the concept of a shared cache.
+ ///
+ /// Depending on how the DynamicLoader gathers information about the
+ /// shared cache, it may be able to only return basic information -
+ /// like the UUID of the cache - or it may be able to return additional
+ /// information about the cache.
+ ///
+ /// @param[out] base_address
+ /// The base address (load address) of the shared cache.
+ /// LLDB_INVALID_ADDRESS if it cannot be determined.
+ ///
+ /// @param[out] uuid
+ /// The UUID of the shared cache, if it can be determined.
+ /// If the UUID cannot be fetched, IsValid() will be false.
+ ///
+ /// @param[out] using_shared_cache
+ /// If this process is using a shared cache.
+ /// If unknown, eLazyBoolCalculate is returned.
+ ///
+ /// @param[out] private_shared_cache
+ /// A LazyBool indicating whether this process is using a
+ /// private shared cache.
+ /// If this information cannot be fetched, eLazyBoolCalculate.
+ ///
+ /// @return
+ /// Returns false if this DynamicLoader cannot gather information
+ /// about the shared cache / has no concept of a shared cache.
+ //------------------------------------------------------------------
+ virtual bool GetSharedCacheInformation(lldb::addr_t &base_address, UUID &uuid,
+ LazyBool &using_shared_cache,
+ LazyBool &private_shared_cache) {
+ base_address = LLDB_INVALID_ADDRESS;
+ uuid.Clear();
+ using_shared_cache = eLazyBoolCalculate;
+ private_shared_cache = eLazyBoolCalculate;
+ return false;
+ }
protected:
- //------------------------------------------------------------------
- // Utility methods for derived classes
- //------------------------------------------------------------------
+ //------------------------------------------------------------------
+ // Utility methods for derived classes
+ //------------------------------------------------------------------
- /// Checks to see if the target module has changed, updates the target
- /// accordingly and returns the target executable module.
- lldb::ModuleSP
- GetTargetExecutable();
+ /// Checks to see if the target module has changed, updates the target
+ /// accordingly and returns the target executable module.
+ lldb::ModuleSP GetTargetExecutable();
- /// Updates the load address of every allocatable section in @p module.
- ///
- /// @param module The module to traverse.
- ///
- /// @param link_map_addr The virtual address of the link map for the @p module.
- ///
- /// @param base_addr The virtual base address @p module is loaded at.
- virtual void
- UpdateLoadedSections(lldb::ModuleSP module,
- lldb::addr_t link_map_addr,
- lldb::addr_t base_addr,
- bool base_addr_is_offset);
+ /// Updates the load address of every allocatable section in @p module.
+ ///
+ /// @param module The module to traverse.
+ ///
+ /// @param link_map_addr The virtual address of the link map for the @p
+ /// module.
+ ///
+ /// @param base_addr The virtual base address @p module is loaded at.
+ virtual void UpdateLoadedSections(lldb::ModuleSP module,
+ lldb::addr_t link_map_addr,
+ lldb::addr_t base_addr,
+ bool base_addr_is_offset);
- // Utility method so base classes can share implementation of UpdateLoadedSections
- void
- UpdateLoadedSectionsCommon(lldb::ModuleSP module,
- lldb::addr_t base_addr,
- bool base_addr_is_offset);
+ // Utility method so base classes can share implementation of
+ // UpdateLoadedSections
+ void UpdateLoadedSectionsCommon(lldb::ModuleSP module, lldb::addr_t base_addr,
+ bool base_addr_is_offset);
- /// Removes the loaded sections from the target in @p module.
- ///
- /// @param module The module to traverse.
- virtual void
- UnloadSections(const lldb::ModuleSP module);
+ /// Removes the loaded sections from the target in @p module.
+ ///
+ /// @param module The module to traverse.
+ virtual void UnloadSections(const lldb::ModuleSP module);
- // Utility method so base classes can share implementation of UnloadSections
- void
- UnloadSectionsCommon(const lldb::ModuleSP module);
+ // Utility method so base classes can share implementation of UnloadSections
+ void UnloadSectionsCommon(const lldb::ModuleSP module);
- const lldb_private::SectionList *
- GetSectionListFromModule(const lldb::ModuleSP module) const;
+ const lldb_private::SectionList *
+ GetSectionListFromModule(const lldb::ModuleSP module) const;
- // Read an unsigned int of the given size from memory at the given addr.
- // Return -1 if the read fails, otherwise return the result as an int64_t.
- int64_t
- ReadUnsignedIntWithSizeInBytes(lldb::addr_t addr, int size_in_bytes);
+ // Read an unsigned int of the given size from memory at the given addr.
+ // Return -1 if the read fails, otherwise return the result as an int64_t.
+ int64_t ReadUnsignedIntWithSizeInBytes(lldb::addr_t addr, int size_in_bytes);
- // Read a pointer from memory at the given addr.
- // Return LLDB_INVALID_ADDRESS if the read fails.
- lldb::addr_t
- ReadPointer(lldb::addr_t addr);
+ // Read a pointer from memory at the given addr.
+ // Return LLDB_INVALID_ADDRESS if the read fails.
+ lldb::addr_t ReadPointer(lldb::addr_t addr);
- //------------------------------------------------------------------
- // Member variables.
- //------------------------------------------------------------------
- Process* m_process; ///< The process that this dynamic loader plug-in is tracking.
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ Process
+ *m_process; ///< The process that this dynamic loader plug-in is tracking.
private:
-
- DISALLOW_COPY_AND_ASSIGN (DynamicLoader);
+ DISALLOW_COPY_AND_ASSIGN(DynamicLoader);
};
} // namespace lldb_private
diff --git a/include/lldb/Target/ExecutionContext.h b/include/lldb/Target/ExecutionContext.h
index da585e4c9dad..04af3ebc278d 100644
--- a/include/lldb/Target/ExecutionContext.h
+++ b/include/lldb/Target/ExecutionContext.h
@@ -16,26 +16,26 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/StackID.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
//===----------------------------------------------------------------------===//
/// Execution context objects refer to objects in the execution of the
-/// program that is being debugged. The consist of one or more of the
+/// program that is being debugged. The consist of one or more of the
/// following objects: target, process, thread, and frame. Many objects
/// in the debugger need to track different executions contexts. For
/// example, a local function variable might have an execution context
-/// that refers to a stack frame. A global or static variable might
+/// that refers to a stack frame. A global or static variable might
/// refer to a target since a stack frame isn't required in order to
/// evaluate a global or static variable (a process isn't necessarily
/// needed for a global variable since we might be able to read the
-/// variable value from a data section in one of the object files in
+/// variable value from a data section in one of the object files in
/// a target). There are two types of objects that hold onto execution
/// contexts: ExecutionContextRef and ExecutionContext. Both of these
/// objects are described below.
-///
+///
/// Not all objects in an ExectionContext objects will be valid. If you want
/// to refer strongly (ExectionContext) or weakly (ExectionContextRef) to
/// a process, then only the process and target references will be valid.
@@ -47,7 +47,8 @@ namespace lldb_private {
//===----------------------------------------------------------------------===//
//----------------------------------------------------------------------
-/// @class ExecutionContextRef ExecutionContext.h "lldb/Target/ExecutionContext.h"
+/// @class ExecutionContextRef ExecutionContext.h
+/// "lldb/Target/ExecutionContext.h"
/// @brief A class that holds a weak reference to an execution context.
///
/// ExecutionContextRef objects are designed to hold onto an execution
@@ -62,296 +63,267 @@ namespace lldb_private {
/// to a stack frame and a stack frame is no longer in a thread, then a
/// ExecutionContextRef object that refers to that frame will not be able
/// to get a shared pointer to those objects since they are no longer around.
-///
+///
/// ExecutionContextRef objects can also be used as objects in classes
-/// that want to track a "previous execution context". Since the weak
+/// that want to track a "previous execution context". Since the weak
/// references to the execution objects (target, process, thread and frame)
-/// don't keep these objects around, they are safe to keep around.
+/// don't keep these objects around, they are safe to keep around.
///
/// The general rule of thumb is all long lived objects that want to
/// refer to execution contexts should use ExecutionContextRef objects.
-/// The ExecutionContext class is used to temporarily get shared
+/// The ExecutionContext class is used to temporarily get shared
/// pointers to any execution context objects that are still around
/// so they are guaranteed to exist during a function that requires the
/// objects. ExecutionContext objects should NOT be used for long term
-/// storage since they will keep objects alive with extra shared pointer
+/// storage since they will keep objects alive with extra shared pointer
/// references to these objects.
//----------------------------------------------------------------------
-class ExecutionContextRef
-{
+class ExecutionContextRef {
public:
- //------------------------------------------------------------------
- /// Default Constructor.
- //------------------------------------------------------------------
- ExecutionContextRef();
-
- //------------------------------------------------------------------
- /// Copy Constructor.
- //------------------------------------------------------------------
- ExecutionContextRef (const ExecutionContextRef &rhs);
-
- //------------------------------------------------------------------
- /// Construct using an ExecutionContext object that might be nullptr.
- ///
- /// If \a exe_ctx_ptr is valid, then make weak references to any
- /// valid objects in the ExecutionContext, otherwise no weak
- /// references to any execution context objects will be made.
- //------------------------------------------------------------------
- ExecutionContextRef (const ExecutionContext *exe_ctx_ptr);
-
- //------------------------------------------------------------------
- /// Construct using an ExecutionContext object.
- ///
- /// Make weak references to any valid objects in the ExecutionContext.
- //------------------------------------------------------------------
- ExecutionContextRef (const ExecutionContext &exe_ctx);
-
- //------------------------------------------------------------------
- /// Construct using the target and all the selected items inside of it
- /// (the process and its selected thread, and the thread's selected
- /// frame). If there is no selected thread, default to the first thread
- /// If there is no selected frame, default to the first frame.
- //------------------------------------------------------------------
- ExecutionContextRef (Target *target, bool adopt_selected);
-
- //------------------------------------------------------------------
- /// Construct using an execution context scope.
- ///
- /// If the ExecutionContextScope object is valid and refers to a frame,
- /// make weak references too the frame, thread, process and target.
- /// If the ExecutionContextScope object is valid and refers to a thread,
- /// make weak references too the thread, process and target.
- /// If the ExecutionContextScope object is valid and refers to a process,
- /// make weak references too the process and target.
- /// If the ExecutionContextScope object is valid and refers to a target,
- /// make weak references too the target.
- //------------------------------------------------------------------
- ExecutionContextRef (ExecutionContextScope *exe_scope);
-
- //------------------------------------------------------------------
- /// Construct using an execution context scope.
- ///
- /// If the ExecutionContextScope object refers to a frame,
- /// make weak references too the frame, thread, process and target.
- /// If the ExecutionContextScope object refers to a thread,
- /// make weak references too the thread, process and target.
- /// If the ExecutionContextScope object refers to a process,
- /// make weak references too the process and target.
- /// If the ExecutionContextScope object refers to a target,
- /// make weak references too the target.
- //------------------------------------------------------------------
- ExecutionContextRef (ExecutionContextScope &exe_scope);
-
- ~ExecutionContextRef();
-
- //------------------------------------------------------------------
- /// Assignment operator
- ///
- /// Copy all weak references in \a rhs.
- //------------------------------------------------------------------
- ExecutionContextRef &
- operator =(const ExecutionContextRef &rhs);
-
- //------------------------------------------------------------------
- /// Assignment operator from a ExecutionContext
- ///
- /// Make weak references to any strongly referenced objects in \a exe_ctx.
- //------------------------------------------------------------------
- ExecutionContextRef &
- operator =(const ExecutionContext &exe_ctx);
-
- //------------------------------------------------------------------
- /// Clear the object's state.
- ///
- /// Sets the process and thread to nullptr, and the frame index to an
- /// invalid value.
- //------------------------------------------------------------------
- void
- Clear ();
-
- //------------------------------------------------------------------
- /// Set accessor that creates a weak reference to the target
- /// referenced in \a target_sp.
- ///
- /// If \a target_sp is valid this object will create a weak
- /// reference to that object, otherwise any previous target weak
- /// reference contained in this object will be reset.
- ///
- /// Only the weak reference to the target will be updated, no other
- /// weak references will be modified. If you want this execution
- /// context to make a weak reference to the target's process, use
- /// the ExecutionContextRef::SetContext() functions.
- ///
- /// @see ExecutionContextRef::SetContext(const lldb::TargetSP &, bool)
- //------------------------------------------------------------------
- void
- SetTargetSP (const lldb::TargetSP &target_sp);
-
- //------------------------------------------------------------------
- /// Set accessor that creates a weak reference to the process
- /// referenced in \a process_sp.
- ///
- /// If \a process_sp is valid this object will create a weak
- /// reference to that object, otherwise any previous process weak
- /// reference contained in this object will be reset.
- ///
- /// Only the weak reference to the process will be updated, no other
- /// weak references will be modified. If you want this execution
- /// context to make a weak reference to the target, use the
- /// ExecutionContextRef::SetContext() functions.
- ///
- /// @see ExecutionContextRef::SetContext(const lldb::ProcessSP &)
- //------------------------------------------------------------------
- void
- SetProcessSP (const lldb::ProcessSP &process_sp);
-
- //------------------------------------------------------------------
- /// Set accessor that creates a weak reference to the thread
- /// referenced in \a thread_sp.
- ///
- /// If \a thread_sp is valid this object will create a weak
- /// reference to that object, otherwise any previous thread weak
- /// reference contained in this object will be reset.
- ///
- /// Only the weak reference to the thread will be updated, no other
- /// weak references will be modified. If you want this execution
- /// context to make a weak reference to the thread's process and
- /// target, use the ExecutionContextRef::SetContext() functions.
- ///
- /// @see ExecutionContextRef::SetContext(const lldb::ThreadSP &)
- //------------------------------------------------------------------
- void
- SetThreadSP (const lldb::ThreadSP &thread_sp);
-
- //------------------------------------------------------------------
- /// Set accessor that creates a weak reference to the frame
- /// referenced in \a frame_sp.
- ///
- /// If \a frame_sp is valid this object will create a weak
- /// reference to that object, otherwise any previous frame weak
- /// reference contained in this object will be reset.
- ///
- /// Only the weak reference to the frame will be updated, no other
- /// weak references will be modified. If you want this execution
- /// context to make a weak reference to the frame's thread, process
- /// and target, use the ExecutionContextRef::SetContext() functions.
- ///
- /// @see ExecutionContextRef::SetContext(const lldb::StackFrameSP &)
- //------------------------------------------------------------------
- void
- SetFrameSP (const lldb::StackFrameSP &frame_sp);
-
- void
- SetTargetPtr (Target* target, bool adopt_selected);
-
- void
- SetProcessPtr (Process *process);
-
- void
- SetThreadPtr (Thread *thread);
-
- void
- SetFramePtr (StackFrame *frame);
-
- //------------------------------------------------------------------
- /// Get accessor that creates a strong reference from the weak target
- /// reference contained in this object.
- ///
- /// @returns
- /// A shared pointer to a target that is not guaranteed to be valid.
- //------------------------------------------------------------------
- lldb::TargetSP
- GetTargetSP () const;
-
- //------------------------------------------------------------------
- /// Get accessor that creates a strong reference from the weak process
- /// reference contained in this object.
- ///
- /// @returns
- /// A shared pointer to a process that is not guaranteed to be valid.
- //------------------------------------------------------------------
- lldb::ProcessSP
- GetProcessSP () const;
-
- //------------------------------------------------------------------
- /// Get accessor that creates a strong reference from the weak thread
- /// reference contained in this object.
- ///
- /// @returns
- /// A shared pointer to a thread that is not guaranteed to be valid.
- //------------------------------------------------------------------
- lldb::ThreadSP
- GetThreadSP () const;
-
- //------------------------------------------------------------------
- /// Get accessor that creates a strong reference from the weak frame
- /// reference contained in this object.
- ///
- /// @returns
- /// A shared pointer to a frame that is not guaranteed to be valid.
- //------------------------------------------------------------------
- lldb::StackFrameSP
- GetFrameSP () const;
-
- //------------------------------------------------------------------
- /// Create an ExecutionContext object from this object.
- ///
- /// Create strong references to any execution context objects that
- /// are still valid. Any of the returned shared pointers in the
- /// ExecutionContext objects is not guaranteed to be valid.
- /// @returns
- /// An execution context object that has strong references to
- /// any valid weak references in this object.
- //------------------------------------------------------------------
- ExecutionContext
- Lock (bool thread_and_frame_only_if_stopped) const;
-
- //------------------------------------------------------------------
- /// Returns true if this object has a weak reference to a thread.
- /// The return value is only an indication of whether this object has
- /// a weak reference and does not indicate whether the weak reference
- /// is valid or not.
- //------------------------------------------------------------------
- bool
- HasThreadRef () const
- {
- return m_tid != LLDB_INVALID_THREAD_ID;
- }
-
- //------------------------------------------------------------------
- /// Returns true if this object has a weak reference to a frame.
- /// The return value is only an indication of whether this object has
- /// a weak reference and does not indicate whether the weak reference
- /// is valid or not.
- //------------------------------------------------------------------
- bool
- HasFrameRef () const
- {
- return m_stack_id.IsValid();
- }
-
- void
- ClearThread ()
- {
- m_thread_wp.reset();
- m_tid = LLDB_INVALID_THREAD_ID;
- }
-
- void
- ClearFrame ()
- {
- m_stack_id.Clear();
- }
+ //------------------------------------------------------------------
+ /// Default Constructor.
+ //------------------------------------------------------------------
+ ExecutionContextRef();
+
+ //------------------------------------------------------------------
+ /// Copy Constructor.
+ //------------------------------------------------------------------
+ ExecutionContextRef(const ExecutionContextRef &rhs);
+
+ //------------------------------------------------------------------
+ /// Construct using an ExecutionContext object that might be nullptr.
+ ///
+ /// If \a exe_ctx_ptr is valid, then make weak references to any
+ /// valid objects in the ExecutionContext, otherwise no weak
+ /// references to any execution context objects will be made.
+ //------------------------------------------------------------------
+ ExecutionContextRef(const ExecutionContext *exe_ctx_ptr);
+
+ //------------------------------------------------------------------
+ /// Construct using an ExecutionContext object.
+ ///
+ /// Make weak references to any valid objects in the ExecutionContext.
+ //------------------------------------------------------------------
+ ExecutionContextRef(const ExecutionContext &exe_ctx);
+
+ //------------------------------------------------------------------
+ /// Construct using the target and all the selected items inside of it
+ /// (the process and its selected thread, and the thread's selected
+ /// frame). If there is no selected thread, default to the first thread
+ /// If there is no selected frame, default to the first frame.
+ //------------------------------------------------------------------
+ ExecutionContextRef(Target *target, bool adopt_selected);
+
+ //------------------------------------------------------------------
+ /// Construct using an execution context scope.
+ ///
+ /// If the ExecutionContextScope object is valid and refers to a frame,
+ /// make weak references too the frame, thread, process and target.
+ /// If the ExecutionContextScope object is valid and refers to a thread,
+ /// make weak references too the thread, process and target.
+ /// If the ExecutionContextScope object is valid and refers to a process,
+ /// make weak references too the process and target.
+ /// If the ExecutionContextScope object is valid and refers to a target,
+ /// make weak references too the target.
+ //------------------------------------------------------------------
+ ExecutionContextRef(ExecutionContextScope *exe_scope);
+
+ //------------------------------------------------------------------
+ /// Construct using an execution context scope.
+ ///
+ /// If the ExecutionContextScope object refers to a frame,
+ /// make weak references too the frame, thread, process and target.
+ /// If the ExecutionContextScope object refers to a thread,
+ /// make weak references too the thread, process and target.
+ /// If the ExecutionContextScope object refers to a process,
+ /// make weak references too the process and target.
+ /// If the ExecutionContextScope object refers to a target,
+ /// make weak references too the target.
+ //------------------------------------------------------------------
+ ExecutionContextRef(ExecutionContextScope &exe_scope);
+
+ ~ExecutionContextRef();
+
+ //------------------------------------------------------------------
+ /// Assignment operator
+ ///
+ /// Copy all weak references in \a rhs.
+ //------------------------------------------------------------------
+ ExecutionContextRef &operator=(const ExecutionContextRef &rhs);
+
+ //------------------------------------------------------------------
+ /// Assignment operator from a ExecutionContext
+ ///
+ /// Make weak references to any strongly referenced objects in \a exe_ctx.
+ //------------------------------------------------------------------
+ ExecutionContextRef &operator=(const ExecutionContext &exe_ctx);
+
+ //------------------------------------------------------------------
+ /// Clear the object's state.
+ ///
+ /// Sets the process and thread to nullptr, and the frame index to an
+ /// invalid value.
+ //------------------------------------------------------------------
+ void Clear();
+
+ //------------------------------------------------------------------
+ /// Set accessor that creates a weak reference to the target
+ /// referenced in \a target_sp.
+ ///
+ /// If \a target_sp is valid this object will create a weak
+ /// reference to that object, otherwise any previous target weak
+ /// reference contained in this object will be reset.
+ ///
+ /// Only the weak reference to the target will be updated, no other
+ /// weak references will be modified. If you want this execution
+ /// context to make a weak reference to the target's process, use
+ /// the ExecutionContextRef::SetContext() functions.
+ ///
+ /// @see ExecutionContextRef::SetContext(const lldb::TargetSP &, bool)
+ //------------------------------------------------------------------
+ void SetTargetSP(const lldb::TargetSP &target_sp);
+
+ //------------------------------------------------------------------
+ /// Set accessor that creates a weak reference to the process
+ /// referenced in \a process_sp.
+ ///
+ /// If \a process_sp is valid this object will create a weak
+ /// reference to that object, otherwise any previous process weak
+ /// reference contained in this object will be reset.
+ ///
+ /// Only the weak reference to the process will be updated, no other
+ /// weak references will be modified. If you want this execution
+ /// context to make a weak reference to the target, use the
+ /// ExecutionContextRef::SetContext() functions.
+ ///
+ /// @see ExecutionContextRef::SetContext(const lldb::ProcessSP &)
+ //------------------------------------------------------------------
+ void SetProcessSP(const lldb::ProcessSP &process_sp);
+
+ //------------------------------------------------------------------
+ /// Set accessor that creates a weak reference to the thread
+ /// referenced in \a thread_sp.
+ ///
+ /// If \a thread_sp is valid this object will create a weak
+ /// reference to that object, otherwise any previous thread weak
+ /// reference contained in this object will be reset.
+ ///
+ /// Only the weak reference to the thread will be updated, no other
+ /// weak references will be modified. If you want this execution
+ /// context to make a weak reference to the thread's process and
+ /// target, use the ExecutionContextRef::SetContext() functions.
+ ///
+ /// @see ExecutionContextRef::SetContext(const lldb::ThreadSP &)
+ //------------------------------------------------------------------
+ void SetThreadSP(const lldb::ThreadSP &thread_sp);
+
+ //------------------------------------------------------------------
+ /// Set accessor that creates a weak reference to the frame
+ /// referenced in \a frame_sp.
+ ///
+ /// If \a frame_sp is valid this object will create a weak
+ /// reference to that object, otherwise any previous frame weak
+ /// reference contained in this object will be reset.
+ ///
+ /// Only the weak reference to the frame will be updated, no other
+ /// weak references will be modified. If you want this execution
+ /// context to make a weak reference to the frame's thread, process
+ /// and target, use the ExecutionContextRef::SetContext() functions.
+ ///
+ /// @see ExecutionContextRef::SetContext(const lldb::StackFrameSP &)
+ //------------------------------------------------------------------
+ void SetFrameSP(const lldb::StackFrameSP &frame_sp);
+
+ void SetTargetPtr(Target *target, bool adopt_selected);
+
+ void SetProcessPtr(Process *process);
+
+ void SetThreadPtr(Thread *thread);
+
+ void SetFramePtr(StackFrame *frame);
+
+ //------------------------------------------------------------------
+ /// Get accessor that creates a strong reference from the weak target
+ /// reference contained in this object.
+ ///
+ /// @returns
+ /// A shared pointer to a target that is not guaranteed to be valid.
+ //------------------------------------------------------------------
+ lldb::TargetSP GetTargetSP() const;
+
+ //------------------------------------------------------------------
+ /// Get accessor that creates a strong reference from the weak process
+ /// reference contained in this object.
+ ///
+ /// @returns
+ /// A shared pointer to a process that is not guaranteed to be valid.
+ //------------------------------------------------------------------
+ lldb::ProcessSP GetProcessSP() const;
+
+ //------------------------------------------------------------------
+ /// Get accessor that creates a strong reference from the weak thread
+ /// reference contained in this object.
+ ///
+ /// @returns
+ /// A shared pointer to a thread that is not guaranteed to be valid.
+ //------------------------------------------------------------------
+ lldb::ThreadSP GetThreadSP() const;
+
+ //------------------------------------------------------------------
+ /// Get accessor that creates a strong reference from the weak frame
+ /// reference contained in this object.
+ ///
+ /// @returns
+ /// A shared pointer to a frame that is not guaranteed to be valid.
+ //------------------------------------------------------------------
+ lldb::StackFrameSP GetFrameSP() const;
+
+ //------------------------------------------------------------------
+ /// Create an ExecutionContext object from this object.
+ ///
+ /// Create strong references to any execution context objects that
+ /// are still valid. Any of the returned shared pointers in the
+ /// ExecutionContext objects is not guaranteed to be valid.
+ /// @returns
+ /// An execution context object that has strong references to
+ /// any valid weak references in this object.
+ //------------------------------------------------------------------
+ ExecutionContext Lock(bool thread_and_frame_only_if_stopped) const;
+
+ //------------------------------------------------------------------
+ /// Returns true if this object has a weak reference to a thread.
+ /// The return value is only an indication of whether this object has
+ /// a weak reference and does not indicate whether the weak reference
+ /// is valid or not.
+ //------------------------------------------------------------------
+ bool HasThreadRef() const { return m_tid != LLDB_INVALID_THREAD_ID; }
+
+ //------------------------------------------------------------------
+ /// Returns true if this object has a weak reference to a frame.
+ /// The return value is only an indication of whether this object has
+ /// a weak reference and does not indicate whether the weak reference
+ /// is valid or not.
+ //------------------------------------------------------------------
+ bool HasFrameRef() const { return m_stack_id.IsValid(); }
+
+ void ClearThread() {
+ m_thread_wp.reset();
+ m_tid = LLDB_INVALID_THREAD_ID;
+ }
+
+ void ClearFrame() { m_stack_id.Clear(); }
protected:
- //------------------------------------------------------------------
- // Member variables
- //------------------------------------------------------------------
- lldb::TargetWP m_target_wp; ///< A weak reference to a target
- lldb::ProcessWP m_process_wp; ///< A weak reference to a process
- mutable lldb::ThreadWP m_thread_wp; ///< A weak reference to a thread
- lldb::tid_t m_tid; ///< The thread ID that this object refers to in case the backing object changes
- StackID m_stack_id; ///< The stack ID that this object refers to in case the backing object changes
+ //------------------------------------------------------------------
+ // Member variables
+ //------------------------------------------------------------------
+ lldb::TargetWP m_target_wp; ///< A weak reference to a target
+ lldb::ProcessWP m_process_wp; ///< A weak reference to a process
+ mutable lldb::ThreadWP m_thread_wp; ///< A weak reference to a thread
+ lldb::tid_t m_tid; ///< The thread ID that this object refers to in case the
+ ///backing object changes
+ StackID m_stack_id; ///< The stack ID that this object refers to in case the
+ ///backing object changes
};
//----------------------------------------------------------------------
@@ -362,7 +334,7 @@ protected:
/// a context that specifies a target, process, thread and frame.
/// These objects are designed to be used for short term execution
/// context object storage while a function might be trying to evaluate
-/// something that requires a thread or frame. ExecutionContextRef
+/// something that requires a thread or frame. ExecutionContextRef
/// objects can be used to initialize one of these objects to turn
/// the weak execution context object references to the target, process,
/// thread and frame into strong references (shared pointers) so that
@@ -375,413 +347,360 @@ protected:
/// require specific contexts. They should NOT be used for long term
/// storage, for long term storage use ExecutionContextRef objects.
//----------------------------------------------------------------------
-class ExecutionContext
-{
+class ExecutionContext {
public:
- //------------------------------------------------------------------
- /// Default Constructor.
- //------------------------------------------------------------------
- ExecutionContext();
-
- //------------------------------------------------------------------
- // Copy constructor
- //------------------------------------------------------------------
- ExecutionContext (const ExecutionContext &rhs);
-
- //------------------------------------------------------------------
- // Adopt the target and optionally its current context.
- //------------------------------------------------------------------
- ExecutionContext (Target* t, bool fill_current_process_thread_frame = true);
-
- //------------------------------------------------------------------
- // Create execution contexts from shared pointers
- //------------------------------------------------------------------
- ExecutionContext (const lldb::TargetSP &target_sp, bool get_process);
- ExecutionContext (const lldb::ProcessSP &process_sp);
- ExecutionContext (const lldb::ThreadSP &thread_sp);
- ExecutionContext (const lldb::StackFrameSP &frame_sp);
-
- //------------------------------------------------------------------
- // Create execution contexts from weak pointers
- //------------------------------------------------------------------
- ExecutionContext (const lldb::TargetWP &target_wp, bool get_process);
- ExecutionContext (const lldb::ProcessWP &process_wp);
- ExecutionContext (const lldb::ThreadWP &thread_wp);
- ExecutionContext (const lldb::StackFrameWP &frame_wp);
- ExecutionContext (const ExecutionContextRef &exe_ctx_ref);
- ExecutionContext (const ExecutionContextRef *exe_ctx_ref, bool thread_and_frame_only_if_stopped = false);
-
- // These two variants take in a locker, and grab the target, lock the API mutex into locker, then
- // fill in the rest of the shared pointers.
- ExecutionContext(const ExecutionContextRef &exe_ctx_ref, std::unique_lock<std::recursive_mutex> &locker);
- ExecutionContext(const ExecutionContextRef *exe_ctx_ref, std::unique_lock<std::recursive_mutex> &locker);
- //------------------------------------------------------------------
- // Create execution contexts from execution context scopes
- //------------------------------------------------------------------
- ExecutionContext (ExecutionContextScope *exe_scope);
- ExecutionContext (ExecutionContextScope &exe_scope);
-
- //------------------------------------------------------------------
- /// Construct with process, thread, and frame index.
- ///
- /// Initialize with process \a p, thread \a t, and frame index \a f.
- ///
- /// @param[in] process
- /// The process for this execution context.
- ///
- /// @param[in] thread
- /// The thread for this execution context.
- ///
- /// @param[in] frame
- /// The frame index for this execution context.
- //------------------------------------------------------------------
- ExecutionContext(Process* process,
- Thread *thread = nullptr,
- StackFrame * frame = nullptr);
-
-
- ~ExecutionContext();
-
- ExecutionContext &
- operator =(const ExecutionContext &rhs);
-
- bool
- operator ==(const ExecutionContext &rhs) const;
-
- bool
- operator !=(const ExecutionContext &rhs) const;
-
- //------------------------------------------------------------------
- /// Clear the object's state.
- ///
- /// Sets the process and thread to nullptr, and the frame index to an
- /// invalid value.
- //------------------------------------------------------------------
- void
- Clear ();
-
- RegisterContext *
- GetRegisterContext () const;
-
- ExecutionContextScope *
- GetBestExecutionContextScope () const;
-
- uint32_t
- GetAddressByteSize() const;
-
- lldb::ByteOrder
- GetByteOrder() const;
-
- //------------------------------------------------------------------
- /// Returns a pointer to the target object.
- ///
- /// The returned pointer might be nullptr. Calling HasTargetScope(),
- /// HasProcessScope(), HasThreadScope(), or HasFrameScope()
- /// can help to pre-validate this pointer so that this accessor can
- /// freely be used without having to check for nullptr each time.
- ///
- /// @see ExecutionContext::HasTargetScope() const
- /// @see ExecutionContext::HasProcessScope() const
- /// @see ExecutionContext::HasThreadScope() const
- /// @see ExecutionContext::HasFrameScope() const
- //------------------------------------------------------------------
- Target *
- GetTargetPtr () const;
-
- //------------------------------------------------------------------
- /// Returns a pointer to the process object.
- ///
- /// The returned pointer might be nullptr. Calling HasProcessScope(),
- /// HasThreadScope(), or HasFrameScope() can help to pre-validate
- /// this pointer so that this accessor can freely be used without
- /// having to check for nullptr each time.
- ///
- /// @see ExecutionContext::HasProcessScope() const
- /// @see ExecutionContext::HasThreadScope() const
- /// @see ExecutionContext::HasFrameScope() const
- //------------------------------------------------------------------
- Process *
- GetProcessPtr () const;
-
- //------------------------------------------------------------------
- /// Returns a pointer to the thread object.
- ///
- /// The returned pointer might be nullptr. Calling HasThreadScope() or
- /// HasFrameScope() can help to pre-validate this pointer so that
- /// this accessor can freely be used without having to check for
- /// nullptr each time.
- ///
- /// @see ExecutionContext::HasThreadScope() const
- /// @see ExecutionContext::HasFrameScope() const
- //------------------------------------------------------------------
- Thread *
- GetThreadPtr () const
- {
- return m_thread_sp.get();
- }
-
- //------------------------------------------------------------------
- /// Returns a pointer to the frame object.
- ///
- /// The returned pointer might be nullptr. Calling HasFrameScope(),
- /// can help to pre-validate this pointer so that this accessor can
- /// freely be used without having to check for nullptr each time.
- ///
- /// @see ExecutionContext::HasFrameScope() const
- //------------------------------------------------------------------
- StackFrame *
- GetFramePtr () const
- {
- return m_frame_sp.get();
- }
-
- //------------------------------------------------------------------
- /// Returns a reference to the target object.
- ///
- /// Clients should call HasTargetScope(), HasProcessScope(),
- /// HasThreadScope(), or HasFrameScope() prior to calling this
- /// function to ensure that this ExecutionContext object contains
- /// a valid target.
- ///
- /// @see ExecutionContext::HasTargetScope() const
- /// @see ExecutionContext::HasProcessScope() const
- /// @see ExecutionContext::HasThreadScope() const
- /// @see ExecutionContext::HasFrameScope() const
- //------------------------------------------------------------------
- Target &
- GetTargetRef () const;
-
- //------------------------------------------------------------------
- /// Returns a reference to the process object.
- ///
- /// Clients should call HasProcessScope(), HasThreadScope(), or
- /// HasFrameScope() prior to calling this function to ensure that
- /// this ExecutionContext object contains a valid target.
- ///
- /// @see ExecutionContext::HasProcessScope() const
- /// @see ExecutionContext::HasThreadScope() const
- /// @see ExecutionContext::HasFrameScope() const
- //------------------------------------------------------------------
- Process &
- GetProcessRef () const;
-
- //------------------------------------------------------------------
- /// Returns a reference to the thread object.
- ///
- /// Clients should call HasThreadScope(), or HasFrameScope() prior
- /// to calling this function to ensure that this ExecutionContext
- /// object contains a valid target.
- ///
- /// @see ExecutionContext::HasThreadScope() const
- /// @see ExecutionContext::HasFrameScope() const
- //------------------------------------------------------------------
- Thread &
- GetThreadRef () const;
-
- //------------------------------------------------------------------
- /// Returns a reference to the thread object.
- ///
- /// Clients should call HasFrameScope() prior to calling this
- /// function to ensure that this ExecutionContext object contains
- /// a valid target.
- ///
- /// @see ExecutionContext::HasFrameScope() const
- //------------------------------------------------------------------
- StackFrame &
- GetFrameRef () const;
-
- //------------------------------------------------------------------
- /// Get accessor to get the target shared pointer.
- ///
- /// The returned shared pointer is not guaranteed to be valid.
- //------------------------------------------------------------------
- const lldb::TargetSP &
- GetTargetSP () const
- {
- return m_target_sp;
- }
-
- //------------------------------------------------------------------
- /// Get accessor to get the process shared pointer.
- ///
- /// The returned shared pointer is not guaranteed to be valid.
- //------------------------------------------------------------------
- const lldb::ProcessSP &
- GetProcessSP () const
- {
- return m_process_sp;
- }
-
- //------------------------------------------------------------------
- /// Get accessor to get the thread shared pointer.
- ///
- /// The returned shared pointer is not guaranteed to be valid.
- //------------------------------------------------------------------
- const lldb::ThreadSP &
- GetThreadSP () const
- {
- return m_thread_sp;
- }
-
- //------------------------------------------------------------------
- /// Get accessor to get the frame shared pointer.
- ///
- /// The returned shared pointer is not guaranteed to be valid.
- //------------------------------------------------------------------
- const lldb::StackFrameSP &
- GetFrameSP () const
- {
- return m_frame_sp;
- }
-
- //------------------------------------------------------------------
- /// Set accessor to set only the target shared pointer.
- //------------------------------------------------------------------
- void
- SetTargetSP (const lldb::TargetSP &target_sp);
-
- //------------------------------------------------------------------
- /// Set accessor to set only the process shared pointer.
- //------------------------------------------------------------------
- void
- SetProcessSP (const lldb::ProcessSP &process_sp);
-
- //------------------------------------------------------------------
- /// Set accessor to set only the thread shared pointer.
- //------------------------------------------------------------------
- void
- SetThreadSP (const lldb::ThreadSP &thread_sp);
-
- //------------------------------------------------------------------
- /// Set accessor to set only the frame shared pointer.
- //------------------------------------------------------------------
- void
- SetFrameSP (const lldb::StackFrameSP &frame_sp);
-
- //------------------------------------------------------------------
- /// Set accessor to set only the target shared pointer from a target
- /// pointer.
- //------------------------------------------------------------------
- void
- SetTargetPtr (Target* target);
-
- //------------------------------------------------------------------
- /// Set accessor to set only the process shared pointer from a
- /// process pointer.
- //------------------------------------------------------------------
- void
- SetProcessPtr (Process *process);
-
- //------------------------------------------------------------------
- /// Set accessor to set only the thread shared pointer from a thread
- /// pointer.
- //------------------------------------------------------------------
- void
- SetThreadPtr (Thread *thread);
-
- //------------------------------------------------------------------
- /// Set accessor to set only the frame shared pointer from a frame
- /// pointer.
- //------------------------------------------------------------------
- void
- SetFramePtr (StackFrame *frame);
-
- //------------------------------------------------------------------
- // Set the execution context using a target shared pointer.
- //
- // If "target_sp" is valid, sets the target context to match and
- // if "get_process" is true, sets the process shared pointer if
- // the target currently has a process.
- //------------------------------------------------------------------
- void
- SetContext (const lldb::TargetSP &target_sp, bool get_process);
-
- //------------------------------------------------------------------
- // Set the execution context using a process shared pointer.
- //
- // If "process_sp" is valid, then set the process and target in this
- // context. Thread and frame contexts will be cleared.
- // If "process_sp" is not valid, all shared pointers are reset.
- //------------------------------------------------------------------
- void
- SetContext (const lldb::ProcessSP &process_sp);
-
- //------------------------------------------------------------------
- // Set the execution context using a thread shared pointer.
- //
- // If "thread_sp" is valid, then set the thread, process and target
- // in this context. The frame context will be cleared.
- // If "thread_sp" is not valid, all shared pointers are reset.
- //------------------------------------------------------------------
- void
- SetContext (const lldb::ThreadSP &thread_sp);
-
- //------------------------------------------------------------------
- // Set the execution context using a frame shared pointer.
- //
- // If "frame_sp" is valid, then set the frame, thread, process and
- // target in this context
- // If "frame_sp" is not valid, all shared pointers are reset.
- //------------------------------------------------------------------
- void
- SetContext (const lldb::StackFrameSP &frame_sp);
-
- //------------------------------------------------------------------
- /// Returns true the ExecutionContext object contains a valid
- /// target.
- ///
- /// This function can be called after initializing an ExecutionContext
- /// object, and if it returns true, calls to GetTargetPtr() and
- /// GetTargetRef() do not need to be checked for validity.
- //------------------------------------------------------------------
- bool
- HasTargetScope () const;
-
- //------------------------------------------------------------------
- /// Returns true the ExecutionContext object contains a valid
- /// target and process.
- ///
- /// This function can be called after initializing an ExecutionContext
- /// object, and if it returns true, calls to GetTargetPtr() and
- /// GetTargetRef(), GetProcessPtr(), and GetProcessRef(), do not
- /// need to be checked for validity.
- //------------------------------------------------------------------
- bool
- HasProcessScope () const;
-
- //------------------------------------------------------------------
- /// Returns true the ExecutionContext object contains a valid
- /// target, process, and thread.
- ///
- /// This function can be called after initializing an ExecutionContext
- /// object, and if it returns true, calls to GetTargetPtr(),
- /// GetTargetRef(), GetProcessPtr(), GetProcessRef(), GetThreadPtr(),
- /// and GetThreadRef() do not need to be checked for validity.
- //------------------------------------------------------------------
- bool
- HasThreadScope () const;
-
- //------------------------------------------------------------------
- /// Returns true the ExecutionContext object contains a valid
- /// target, process, thread and frame.
- ///
- /// This function can be called after initializing an ExecutionContext
- /// object, and if it returns true, calls to GetTargetPtr(),
- /// GetTargetRef(), GetProcessPtr(), GetProcessRef(), GetThreadPtr(),
- /// GetThreadRef(), GetFramePtr(), and GetFrameRef() do not need
- /// to be checked for validity.
- //------------------------------------------------------------------
- bool
- HasFrameScope () const;
-
+ //------------------------------------------------------------------
+ /// Default Constructor.
+ //------------------------------------------------------------------
+ ExecutionContext();
+
+ //------------------------------------------------------------------
+ // Copy constructor
+ //------------------------------------------------------------------
+ ExecutionContext(const ExecutionContext &rhs);
+
+ //------------------------------------------------------------------
+ // Adopt the target and optionally its current context.
+ //------------------------------------------------------------------
+ ExecutionContext(Target *t, bool fill_current_process_thread_frame = true);
+
+ //------------------------------------------------------------------
+ // Create execution contexts from shared pointers
+ //------------------------------------------------------------------
+ ExecutionContext(const lldb::TargetSP &target_sp, bool get_process);
+ ExecutionContext(const lldb::ProcessSP &process_sp);
+ ExecutionContext(const lldb::ThreadSP &thread_sp);
+ ExecutionContext(const lldb::StackFrameSP &frame_sp);
+
+ //------------------------------------------------------------------
+ // Create execution contexts from weak pointers
+ //------------------------------------------------------------------
+ ExecutionContext(const lldb::TargetWP &target_wp, bool get_process);
+ ExecutionContext(const lldb::ProcessWP &process_wp);
+ ExecutionContext(const lldb::ThreadWP &thread_wp);
+ ExecutionContext(const lldb::StackFrameWP &frame_wp);
+ ExecutionContext(const ExecutionContextRef &exe_ctx_ref);
+ ExecutionContext(const ExecutionContextRef *exe_ctx_ref,
+ bool thread_and_frame_only_if_stopped = false);
+
+ // These two variants take in a locker, and grab the target, lock the API
+ // mutex into locker, then
+ // fill in the rest of the shared pointers.
+ ExecutionContext(const ExecutionContextRef &exe_ctx_ref,
+ std::unique_lock<std::recursive_mutex> &locker);
+ ExecutionContext(const ExecutionContextRef *exe_ctx_ref,
+ std::unique_lock<std::recursive_mutex> &locker);
+ //------------------------------------------------------------------
+ // Create execution contexts from execution context scopes
+ //------------------------------------------------------------------
+ ExecutionContext(ExecutionContextScope *exe_scope);
+ ExecutionContext(ExecutionContextScope &exe_scope);
+
+ //------------------------------------------------------------------
+ /// Construct with process, thread, and frame index.
+ ///
+ /// Initialize with process \a p, thread \a t, and frame index \a f.
+ ///
+ /// @param[in] process
+ /// The process for this execution context.
+ ///
+ /// @param[in] thread
+ /// The thread for this execution context.
+ ///
+ /// @param[in] frame
+ /// The frame index for this execution context.
+ //------------------------------------------------------------------
+ ExecutionContext(Process *process, Thread *thread = nullptr,
+ StackFrame *frame = nullptr);
+
+ ~ExecutionContext();
+
+ ExecutionContext &operator=(const ExecutionContext &rhs);
+
+ bool operator==(const ExecutionContext &rhs) const;
+
+ bool operator!=(const ExecutionContext &rhs) const;
+
+ //------------------------------------------------------------------
+ /// Clear the object's state.
+ ///
+ /// Sets the process and thread to nullptr, and the frame index to an
+ /// invalid value.
+ //------------------------------------------------------------------
+ void Clear();
+
+ RegisterContext *GetRegisterContext() const;
+
+ ExecutionContextScope *GetBestExecutionContextScope() const;
+
+ uint32_t GetAddressByteSize() const;
+
+ lldb::ByteOrder GetByteOrder() const;
+
+ //------------------------------------------------------------------
+ /// Returns a pointer to the target object.
+ ///
+ /// The returned pointer might be nullptr. Calling HasTargetScope(),
+ /// HasProcessScope(), HasThreadScope(), or HasFrameScope()
+ /// can help to pre-validate this pointer so that this accessor can
+ /// freely be used without having to check for nullptr each time.
+ ///
+ /// @see ExecutionContext::HasTargetScope() const
+ /// @see ExecutionContext::HasProcessScope() const
+ /// @see ExecutionContext::HasThreadScope() const
+ /// @see ExecutionContext::HasFrameScope() const
+ //------------------------------------------------------------------
+ Target *GetTargetPtr() const;
+
+ //------------------------------------------------------------------
+ /// Returns a pointer to the process object.
+ ///
+ /// The returned pointer might be nullptr. Calling HasProcessScope(),
+ /// HasThreadScope(), or HasFrameScope() can help to pre-validate
+ /// this pointer so that this accessor can freely be used without
+ /// having to check for nullptr each time.
+ ///
+ /// @see ExecutionContext::HasProcessScope() const
+ /// @see ExecutionContext::HasThreadScope() const
+ /// @see ExecutionContext::HasFrameScope() const
+ //------------------------------------------------------------------
+ Process *GetProcessPtr() const;
+
+ //------------------------------------------------------------------
+ /// Returns a pointer to the thread object.
+ ///
+ /// The returned pointer might be nullptr. Calling HasThreadScope() or
+ /// HasFrameScope() can help to pre-validate this pointer so that
+ /// this accessor can freely be used without having to check for
+ /// nullptr each time.
+ ///
+ /// @see ExecutionContext::HasThreadScope() const
+ /// @see ExecutionContext::HasFrameScope() const
+ //------------------------------------------------------------------
+ Thread *GetThreadPtr() const { return m_thread_sp.get(); }
+
+ //------------------------------------------------------------------
+ /// Returns a pointer to the frame object.
+ ///
+ /// The returned pointer might be nullptr. Calling HasFrameScope(),
+ /// can help to pre-validate this pointer so that this accessor can
+ /// freely be used without having to check for nullptr each time.
+ ///
+ /// @see ExecutionContext::HasFrameScope() const
+ //------------------------------------------------------------------
+ StackFrame *GetFramePtr() const { return m_frame_sp.get(); }
+
+ //------------------------------------------------------------------
+ /// Returns a reference to the target object.
+ ///
+ /// Clients should call HasTargetScope(), HasProcessScope(),
+ /// HasThreadScope(), or HasFrameScope() prior to calling this
+ /// function to ensure that this ExecutionContext object contains
+ /// a valid target.
+ ///
+ /// @see ExecutionContext::HasTargetScope() const
+ /// @see ExecutionContext::HasProcessScope() const
+ /// @see ExecutionContext::HasThreadScope() const
+ /// @see ExecutionContext::HasFrameScope() const
+ //------------------------------------------------------------------
+ Target &GetTargetRef() const;
+
+ //------------------------------------------------------------------
+ /// Returns a reference to the process object.
+ ///
+ /// Clients should call HasProcessScope(), HasThreadScope(), or
+ /// HasFrameScope() prior to calling this function to ensure that
+ /// this ExecutionContext object contains a valid target.
+ ///
+ /// @see ExecutionContext::HasProcessScope() const
+ /// @see ExecutionContext::HasThreadScope() const
+ /// @see ExecutionContext::HasFrameScope() const
+ //------------------------------------------------------------------
+ Process &GetProcessRef() const;
+
+ //------------------------------------------------------------------
+ /// Returns a reference to the thread object.
+ ///
+ /// Clients should call HasThreadScope(), or HasFrameScope() prior
+ /// to calling this function to ensure that this ExecutionContext
+ /// object contains a valid target.
+ ///
+ /// @see ExecutionContext::HasThreadScope() const
+ /// @see ExecutionContext::HasFrameScope() const
+ //------------------------------------------------------------------
+ Thread &GetThreadRef() const;
+
+ //------------------------------------------------------------------
+ /// Returns a reference to the thread object.
+ ///
+ /// Clients should call HasFrameScope() prior to calling this
+ /// function to ensure that this ExecutionContext object contains
+ /// a valid target.
+ ///
+ /// @see ExecutionContext::HasFrameScope() const
+ //------------------------------------------------------------------
+ StackFrame &GetFrameRef() const;
+
+ //------------------------------------------------------------------
+ /// Get accessor to get the target shared pointer.
+ ///
+ /// The returned shared pointer is not guaranteed to be valid.
+ //------------------------------------------------------------------
+ const lldb::TargetSP &GetTargetSP() const { return m_target_sp; }
+
+ //------------------------------------------------------------------
+ /// Get accessor to get the process shared pointer.
+ ///
+ /// The returned shared pointer is not guaranteed to be valid.
+ //------------------------------------------------------------------
+ const lldb::ProcessSP &GetProcessSP() const { return m_process_sp; }
+
+ //------------------------------------------------------------------
+ /// Get accessor to get the thread shared pointer.
+ ///
+ /// The returned shared pointer is not guaranteed to be valid.
+ //------------------------------------------------------------------
+ const lldb::ThreadSP &GetThreadSP() const { return m_thread_sp; }
+
+ //------------------------------------------------------------------
+ /// Get accessor to get the frame shared pointer.
+ ///
+ /// The returned shared pointer is not guaranteed to be valid.
+ //------------------------------------------------------------------
+ const lldb::StackFrameSP &GetFrameSP() const { return m_frame_sp; }
+
+ //------------------------------------------------------------------
+ /// Set accessor to set only the target shared pointer.
+ //------------------------------------------------------------------
+ void SetTargetSP(const lldb::TargetSP &target_sp);
+
+ //------------------------------------------------------------------
+ /// Set accessor to set only the process shared pointer.
+ //------------------------------------------------------------------
+ void SetProcessSP(const lldb::ProcessSP &process_sp);
+
+ //------------------------------------------------------------------
+ /// Set accessor to set only the thread shared pointer.
+ //------------------------------------------------------------------
+ void SetThreadSP(const lldb::ThreadSP &thread_sp);
+
+ //------------------------------------------------------------------
+ /// Set accessor to set only the frame shared pointer.
+ //------------------------------------------------------------------
+ void SetFrameSP(const lldb::StackFrameSP &frame_sp);
+
+ //------------------------------------------------------------------
+ /// Set accessor to set only the target shared pointer from a target
+ /// pointer.
+ //------------------------------------------------------------------
+ void SetTargetPtr(Target *target);
+
+ //------------------------------------------------------------------
+ /// Set accessor to set only the process shared pointer from a
+ /// process pointer.
+ //------------------------------------------------------------------
+ void SetProcessPtr(Process *process);
+
+ //------------------------------------------------------------------
+ /// Set accessor to set only the thread shared pointer from a thread
+ /// pointer.
+ //------------------------------------------------------------------
+ void SetThreadPtr(Thread *thread);
+
+ //------------------------------------------------------------------
+ /// Set accessor to set only the frame shared pointer from a frame
+ /// pointer.
+ //------------------------------------------------------------------
+ void SetFramePtr(StackFrame *frame);
+
+ //------------------------------------------------------------------
+ // Set the execution context using a target shared pointer.
+ //
+ // If "target_sp" is valid, sets the target context to match and
+ // if "get_process" is true, sets the process shared pointer if
+ // the target currently has a process.
+ //------------------------------------------------------------------
+ void SetContext(const lldb::TargetSP &target_sp, bool get_process);
+
+ //------------------------------------------------------------------
+ // Set the execution context using a process shared pointer.
+ //
+ // If "process_sp" is valid, then set the process and target in this
+ // context. Thread and frame contexts will be cleared.
+ // If "process_sp" is not valid, all shared pointers are reset.
+ //------------------------------------------------------------------
+ void SetContext(const lldb::ProcessSP &process_sp);
+
+ //------------------------------------------------------------------
+ // Set the execution context using a thread shared pointer.
+ //
+ // If "thread_sp" is valid, then set the thread, process and target
+ // in this context. The frame context will be cleared.
+ // If "thread_sp" is not valid, all shared pointers are reset.
+ //------------------------------------------------------------------
+ void SetContext(const lldb::ThreadSP &thread_sp);
+
+ //------------------------------------------------------------------
+ // Set the execution context using a frame shared pointer.
+ //
+ // If "frame_sp" is valid, then set the frame, thread, process and
+ // target in this context
+ // If "frame_sp" is not valid, all shared pointers are reset.
+ //------------------------------------------------------------------
+ void SetContext(const lldb::StackFrameSP &frame_sp);
+
+ //------------------------------------------------------------------
+ /// Returns true the ExecutionContext object contains a valid
+ /// target.
+ ///
+ /// This function can be called after initializing an ExecutionContext
+ /// object, and if it returns true, calls to GetTargetPtr() and
+ /// GetTargetRef() do not need to be checked for validity.
+ //------------------------------------------------------------------
+ bool HasTargetScope() const;
+
+ //------------------------------------------------------------------
+ /// Returns true the ExecutionContext object contains a valid
+ /// target and process.
+ ///
+ /// This function can be called after initializing an ExecutionContext
+ /// object, and if it returns true, calls to GetTargetPtr() and
+ /// GetTargetRef(), GetProcessPtr(), and GetProcessRef(), do not
+ /// need to be checked for validity.
+ //------------------------------------------------------------------
+ bool HasProcessScope() const;
+
+ //------------------------------------------------------------------
+ /// Returns true the ExecutionContext object contains a valid
+ /// target, process, and thread.
+ ///
+ /// This function can be called after initializing an ExecutionContext
+ /// object, and if it returns true, calls to GetTargetPtr(),
+ /// GetTargetRef(), GetProcessPtr(), GetProcessRef(), GetThreadPtr(),
+ /// and GetThreadRef() do not need to be checked for validity.
+ //------------------------------------------------------------------
+ bool HasThreadScope() const;
+
+ //------------------------------------------------------------------
+ /// Returns true the ExecutionContext object contains a valid
+ /// target, process, thread and frame.
+ ///
+ /// This function can be called after initializing an ExecutionContext
+ /// object, and if it returns true, calls to GetTargetPtr(),
+ /// GetTargetRef(), GetProcessPtr(), GetProcessRef(), GetThreadPtr(),
+ /// GetThreadRef(), GetFramePtr(), and GetFrameRef() do not need
+ /// to be checked for validity.
+ //------------------------------------------------------------------
+ bool HasFrameScope() const;
+
protected:
- //------------------------------------------------------------------
- // Member variables
- //------------------------------------------------------------------
- lldb::TargetSP m_target_sp; ///< The target that owns the process/thread/frame
- lldb::ProcessSP m_process_sp; ///< The process that owns the thread/frame
- lldb::ThreadSP m_thread_sp; ///< The thread that owns the frame
- lldb::StackFrameSP m_frame_sp; ///< The stack frame in thread.
+ //------------------------------------------------------------------
+ // Member variables
+ //------------------------------------------------------------------
+ lldb::TargetSP m_target_sp; ///< The target that owns the process/thread/frame
+ lldb::ProcessSP m_process_sp; ///< The process that owns the thread/frame
+ lldb::ThreadSP m_thread_sp; ///< The thread that owns the frame
+ lldb::StackFrameSP m_frame_sp; ///< The stack frame in thread.
};
} // namespace lldb_private
diff --git a/include/lldb/Target/ExecutionContextScope.h b/include/lldb/Target/ExecutionContextScope.h
index 4a1b17d5a114..36d3d9de49b0 100644
--- a/include/lldb/Target/ExecutionContextScope.h
+++ b/include/lldb/Target/ExecutionContextScope.h
@@ -19,7 +19,8 @@
namespace lldb_private {
//----------------------------------------------------------------------
-/// @class ExecutionContextScope ExecutionContextScope.h "lldb/Symbol/ExecutionContextScope.h"
+/// @class ExecutionContextScope ExecutionContextScope.h
+/// "lldb/Symbol/ExecutionContextScope.h"
/// @brief Inherit from this if your object can reconstruct its
/// execution context.
///
@@ -36,39 +37,32 @@ namespace lldb_private {
/// execution context to allow functions that take a execution contexts
/// to be called.
//----------------------------------------------------------------------
-class ExecutionContextScope
-{
+class ExecutionContextScope {
public:
- virtual
- ~ExecutionContextScope () {}
+ virtual ~ExecutionContextScope() {}
- virtual lldb::TargetSP
- CalculateTarget () = 0;
+ virtual lldb::TargetSP CalculateTarget() = 0;
- virtual lldb::ProcessSP
- CalculateProcess () = 0;
+ virtual lldb::ProcessSP CalculateProcess() = 0;
- virtual lldb::ThreadSP
- CalculateThread () = 0;
+ virtual lldb::ThreadSP CalculateThread() = 0;
- virtual lldb::StackFrameSP
- CalculateStackFrame () = 0;
+ virtual lldb::StackFrameSP CalculateStackFrame() = 0;
- //------------------------------------------------------------------
- /// Reconstruct the object's execution context into \a sc.
- ///
- /// The object should fill in as much of the ExecutionContextScope as it
- /// can so function calls that require a execution context can be made
- /// for the given object.
- ///
- /// @param[out] exe_ctx
- /// A reference to an execution context object that gets filled
- /// in.
- //------------------------------------------------------------------
- virtual void
- CalculateExecutionContext (ExecutionContext &exe_ctx) = 0;
+ //------------------------------------------------------------------
+ /// Reconstruct the object's execution context into \a sc.
+ ///
+ /// The object should fill in as much of the ExecutionContextScope as it
+ /// can so function calls that require a execution context can be made
+ /// for the given object.
+ ///
+ /// @param[out] exe_ctx
+ /// A reference to an execution context object that gets filled
+ /// in.
+ //------------------------------------------------------------------
+ virtual void CalculateExecutionContext(ExecutionContext &exe_ctx) = 0;
};
} // namespace lldb_private
-#endif // liblldb_ExecutionContextScope_h_
+#endif // liblldb_ExecutionContextScope_h_
diff --git a/include/lldb/Target/FileAction.h b/include/lldb/Target/FileAction.h
index 907c4d937beb..81122ec68798 100644
--- a/include/lldb/Target/FileAction.h
+++ b/include/lldb/Target/FileAction.h
@@ -10,65 +10,48 @@
#ifndef liblldb_Target_FileAction_h
#define liblldb_Target_FileAction_h
-#include <string>
#include "lldb/Host/FileSpec.h"
+#include <string>
-namespace lldb_private
-{
+namespace lldb_private {
-class FileAction
-{
- public:
- enum Action
- {
- eFileActionNone,
- eFileActionClose,
- eFileActionDuplicate,
- eFileActionOpen
- };
+class FileAction {
+public:
+ enum Action {
+ eFileActionNone,
+ eFileActionClose,
+ eFileActionDuplicate,
+ eFileActionOpen
+ };
- FileAction();
+ FileAction();
- void Clear();
+ void Clear();
- bool Close(int fd);
+ bool Close(int fd);
- bool Duplicate(int fd, int dup_fd);
+ bool Duplicate(int fd, int dup_fd);
- bool Open(int fd, const FileSpec &file_spec, bool read, bool write);
+ bool Open(int fd, const FileSpec &file_spec, bool read, bool write);
- int
- GetFD() const
- {
- return m_fd;
- }
+ int GetFD() const { return m_fd; }
- Action
- GetAction() const
- {
- return m_action;
- }
+ Action GetAction() const { return m_action; }
- int
- GetActionArgument() const
- {
- return m_arg;
- }
+ int GetActionArgument() const { return m_arg; }
- const char *
- GetPath() const;
+ llvm::StringRef GetPath() const;
- const FileSpec &
- GetFileSpec() const;
+ const FileSpec &GetFileSpec() const;
- void
- Dump (Stream &stream) const;
+ void Dump(Stream &stream) const;
- protected:
- Action m_action; // The action for this file
- int m_fd; // An existing file descriptor
- int m_arg; // oflag for eFileActionOpen*, dup_fd for eFileActionDuplicate
- FileSpec m_file_spec; // A file spec to use for opening after fork or posix_spawn
+protected:
+ Action m_action; // The action for this file
+ int m_fd; // An existing file descriptor
+ int m_arg; // oflag for eFileActionOpen*, dup_fd for eFileActionDuplicate
+ FileSpec
+ m_file_spec; // A file spec to use for opening after fork or posix_spawn
};
} // namespace lldb_private
diff --git a/include/lldb/Target/InstrumentationRuntime.h b/include/lldb/Target/InstrumentationRuntime.h
index a5dc853ab55b..a40914d04ea9 100644
--- a/include/lldb/Target/InstrumentationRuntime.h
+++ b/include/lldb/Target/InstrumentationRuntime.h
@@ -12,40 +12,89 @@
// C Includes
// C++ Includes
-#include <vector>
#include <map>
+#include <vector>
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
-#include "lldb/lldb-types.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Core/StructuredData.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private.h"
+#include "lldb/lldb-types.h"
namespace lldb_private {
-
-typedef std::map<lldb::InstrumentationRuntimeType, lldb::InstrumentationRuntimeSP> InstrumentationRuntimeCollection;
-
-class InstrumentationRuntime :
- public std::enable_shared_from_this<InstrumentationRuntime>,
- public PluginInterface
-{
+
+typedef std::map<lldb::InstrumentationRuntimeType,
+ lldb::InstrumentationRuntimeSP>
+ InstrumentationRuntimeCollection;
+
+class InstrumentationRuntime
+ : public std::enable_shared_from_this<InstrumentationRuntime>,
+ public PluginInterface {
+ /// The instrumented process.
+ lldb::ProcessWP m_process_wp;
+
+ /// The module containing the instrumentation runtime.
+ lldb::ModuleSP m_runtime_module;
+
+ /// The breakpoint in the instrumentation runtime.
+ lldb::user_id_t m_breakpoint_id;
+
+ /// Indicates whether or not breakpoints have been registered in the
+ /// instrumentation runtime.
+ bool m_is_active;
+
+protected:
+ InstrumentationRuntime(const lldb::ProcessSP &process_sp)
+ : m_process_wp(), m_runtime_module(), m_breakpoint_id(0),
+ m_is_active(false) {
+ if (process_sp)
+ m_process_wp = process_sp;
+ }
+
+ lldb::ProcessSP GetProcessSP() { return m_process_wp.lock(); }
+
+ lldb::ModuleSP GetRuntimeModuleSP() { return m_runtime_module; }
+
+ void SetRuntimeModuleSP(lldb::ModuleSP module_sp) {
+ m_runtime_module = module_sp;
+ }
+
+ lldb::user_id_t GetBreakpointID() const { return m_breakpoint_id; }
+
+ void SetBreakpointID(lldb::user_id_t ID) { m_breakpoint_id = ID; }
+
+ void SetActive(bool IsActive) { m_is_active = IsActive; }
+
+ /// Return a regular expression which can be used to identify a valid version
+ /// of the runtime library.
+ virtual const RegularExpression &GetPatternForRuntimeLibrary() = 0;
+
+ /// Check whether \p module_sp corresponds to a valid runtime library.
+ virtual bool CheckIfRuntimeIsValid(const lldb::ModuleSP module_sp) = 0;
+
+ /// Register a breakpoint in the runtime library and perform any other
+ /// necessary initialization. The runtime library
+ /// is guaranteed to be loaded.
+ virtual void Activate() = 0;
+
public:
-
- static void
- ModulesDidLoad(lldb_private::ModuleList &module_list, Process *process, InstrumentationRuntimeCollection &runtimes);
-
- virtual void
- ModulesDidLoad(lldb_private::ModuleList &module_list);
-
- virtual bool
- IsActive();
-
- virtual lldb::ThreadCollectionSP
- GetBacktracesFromExtendedStopInfo(StructuredData::ObjectSP info);
-
+ static void ModulesDidLoad(lldb_private::ModuleList &module_list,
+ Process *process,
+ InstrumentationRuntimeCollection &runtimes);
+
+ /// Look for the instrumentation runtime in \p module_list. Register and
+ /// activate the runtime if this hasn't already
+ /// been done.
+ void ModulesDidLoad(lldb_private::ModuleList &module_list);
+
+ bool IsActive() const { return m_is_active; }
+
+ virtual lldb::ThreadCollectionSP
+ GetBacktracesFromExtendedStopInfo(StructuredData::ObjectSP info);
};
-
+
} // namespace lldb_private
-#endif // liblldb_InstrumentationRuntime_h_
+#endif // liblldb_InstrumentationRuntime_h_
diff --git a/include/lldb/Target/InstrumentationRuntimeStopInfo.h b/include/lldb/Target/InstrumentationRuntimeStopInfo.h
index df1b937e6e26..0a4a17003d93 100644
--- a/include/lldb/Target/InstrumentationRuntimeStopInfo.h
+++ b/include/lldb/Target/InstrumentationRuntimeStopInfo.h
@@ -16,40 +16,30 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/Target/StopInfo.h"
#include "lldb/Core/StructuredData.h"
+#include "lldb/Target/StopInfo.h"
namespace lldb_private {
-class InstrumentationRuntimeStopInfo : public StopInfo
-{
+class InstrumentationRuntimeStopInfo : public StopInfo {
public:
-
- ~InstrumentationRuntimeStopInfo() override
- {
- }
-
- lldb::StopReason
- GetStopReason() const override
- {
- return lldb::eStopReasonInstrumentation;
- }
-
- const char *
- GetDescription() override;
-
- bool
- DoShouldNotify(Event *event_ptr) override
- {
- return true;
- }
-
- static lldb::StopInfoSP
- CreateStopReasonWithInstrumentationData (Thread &thread, std::string description, StructuredData::ObjectSP additional_data);
-
+ ~InstrumentationRuntimeStopInfo() override {}
+
+ lldb::StopReason GetStopReason() const override {
+ return lldb::eStopReasonInstrumentation;
+ }
+
+ const char *GetDescription() override;
+
+ bool DoShouldNotify(Event *event_ptr) override { return true; }
+
+ static lldb::StopInfoSP CreateStopReasonWithInstrumentationData(
+ Thread &thread, std::string description,
+ StructuredData::ObjectSP additional_data);
+
private:
-
- InstrumentationRuntimeStopInfo(Thread &thread, std::string description, StructuredData::ObjectSP additional_data);
+ InstrumentationRuntimeStopInfo(Thread &thread, std::string description,
+ StructuredData::ObjectSP additional_data);
};
} // namespace lldb_private
diff --git a/include/lldb/Target/JITLoader.h b/include/lldb/Target/JITLoader.h
index 8a2d6828db2f..97f2a9796a80 100644
--- a/include/lldb/Target/JITLoader.h
+++ b/include/lldb/Target/JITLoader.h
@@ -21,67 +21,61 @@ namespace lldb_private {
/// @class JITLoader JITLoader.h "lldb/Target/JITLoader.h"
/// @brief A plug-in interface definition class for JIT loaders.
///
-/// Plugins of this kind listen for code generated at runtime in the
+/// Plugins of this kind listen for code generated at runtime in the
/// target. They are very similar to dynamic loader, with the difference
/// that they do not have information about the target's dyld and
-/// that there may be multiple JITLoader plugins per process, while
-/// there is at most one DynamicLoader.
+/// that there may be multiple JITLoader plugins per process, while
+/// there is at most one DynamicLoader.
//----------------------------------------------------------------------
-class JITLoader :
- public PluginInterface
-{
+class JITLoader : public PluginInterface {
public:
- //------------------------------------------------------------------
- /// Find a JIT loader plugin for a given process.
- ///
- /// Scans the installed DynamicLoader plug-ins and tries to find
- /// all applicable instances for the current process.
- ///
- /// @param[in] process
- /// The process for which to try and locate a JIT loader
- /// plug-in instance.
- ///
- //------------------------------------------------------------------
- static void
- LoadPlugins (Process *process, lldb_private::JITLoaderList &list);
+ //------------------------------------------------------------------
+ /// Find a JIT loader plugin for a given process.
+ ///
+ /// Scans the installed DynamicLoader plug-ins and tries to find
+ /// all applicable instances for the current process.
+ ///
+ /// @param[in] process
+ /// The process for which to try and locate a JIT loader
+ /// plug-in instance.
+ ///
+ //------------------------------------------------------------------
+ static void LoadPlugins(Process *process, lldb_private::JITLoaderList &list);
- //------------------------------------------------------------------
- /// Construct with a process.
- //------------------------------------------------------------------
- JITLoader (Process *process);
+ //------------------------------------------------------------------
+ /// Construct with a process.
+ //------------------------------------------------------------------
+ JITLoader(Process *process);
- ~JITLoader() override;
+ ~JITLoader() override;
- //------------------------------------------------------------------
- /// Called after attaching a process.
- ///
- /// Allow JITLoader plug-ins to execute some code after
- /// attaching to a process.
- //------------------------------------------------------------------
- virtual void
- DidAttach () = 0;
+ //------------------------------------------------------------------
+ /// Called after attaching a process.
+ ///
+ /// Allow JITLoader plug-ins to execute some code after
+ /// attaching to a process.
+ //------------------------------------------------------------------
+ virtual void DidAttach() = 0;
- //------------------------------------------------------------------
- /// Called after launching a process.
- ///
- /// Allow JITLoader plug-ins to execute some code after
- /// the process has stopped for the first time on launch.
- //------------------------------------------------------------------
- virtual void
- DidLaunch () = 0;
+ //------------------------------------------------------------------
+ /// Called after launching a process.
+ ///
+ /// Allow JITLoader plug-ins to execute some code after
+ /// the process has stopped for the first time on launch.
+ //------------------------------------------------------------------
+ virtual void DidLaunch() = 0;
- //------------------------------------------------------------------
- /// Called after a new shared object has been loaded so that it can
- /// be probed for JIT entry point hooks.
- //------------------------------------------------------------------
- virtual void
- ModulesDidLoad (lldb_private::ModuleList &module_list) = 0;
+ //------------------------------------------------------------------
+ /// Called after a new shared object has been loaded so that it can
+ /// be probed for JIT entry point hooks.
+ //------------------------------------------------------------------
+ virtual void ModulesDidLoad(lldb_private::ModuleList &module_list) = 0;
protected:
- //------------------------------------------------------------------
- // Member variables.
- //------------------------------------------------------------------
- Process* m_process;
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ Process *m_process;
};
} // namespace lldb_private
diff --git a/include/lldb/Target/JITLoaderList.h b/include/lldb/Target/JITLoaderList.h
index c86043c5cf1f..4b9d79bbfcab 100644
--- a/include/lldb/Target/JITLoaderList.h
+++ b/include/lldb/Target/JITLoaderList.h
@@ -22,37 +22,28 @@ namespace lldb_private {
///
/// Class used by the Process to hold a list of its JITLoaders.
//----------------------------------------------------------------------
-class JITLoaderList
-{
+class JITLoaderList {
public:
+ JITLoaderList();
+ ~JITLoaderList();
- JITLoaderList();
- ~JITLoaderList();
+ void Append(const lldb::JITLoaderSP &jit_loader_sp);
- void
- Append (const lldb::JITLoaderSP &jit_loader_sp);
+ void Remove(const lldb::JITLoaderSP &jit_loader_sp);
- void
- Remove (const lldb::JITLoaderSP &jit_loader_sp);
+ size_t GetSize() const;
- size_t
- GetSize() const;
+ lldb::JITLoaderSP GetLoaderAtIndex(size_t idx);
- lldb::JITLoaderSP
- GetLoaderAtIndex (size_t idx);
+ void DidLaunch();
- void
- DidLaunch();
+ void DidAttach();
- void
- DidAttach();
-
- void
- ModulesDidLoad (ModuleList &module_list);
+ void ModulesDidLoad(ModuleList &module_list);
private:
- std::vector<lldb::JITLoaderSP> m_jit_loaders_vec;
- std::recursive_mutex m_jit_loaders_mutex;
+ std::vector<lldb::JITLoaderSP> m_jit_loaders_vec;
+ std::recursive_mutex m_jit_loaders_mutex;
};
} // namespace lldb_private
diff --git a/include/lldb/Target/Language.h b/include/lldb/Target/Language.h
index d1a3ff8e6747..bcf840f93edd 100644
--- a/include/lldb/Target/Language.h
+++ b/include/lldb/Target/Language.h
@@ -1,4 +1,5 @@
-//===-- Language.h ---------------------------------------------------*- C++ -*-===//
+//===-- Language.h ---------------------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,191 +20,255 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-public.h"
-#include "lldb/lldb-private.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/DataFormatters/DumpValueObjectOptions.h"
#include "lldb/DataFormatters/FormatClasses.h"
#include "lldb/DataFormatters/StringPrinter.h"
+#include "lldb/lldb-private.h"
+#include "lldb/lldb-public.h"
namespace lldb_private {
-
-class Language :
-public PluginInterface
-{
+
+class Language : public PluginInterface {
public:
- class TypeScavenger
- {
+ class TypeScavenger {
+ public:
+ class Result {
public:
- class Result
- {
- public:
- virtual bool
- IsValid () = 0;
-
- virtual bool
- DumpToStream (Stream& stream,
- bool print_help_if_available) = 0;
-
- virtual ~Result() = default;
- };
-
- typedef std::set<std::unique_ptr<Result>> ResultSet;
-
- virtual ~TypeScavenger () = default;
-
- size_t
- Find (ExecutionContextScope *exe_scope,
- const char *key,
- ResultSet &results,
- bool append = true);
-
- protected:
- TypeScavenger () = default;
-
- virtual bool
- Find_Impl (ExecutionContextScope *exe_scope,
- const char *key,
- ResultSet &results) = 0;
+ virtual bool IsValid() = 0;
+
+ virtual bool DumpToStream(Stream &stream,
+ bool print_help_if_available) = 0;
+
+ virtual ~Result() = default;
};
-
- enum class FunctionNameRepresentation
- {
- eName,
- eNameWithArgs,
- eNameWithNoArgs
+
+ typedef std::set<std::unique_ptr<Result>> ResultSet;
+
+ virtual ~TypeScavenger() = default;
+
+ size_t Find(ExecutionContextScope *exe_scope, const char *key,
+ ResultSet &results, bool append = true);
+
+ protected:
+ TypeScavenger() = default;
+
+ virtual bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
+ ResultSet &results) = 0;
+ };
+
+ class ImageListTypeScavenger : public TypeScavenger {
+ class Result : public Language::TypeScavenger::Result {
+ public:
+ Result(CompilerType type)
+ : Language::TypeScavenger::Result(), m_compiler_type(type) {}
+
+ bool IsValid() override { return m_compiler_type.IsValid(); }
+
+ bool DumpToStream(Stream &stream, bool print_help_if_available) override {
+ if (IsValid()) {
+ m_compiler_type.DumpTypeDescription(&stream);
+ stream.EOL();
+ return true;
+ }
+ return false;
+ }
+
+ ~Result() override = default;
+
+ private:
+ CompilerType m_compiler_type;
};
- ~Language() override;
-
- static Language*
- FindPlugin (lldb::LanguageType language);
-
- // return false from callback to stop iterating
- static void
- ForEach (std::function<bool(Language*)> callback);
-
- virtual lldb::LanguageType
- GetLanguageType () const = 0;
-
- virtual bool
- IsTopLevelFunction (Function& function);
-
- virtual lldb::TypeCategoryImplSP
- GetFormatters ();
-
- virtual HardcodedFormatters::HardcodedFormatFinder
- GetHardcodedFormats ();
-
- virtual HardcodedFormatters::HardcodedSummaryFinder
- GetHardcodedSummaries ();
-
- virtual HardcodedFormatters::HardcodedSyntheticFinder
- GetHardcodedSynthetics ();
-
- virtual HardcodedFormatters::HardcodedValidatorFinder
- GetHardcodedValidators ();
-
- virtual std::vector<ConstString>
- GetPossibleFormattersMatches (ValueObject& valobj, lldb::DynamicValueType use_dynamic);
-
- virtual lldb_private::formatters::StringPrinter::EscapingHelper
- GetStringPrinterEscapingHelper (lldb_private::formatters::StringPrinter::GetPrintableElementType);
-
- virtual std::unique_ptr<TypeScavenger>
- GetTypeScavenger ();
-
- virtual const char*
- GetLanguageSpecificTypeLookupHelp ();
-
- // if an individual data formatter can apply to several types and cross a language boundary
- // it makes sense for individual languages to want to customize the printing of values of that
- // type by appending proper prefix/suffix information in language-specific ways
- virtual bool
- GetFormatterPrefixSuffix (ValueObject& valobj, ConstString type_hint,
- std::string& prefix, std::string& suffix);
-
- // if a language has a custom format for printing variable declarations that it wants LLDB to honor
- // it should return an appropriate closure here
- virtual DumpValueObjectOptions::DeclPrintingHelper
- GetDeclPrintingHelper ();
-
- virtual LazyBool
- IsLogicalTrue (ValueObject& valobj,
- Error& error);
-
- // for a ValueObject of some "reference type", if the value points to the
- // nil/null object, this method returns true
- virtual bool
- IsNilReference (ValueObject& valobj);
-
- // for a ValueObject of some "reference type", if the language provides a technique
- // to decide whether the reference has ever been assigned to some object, this method
- // will return true if such detection is possible, and if the reference has never been assigned
- virtual bool
- IsUninitializedReference (ValueObject& valobj);
-
- virtual bool
- GetFunctionDisplayName (const SymbolContext *sc,
- const ExecutionContext *exe_ctx,
- FunctionNameRepresentation representation,
- Stream& s);
-
- virtual void
- GetExceptionResolverDescription(bool catch_on, bool throw_on, Stream &s);
-
- static void
- GetDefaultExceptionResolverDescription(bool catch_on, bool throw_on, Stream &s);
-
- // These are accessors for general information about the Languages lldb knows about:
-
- static lldb::LanguageType
- GetLanguageTypeFromString (const char *string);
-
- static const char *
- GetNameForLanguageType (lldb::LanguageType language);
-
- static void
- PrintAllLanguages (Stream &s, const char *prefix, const char *suffix);
-
- // return false from callback to stop iterating
- static void
- ForAllLanguages (std::function<bool(lldb::LanguageType)> callback);
-
- static bool
- LanguageIsCPlusPlus (lldb::LanguageType language);
-
- static bool
- LanguageIsObjC (lldb::LanguageType language);
-
- static bool
- LanguageIsC (lldb::LanguageType language);
-
- static bool
- LanguageIsPascal (lldb::LanguageType language);
-
- // return the primary language, so if LanguageIsC(l), return eLanguageTypeC, etc.
- static lldb::LanguageType
- GetPrimaryLanguage (lldb::LanguageType language);
-
- static void
- GetLanguagesSupportingTypeSystems (std::set<lldb::LanguageType> &languages,
- std::set<lldb::LanguageType> &languages_for_expressions);
-
- static void
- GetLanguagesSupportingREPLs (std::set<lldb::LanguageType> &languages);
-
+ protected:
+ ImageListTypeScavenger() = default;
+
+ ~ImageListTypeScavenger() override = default;
+
+ // is this type something we should accept? it's usually going to be a
+ // filter by language + maybe some sugar tweaking
+ // returning an empty type means rejecting this candidate entirely;
+ // any other result will be accepted as a valid match
+ virtual CompilerType AdjustForInclusion(CompilerType &candidate) = 0;
+
+ bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
+ ResultSet &results) override;
+ };
+
+ template <typename... ScavengerTypes>
+ class EitherTypeScavenger : public TypeScavenger {
+ public:
+ EitherTypeScavenger() : TypeScavenger(), m_scavengers() {
+ for (std::shared_ptr<TypeScavenger> scavenger : { std::shared_ptr<TypeScavenger>(new ScavengerTypes())... }) {
+ if (scavenger)
+ m_scavengers.push_back(scavenger);
+ }
+ }
+ protected:
+ bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
+ ResultSet &results) override {
+ const bool append = false;
+ for (auto& scavenger : m_scavengers) {
+ if (scavenger && scavenger->Find(exe_scope, key, results, append))
+ return true;
+ }
+ return false;
+ }
+ private:
+ std::vector<std::shared_ptr<TypeScavenger>> m_scavengers;
+ };
+
+ template <typename... ScavengerTypes>
+ class UnionTypeScavenger : public TypeScavenger {
+ public:
+ UnionTypeScavenger() : TypeScavenger(), m_scavengers() {
+ for (std::shared_ptr<TypeScavenger> scavenger : { std::shared_ptr<TypeScavenger>(new ScavengerTypes())... }) {
+ if (scavenger)
+ m_scavengers.push_back(scavenger);
+ }
+ }
+ protected:
+ bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
+ ResultSet &results) override {
+ const bool append = true;
+ bool success = false;
+ for (auto& scavenger : m_scavengers) {
+ if (scavenger)
+ success = scavenger->Find(exe_scope, key, results, append) || success;
+ }
+ return success;
+ }
+ private:
+ std::vector<std::shared_ptr<TypeScavenger>> m_scavengers;
+ };
+
+ enum class FunctionNameRepresentation {
+ eName,
+ eNameWithArgs,
+ eNameWithNoArgs
+ };
+
+ ~Language() override;
+
+ static Language *FindPlugin(lldb::LanguageType language);
+
+ // return false from callback to stop iterating
+ static void ForEach(std::function<bool(Language *)> callback);
+
+ virtual lldb::LanguageType GetLanguageType() const = 0;
+
+ virtual bool IsTopLevelFunction(Function &function);
+
+ virtual lldb::TypeCategoryImplSP GetFormatters();
+
+ virtual HardcodedFormatters::HardcodedFormatFinder GetHardcodedFormats();
+
+ virtual HardcodedFormatters::HardcodedSummaryFinder GetHardcodedSummaries();
+
+ virtual HardcodedFormatters::HardcodedSyntheticFinder
+ GetHardcodedSynthetics();
+
+ virtual HardcodedFormatters::HardcodedValidatorFinder
+ GetHardcodedValidators();
+
+ virtual std::vector<ConstString>
+ GetPossibleFormattersMatches(ValueObject &valobj,
+ lldb::DynamicValueType use_dynamic);
+
+ virtual lldb_private::formatters::StringPrinter::EscapingHelper
+ GetStringPrinterEscapingHelper(
+ lldb_private::formatters::StringPrinter::GetPrintableElementType);
+
+ virtual std::unique_ptr<TypeScavenger> GetTypeScavenger();
+
+ virtual const char *GetLanguageSpecificTypeLookupHelp();
+
+ // if an individual data formatter can apply to several types and cross a
+ // language boundary
+ // it makes sense for individual languages to want to customize the printing
+ // of values of that
+ // type by appending proper prefix/suffix information in language-specific
+ // ways
+ virtual bool GetFormatterPrefixSuffix(ValueObject &valobj,
+ ConstString type_hint,
+ std::string &prefix,
+ std::string &suffix);
+
+ // if a language has a custom format for printing variable declarations that
+ // it wants LLDB to honor
+ // it should return an appropriate closure here
+ virtual DumpValueObjectOptions::DeclPrintingHelper GetDeclPrintingHelper();
+
+ virtual LazyBool IsLogicalTrue(ValueObject &valobj, Error &error);
+
+ // for a ValueObject of some "reference type", if the value points to the
+ // nil/null object, this method returns true
+ virtual bool IsNilReference(ValueObject &valobj);
+
+ // for a ValueObject of some "reference type", if the language provides a
+ // technique
+ // to decide whether the reference has ever been assigned to some object, this
+ // method
+ // will return true if such detection is possible, and if the reference has
+ // never been assigned
+ virtual bool IsUninitializedReference(ValueObject &valobj);
+
+ virtual bool GetFunctionDisplayName(const SymbolContext *sc,
+ const ExecutionContext *exe_ctx,
+ FunctionNameRepresentation representation,
+ Stream &s);
+
+ virtual void GetExceptionResolverDescription(bool catch_on, bool throw_on,
+ Stream &s);
+
+ static void GetDefaultExceptionResolverDescription(bool catch_on,
+ bool throw_on, Stream &s);
+
+ // These are accessors for general information about the Languages lldb knows
+ // about:
+
+ static lldb::LanguageType
+ GetLanguageTypeFromString(const char *string) = delete;
+ static lldb::LanguageType GetLanguageTypeFromString(llvm::StringRef string);
+
+ static const char *GetNameForLanguageType(lldb::LanguageType language);
+
+ static void PrintAllLanguages(Stream &s, const char *prefix,
+ const char *suffix);
+
+ // return false from callback to stop iterating
+ static void ForAllLanguages(std::function<bool(lldb::LanguageType)> callback);
+
+ static bool LanguageIsCPlusPlus(lldb::LanguageType language);
+
+ static bool LanguageIsObjC(lldb::LanguageType language);
+
+ static bool LanguageIsC(lldb::LanguageType language);
+
+ static bool LanguageIsPascal(lldb::LanguageType language);
+
+ // return the primary language, so if LanguageIsC(l), return eLanguageTypeC,
+ // etc.
+ static lldb::LanguageType GetPrimaryLanguage(lldb::LanguageType language);
+
+ static void GetLanguagesSupportingTypeSystems(
+ std::set<lldb::LanguageType> &languages,
+ std::set<lldb::LanguageType> &languages_for_expressions);
+
+ static void
+ GetLanguagesSupportingREPLs(std::set<lldb::LanguageType> &languages);
+
protected:
- //------------------------------------------------------------------
- // Classes that inherit from Language can see and modify these
- //------------------------------------------------------------------
-
- Language();
+ //------------------------------------------------------------------
+ // Classes that inherit from Language can see and modify these
+ //------------------------------------------------------------------
+
+ Language();
+
private:
-
- DISALLOW_COPY_AND_ASSIGN (Language);
+ DISALLOW_COPY_AND_ASSIGN(Language);
};
-
+
} // namespace lldb_private
#endif // liblldb_Language_h_
diff --git a/include/lldb/Target/LanguageRuntime.h b/include/lldb/Target/LanguageRuntime.h
index beb7a9e74876..a57216e84794 100644
--- a/include/lldb/Target/LanguageRuntime.h
+++ b/include/lldb/Target/LanguageRuntime.h
@@ -1,4 +1,5 @@
-//===-- LanguageRuntime.h ---------------------------------------------------*- C++ -*-===//
+//===-- LanguageRuntime.h ---------------------------------------------------*-
+// C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,168 +15,161 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-public.h"
#include "lldb/Breakpoint/BreakpointResolver.h"
#include "lldb/Breakpoint/BreakpointResolverName.h"
#include "lldb/Core/PluginInterface.h"
-#include "lldb/lldb-private.h"
-#include "lldb/Core/ValueObject.h"
#include "lldb/Core/Value.h"
-#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Core/ValueObject.h"
#include "lldb/Expression/LLVMUserExpression.h"
+#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/lldb-private.h"
+#include "lldb/lldb-public.h"
#include "clang/Basic/TargetOptions.h"
namespace lldb_private {
-class LanguageRuntime :
- public PluginInterface
-{
+class ExceptionSearchFilter : public SearchFilter {
public:
+ ExceptionSearchFilter(const lldb::TargetSP &target_sp,
+ lldb::LanguageType language,
+ bool update_module_list = true);
+
+ ~ExceptionSearchFilter() override = default;
+
+ bool ModulePasses(const lldb::ModuleSP &module_sp) override;
+
+ bool ModulePasses(const FileSpec &spec) override;
+
+ void Search(Searcher &searcher) override;
+
+ void GetDescription(Stream *s) override;
+
+ static SearchFilter *
+ CreateFromStructuredData(Target &target,
+ const StructuredData::Dictionary &data_dict,
+ Error &error);
+
+ StructuredData::ObjectSP SerializeToStructuredData() override;
- ~LanguageRuntime() override;
-
- static LanguageRuntime*
- FindPlugin (Process *process, lldb::LanguageType language);
-
- static void
- InitializeCommands (CommandObject* parent);
-
- virtual lldb::LanguageType
- GetLanguageType () const = 0;
-
- virtual bool
- GetObjectDescription (Stream &str, ValueObject &object) = 0;
-
- virtual bool
- GetObjectDescription (Stream &str, Value &value, ExecutionContextScope *exe_scope) = 0;
-
- // this call should return true if it could set the name and/or the type
- virtual bool
- GetDynamicTypeAndAddress (ValueObject &in_value,
- lldb::DynamicValueType use_dynamic,
- TypeAndOrName &class_type_or_name,
- Address &address,
- Value::ValueType &value_type) = 0;
-
- // This call should return a CompilerType given a generic type name
- // and an ExecutionContextScope in which one can actually fetch
- // any specialization information required.
- virtual CompilerType
- GetConcreteType (ExecutionContextScope *exe_scope,
- ConstString abstract_type_name)
- {
- return CompilerType();
- }
-
- // This should be a fast test to determine whether it is likely that this value would
- // have a dynamic type.
- virtual bool
- CouldHaveDynamicValue (ValueObject &in_value) = 0;
-
- // The contract for GetDynamicTypeAndAddress() is to return a "bare-bones" dynamic type
- // For instance, given a Base* pointer, GetDynamicTypeAndAddress() will return the type of
- // Derived, not Derived*. The job of this API is to correct this misalignment between the
- // static type and the discovered dynamic type
- virtual TypeAndOrName
- FixUpDynamicType (const TypeAndOrName& type_and_or_name,
- ValueObject& static_value) = 0;
-
- virtual void
- SetExceptionBreakpoints ()
- {
- }
-
- virtual void
- ClearExceptionBreakpoints ()
- {
- }
-
- virtual bool
- ExceptionBreakpointsAreSet ()
- {
- return false;
- }
-
- virtual bool
- ExceptionBreakpointsExplainStop (lldb::StopInfoSP stop_reason)
- {
- return false;
- }
-
- static lldb::BreakpointSP
- CreateExceptionBreakpoint (Target &target,
- lldb::LanguageType language,
- bool catch_bp,
- bool throw_bp,
- bool is_internal = false);
-
- static Breakpoint::BreakpointPreconditionSP
- CreateExceptionPrecondition (lldb::LanguageType language,
- bool catch_bp,
- bool throw_bp);
- Process *
- GetProcess()
- {
- return m_process;
- }
-
- Target&
- GetTargetRef()
- {
- return m_process->GetTarget();
- }
-
- virtual lldb::BreakpointResolverSP
- CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp) = 0;
-
- virtual lldb::SearchFilterSP
- CreateExceptionSearchFilter ();
-
- virtual bool
- GetTypeBitSize (const CompilerType& compiler_type,
- uint64_t &size)
- {
- return false;
- }
-
- virtual bool
- IsRuntimeSupportValue (ValueObject& valobj)
- {
- return false;
- }
-
- virtual void
- ModulesDidLoad (const ModuleList &module_list)
- {
- }
-
- // Called by the Clang expression evaluation engine to allow runtimes to alter the set of target options provided to
- // the compiler.
- // If the options prototype is modified, runtimes must return true, false otherwise.
- virtual bool
- GetOverrideExprOptions(clang::TargetOptions &prototype)
- {
- return false;
- }
-
- // Called by ClangExpressionParser::PrepareForExecution to query for any custom LLVM IR passes
- // that need to be run before an expression is assembled and run.
- virtual bool
- GetIRPasses(LLVMUserExpression::IRPasses &custom_passes)
- {
- return false;
- }
protected:
- //------------------------------------------------------------------
- // Classes that inherit from LanguageRuntime can see and modify these
- //------------------------------------------------------------------
-
- LanguageRuntime(Process *process);
- Process *m_process;
-private:
+ lldb::LanguageType m_language;
+ LanguageRuntime *m_language_runtime;
+ lldb::SearchFilterSP m_filter_sp;
+
+ lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) override;
+
+ void UpdateModuleListIfNeeded();
+};
+
+class LanguageRuntime : public PluginInterface {
+public:
+ ~LanguageRuntime() override;
+
+ static LanguageRuntime *FindPlugin(Process *process,
+ lldb::LanguageType language);
+
+ static void InitializeCommands(CommandObject *parent);
+
+ virtual lldb::LanguageType GetLanguageType() const = 0;
- DISALLOW_COPY_AND_ASSIGN (LanguageRuntime);
+ virtual bool GetObjectDescription(Stream &str, ValueObject &object) = 0;
+
+ virtual bool GetObjectDescription(Stream &str, Value &value,
+ ExecutionContextScope *exe_scope) = 0;
+
+ // this call should return true if it could set the name and/or the type
+ virtual bool GetDynamicTypeAndAddress(ValueObject &in_value,
+ lldb::DynamicValueType use_dynamic,
+ TypeAndOrName &class_type_or_name,
+ Address &address,
+ Value::ValueType &value_type) = 0;
+
+ // This call should return a CompilerType given a generic type name
+ // and an ExecutionContextScope in which one can actually fetch
+ // any specialization information required.
+ virtual CompilerType GetConcreteType(ExecutionContextScope *exe_scope,
+ ConstString abstract_type_name) {
+ return CompilerType();
+ }
+
+ // This should be a fast test to determine whether it is likely that this
+ // value would
+ // have a dynamic type.
+ virtual bool CouldHaveDynamicValue(ValueObject &in_value) = 0;
+
+ // The contract for GetDynamicTypeAndAddress() is to return a "bare-bones"
+ // dynamic type
+ // For instance, given a Base* pointer, GetDynamicTypeAndAddress() will return
+ // the type of
+ // Derived, not Derived*. The job of this API is to correct this misalignment
+ // between the
+ // static type and the discovered dynamic type
+ virtual TypeAndOrName FixUpDynamicType(const TypeAndOrName &type_and_or_name,
+ ValueObject &static_value) = 0;
+
+ virtual void SetExceptionBreakpoints() {}
+
+ virtual void ClearExceptionBreakpoints() {}
+
+ virtual bool ExceptionBreakpointsAreSet() { return false; }
+
+ virtual bool ExceptionBreakpointsExplainStop(lldb::StopInfoSP stop_reason) {
+ return false;
+ }
+
+ static lldb::BreakpointSP
+ CreateExceptionBreakpoint(Target &target, lldb::LanguageType language,
+ bool catch_bp, bool throw_bp,
+ bool is_internal = false);
+
+ static Breakpoint::BreakpointPreconditionSP
+ CreateExceptionPrecondition(lldb::LanguageType language, bool catch_bp,
+ bool throw_bp);
+ Process *GetProcess() { return m_process; }
+
+ Target &GetTargetRef() { return m_process->GetTarget(); }
+
+ virtual lldb::BreakpointResolverSP
+ CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp) = 0;
+
+ virtual lldb::SearchFilterSP CreateExceptionSearchFilter();
+
+ virtual bool GetTypeBitSize(const CompilerType &compiler_type,
+ uint64_t &size) {
+ return false;
+ }
+
+ virtual bool IsRuntimeSupportValue(ValueObject &valobj) { return false; }
+
+ virtual void ModulesDidLoad(const ModuleList &module_list) {}
+
+ // Called by the Clang expression evaluation engine to allow runtimes to alter
+ // the set of target options provided to
+ // the compiler.
+ // If the options prototype is modified, runtimes must return true, false
+ // otherwise.
+ virtual bool GetOverrideExprOptions(clang::TargetOptions &prototype) {
+ return false;
+ }
+
+ // Called by ClangExpressionParser::PrepareForExecution to query for any
+ // custom LLVM IR passes
+ // that need to be run before an expression is assembled and run.
+ virtual bool GetIRPasses(LLVMUserExpression::IRPasses &custom_passes) {
+ return false;
+ }
+
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from LanguageRuntime can see and modify these
+ //------------------------------------------------------------------
+
+ LanguageRuntime(Process *process);
+ Process *m_process;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(LanguageRuntime);
};
} // namespace lldb_private
diff --git a/include/lldb/Target/Memory.h b/include/lldb/Target/Memory.h
index f4d776a43c99..57275bbda593 100644
--- a/include/lldb/Target/Memory.h
+++ b/include/lldb/Target/Memory.h
@@ -19,187 +19,140 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Core/RangeMap.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
- //----------------------------------------------------------------------
- // A class to track memory that was read from a live process between
- // runs.
- //----------------------------------------------------------------------
- class MemoryCache
- {
- public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- MemoryCache (Process &process);
-
- ~MemoryCache ();
-
- void
- Clear(bool clear_invalid_ranges = false);
-
- void
- Flush (lldb::addr_t addr, size_t size);
-
- size_t
- Read (lldb::addr_t addr,
- void *dst,
- size_t dst_len,
- Error &error);
-
- uint32_t
- GetMemoryCacheLineSize() const
- {
- return m_L2_cache_line_byte_size ;
- }
-
- void
- AddInvalidRange (lldb::addr_t base_addr, lldb::addr_t byte_size);
-
- bool
- RemoveInvalidRange (lldb::addr_t base_addr, lldb::addr_t byte_size);
-
- // Allow external sources to populate data into the L1 memory cache
- void
- AddL1CacheData(lldb::addr_t addr, const void *src, size_t src_len);
-
- void
- AddL1CacheData(lldb::addr_t addr, const lldb::DataBufferSP &data_buffer_sp);
-
- protected:
- typedef std::map<lldb::addr_t, lldb::DataBufferSP> BlockMap;
- typedef RangeArray<lldb::addr_t, lldb::addr_t, 4> InvalidRanges;
- typedef Range<lldb::addr_t, lldb::addr_t> AddrRange;
- //------------------------------------------------------------------
- // Classes that inherit from MemoryCache can see and modify these
- //------------------------------------------------------------------
- std::recursive_mutex m_mutex;
- BlockMap m_L1_cache; // A first level memory cache whose chunk sizes vary that will be used only if the memory read fits entirely in a chunk
- BlockMap m_L2_cache; // A memory cache of fixed size chinks (m_L2_cache_line_byte_size bytes in size each)
- InvalidRanges m_invalid_ranges;
- Process &m_process;
- uint32_t m_L2_cache_line_byte_size;
- private:
- DISALLOW_COPY_AND_ASSIGN (MemoryCache);
- };
-
-
- class AllocatedBlock
- {
- public:
- AllocatedBlock (lldb::addr_t addr,
- uint32_t byte_size,
- uint32_t permissions,
- uint32_t chunk_size);
-
- ~AllocatedBlock ();
-
- lldb::addr_t
- ReserveBlock (uint32_t size);
-
- bool
- FreeBlock (lldb::addr_t addr);
-
- lldb::addr_t
- GetBaseAddress () const
- {
- return m_addr;
- }
-
- uint32_t
- GetByteSize () const
- {
- return m_byte_size;
- }
-
- uint32_t
- GetPermissions () const
- {
- return m_permissions;
- }
-
- uint32_t
- GetChunkSize () const
- {
- return m_chunk_size;
- }
-
- bool
- Contains (lldb::addr_t addr) const
- {
- return ((addr >= m_addr) && addr < (m_addr + m_byte_size));
- }
- protected:
- uint32_t
- TotalChunks () const
- {
- return m_byte_size / m_chunk_size;
- }
-
- uint32_t
- CalculateChunksNeededForSize (uint32_t size) const
- {
- return (size + m_chunk_size - 1) / m_chunk_size;
- }
- const lldb::addr_t m_addr; // Base address of this block of memory
- const uint32_t m_byte_size; // 4GB of chunk should be enough...
- const uint32_t m_permissions; // Permissions for this memory (logical OR of lldb::Permissions bits)
- const uint32_t m_chunk_size; // The size of chunks that the memory at m_addr is divied up into
- typedef std::map<uint32_t, uint32_t> OffsetToChunkSize;
- OffsetToChunkSize m_offset_to_chunk_size;
- };
-
-
- //----------------------------------------------------------------------
- // A class that can track allocated memory and give out allocated memory
- // without us having to make an allocate/deallocate call every time we
- // need some memory in a process that is being debugged.
- //----------------------------------------------------------------------
- class AllocatedMemoryCache
- {
- public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- AllocatedMemoryCache (Process &process);
-
- ~AllocatedMemoryCache ();
-
- void
- Clear();
-
- lldb::addr_t
- AllocateMemory (size_t byte_size,
- uint32_t permissions,
- Error &error);
-
- bool
- DeallocateMemory (lldb::addr_t ptr);
-
- protected:
- typedef std::shared_ptr<AllocatedBlock> AllocatedBlockSP;
-
- AllocatedBlockSP
- AllocatePage (uint32_t byte_size,
- uint32_t permissions,
- uint32_t chunk_size,
- Error &error);
-
-
- //------------------------------------------------------------------
- // Classes that inherit from MemoryCache can see and modify these
- //------------------------------------------------------------------
- Process &m_process;
- std::recursive_mutex m_mutex;
- typedef std::multimap<uint32_t, AllocatedBlockSP> PermissionsToBlockMap;
- PermissionsToBlockMap m_memory_map;
-
- private:
- DISALLOW_COPY_AND_ASSIGN (AllocatedMemoryCache);
- };
+//----------------------------------------------------------------------
+// A class to track memory that was read from a live process between
+// runs.
+//----------------------------------------------------------------------
+class MemoryCache {
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ MemoryCache(Process &process);
+
+ ~MemoryCache();
+
+ void Clear(bool clear_invalid_ranges = false);
+
+ void Flush(lldb::addr_t addr, size_t size);
+
+ size_t Read(lldb::addr_t addr, void *dst, size_t dst_len, Error &error);
+
+ uint32_t GetMemoryCacheLineSize() const { return m_L2_cache_line_byte_size; }
+
+ void AddInvalidRange(lldb::addr_t base_addr, lldb::addr_t byte_size);
+
+ bool RemoveInvalidRange(lldb::addr_t base_addr, lldb::addr_t byte_size);
+
+ // Allow external sources to populate data into the L1 memory cache
+ void AddL1CacheData(lldb::addr_t addr, const void *src, size_t src_len);
+
+ void AddL1CacheData(lldb::addr_t addr,
+ const lldb::DataBufferSP &data_buffer_sp);
+
+protected:
+ typedef std::map<lldb::addr_t, lldb::DataBufferSP> BlockMap;
+ typedef RangeArray<lldb::addr_t, lldb::addr_t, 4> InvalidRanges;
+ typedef Range<lldb::addr_t, lldb::addr_t> AddrRange;
+ //------------------------------------------------------------------
+ // Classes that inherit from MemoryCache can see and modify these
+ //------------------------------------------------------------------
+ std::recursive_mutex m_mutex;
+ BlockMap m_L1_cache; // A first level memory cache whose chunk sizes vary that
+ // will be used only if the memory read fits entirely in
+ // a chunk
+ BlockMap m_L2_cache; // A memory cache of fixed size chinks
+ // (m_L2_cache_line_byte_size bytes in size each)
+ InvalidRanges m_invalid_ranges;
+ Process &m_process;
+ uint32_t m_L2_cache_line_byte_size;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(MemoryCache);
+};
+
+class AllocatedBlock {
+public:
+ AllocatedBlock(lldb::addr_t addr, uint32_t byte_size, uint32_t permissions,
+ uint32_t chunk_size);
+
+ ~AllocatedBlock();
+
+ lldb::addr_t ReserveBlock(uint32_t size);
+
+ bool FreeBlock(lldb::addr_t addr);
+
+ lldb::addr_t GetBaseAddress() const { return m_addr; }
+
+ uint32_t GetByteSize() const { return m_byte_size; }
+
+ uint32_t GetPermissions() const { return m_permissions; }
+
+ uint32_t GetChunkSize() const { return m_chunk_size; }
+
+ bool Contains(lldb::addr_t addr) const {
+ return ((addr >= m_addr) && addr < (m_addr + m_byte_size));
+ }
+
+protected:
+ uint32_t TotalChunks() const { return m_byte_size / m_chunk_size; }
+
+ uint32_t CalculateChunksNeededForSize(uint32_t size) const {
+ return (size + m_chunk_size - 1) / m_chunk_size;
+ }
+ const lldb::addr_t m_addr; // Base address of this block of memory
+ const uint32_t m_byte_size; // 4GB of chunk should be enough...
+ const uint32_t m_permissions; // Permissions for this memory (logical OR of
+ // lldb::Permissions bits)
+ const uint32_t m_chunk_size; // The size of chunks that the memory at m_addr
+ // is divied up into
+ typedef std::map<uint32_t, uint32_t> OffsetToChunkSize;
+ OffsetToChunkSize m_offset_to_chunk_size;
+};
+
+//----------------------------------------------------------------------
+// A class that can track allocated memory and give out allocated memory
+// without us having to make an allocate/deallocate call every time we
+// need some memory in a process that is being debugged.
+//----------------------------------------------------------------------
+class AllocatedMemoryCache {
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ AllocatedMemoryCache(Process &process);
+
+ ~AllocatedMemoryCache();
+
+ void Clear();
+
+ lldb::addr_t AllocateMemory(size_t byte_size, uint32_t permissions,
+ Error &error);
+
+ bool DeallocateMemory(lldb::addr_t ptr);
+
+protected:
+ typedef std::shared_ptr<AllocatedBlock> AllocatedBlockSP;
+
+ AllocatedBlockSP AllocatePage(uint32_t byte_size, uint32_t permissions,
+ uint32_t chunk_size, Error &error);
+
+ //------------------------------------------------------------------
+ // Classes that inherit from MemoryCache can see and modify these
+ //------------------------------------------------------------------
+ Process &m_process;
+ std::recursive_mutex m_mutex;
+ typedef std::multimap<uint32_t, AllocatedBlockSP> PermissionsToBlockMap;
+ PermissionsToBlockMap m_memory_map;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(AllocatedMemoryCache);
+};
} // namespace lldb_private
-#endif // liblldb_Memory_h_
+#endif // liblldb_Memory_h_
diff --git a/include/lldb/Target/MemoryHistory.h b/include/lldb/Target/MemoryHistory.h
index b3bd62d6547c..acc36ffe2eb4 100644
--- a/include/lldb/Target/MemoryHistory.h
+++ b/include/lldb/Target/MemoryHistory.h
@@ -1,4 +1,5 @@
-//===-- MemoryHistory.h ---------------------------------------------------*- C++ -*-===//
+//===-- MemoryHistory.h ---------------------------------------------------*-
+//C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,27 +17,22 @@
// Other libraries and framework includes
// Project includes
+#include "lldb/Core/PluginInterface.h"
#include "lldb/lldb-private.h"
#include "lldb/lldb-types.h"
-#include "lldb/Core/PluginInterface.h"
namespace lldb_private {
-
+
typedef std::vector<lldb::ThreadSP> HistoryThreads;
-
-class MemoryHistory :
- public std::enable_shared_from_this<MemoryHistory>,
- public PluginInterface
-{
-public:
- static lldb::MemoryHistorySP
- FindPlugin (const lldb::ProcessSP process);
+class MemoryHistory : public std::enable_shared_from_this<MemoryHistory>,
+ public PluginInterface {
+public:
+ static lldb::MemoryHistorySP FindPlugin(const lldb::ProcessSP process);
- virtual HistoryThreads
- GetHistoryThreads(lldb::addr_t address) = 0;
+ virtual HistoryThreads GetHistoryThreads(lldb::addr_t address) = 0;
};
-
+
} // namespace lldb_private
-#endif // liblldb_MemoryHistory_h_
+#endif // liblldb_MemoryHistory_h_
diff --git a/include/lldb/Target/MemoryRegionInfo.h b/include/lldb/Target/MemoryRegionInfo.h
index 5c82a1f294dd..be0cfa429b8f 100644
--- a/include/lldb/Target/MemoryRegionInfo.h
+++ b/include/lldb/Target/MemoryRegionInfo.h
@@ -1,4 +1,5 @@
-//===-- MemoryRegionInfo.h ---------------------------------------*- C++ -*-===//
+//===-- MemoryRegionInfo.h ---------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,154 +11,93 @@
#ifndef lldb_MemoryRegionInfo_h
#define lldb_MemoryRegionInfo_h
+#include "lldb/Core/ConstString.h"
#include "lldb/Core/RangeMap.h"
#include "lldb/Utility/Range.h"
-namespace lldb_private
-{
- class MemoryRegionInfo
- {
- public:
- typedef Range<lldb::addr_t, lldb::addr_t> RangeType;
-
- enum OptionalBool {
- eDontKnow = -1,
- eNo = 0,
- eYes = 1
- };
-
- MemoryRegionInfo () :
- m_range (),
- m_read (eDontKnow),
- m_write (eDontKnow),
- m_execute (eDontKnow),
- m_mapped (eDontKnow)
- {
- }
-
- ~MemoryRegionInfo ()
- {
- }
-
- RangeType &
- GetRange()
- {
- return m_range;
- }
-
- void
- Clear()
- {
- m_range.Clear();
- m_read = m_write = m_execute = eDontKnow;
- }
-
- const RangeType &
- GetRange() const
- {
- return m_range;
- }
-
- OptionalBool
- GetReadable () const
- {
- return m_read;
- }
-
- OptionalBool
- GetWritable () const
- {
- return m_write;
- }
-
- OptionalBool
- GetExecutable () const
- {
- return m_execute;
- }
-
- OptionalBool
- GetMapped () const
- {
- return m_mapped;
- }
-
- void
- SetReadable (OptionalBool val)
- {
- m_read = val;
- }
-
- void
- SetWritable (OptionalBool val)
- {
- m_write = val;
- }
-
- void
- SetExecutable (OptionalBool val)
- {
- m_execute = val;
- }
-
- void
- SetMapped (OptionalBool val)
- {
- m_mapped = val;
- }
-
- //----------------------------------------------------------------------
- // Get permissions as a uint32_t that is a mask of one or more bits from
- // the lldb::Permissions
- //----------------------------------------------------------------------
- uint32_t
- GetLLDBPermissions() const
- {
- uint32_t permissions = 0;
- if (m_read)
- permissions |= lldb::ePermissionsReadable;
- if (m_write)
- permissions |= lldb::ePermissionsWritable;
- if (m_execute)
- permissions |= lldb::ePermissionsExecutable;
- return permissions;
- }
-
- //----------------------------------------------------------------------
- // Set permissions from a uint32_t that contains one or more bits from
- // the lldb::Permissions
- //----------------------------------------------------------------------
- void
- SetLLDBPermissions(uint32_t permissions)
- {
- m_read = (permissions & lldb::ePermissionsReadable) ? eYes : eNo;
- m_write = (permissions & lldb::ePermissionsWritable) ? eYes : eNo;
- m_execute = (permissions & lldb::ePermissionsExecutable) ? eYes : eNo;
- }
-
- bool
- operator == (const MemoryRegionInfo &rhs) const
- {
- return m_range == rhs.m_range &&
- m_read == rhs.m_read &&
- m_write == rhs.m_write &&
- m_execute == rhs.m_execute &&
- m_mapped == rhs.m_mapped;
- }
-
- bool
- operator != (const MemoryRegionInfo &rhs) const
- {
- return !(*this == rhs);
- }
-
- protected:
- RangeType m_range;
- OptionalBool m_read;
- OptionalBool m_write;
- OptionalBool m_execute;
- OptionalBool m_mapped;
- };
+namespace lldb_private {
+class MemoryRegionInfo {
+public:
+ typedef Range<lldb::addr_t, lldb::addr_t> RangeType;
+
+ enum OptionalBool { eDontKnow = -1, eNo = 0, eYes = 1 };
+
+ MemoryRegionInfo()
+ : m_range(), m_read(eDontKnow), m_write(eDontKnow), m_execute(eDontKnow),
+ m_mapped(eDontKnow) {}
+
+ ~MemoryRegionInfo() {}
+
+ RangeType &GetRange() { return m_range; }
+
+ void Clear() {
+ m_range.Clear();
+ m_read = m_write = m_execute = eDontKnow;
+ }
+
+ const RangeType &GetRange() const { return m_range; }
+
+ OptionalBool GetReadable() const { return m_read; }
+
+ OptionalBool GetWritable() const { return m_write; }
+
+ OptionalBool GetExecutable() const { return m_execute; }
+
+ OptionalBool GetMapped() const { return m_mapped; }
+
+ const ConstString &GetName() const { return m_name; }
+
+ void SetReadable(OptionalBool val) { m_read = val; }
+
+ void SetWritable(OptionalBool val) { m_write = val; }
+
+ void SetExecutable(OptionalBool val) { m_execute = val; }
+
+ void SetMapped(OptionalBool val) { m_mapped = val; }
+
+ void SetName(const char *name) { m_name = ConstString(name); }
+
+ //----------------------------------------------------------------------
+ // Get permissions as a uint32_t that is a mask of one or more bits from
+ // the lldb::Permissions
+ //----------------------------------------------------------------------
+ uint32_t GetLLDBPermissions() const {
+ uint32_t permissions = 0;
+ if (m_read)
+ permissions |= lldb::ePermissionsReadable;
+ if (m_write)
+ permissions |= lldb::ePermissionsWritable;
+ if (m_execute)
+ permissions |= lldb::ePermissionsExecutable;
+ return permissions;
+ }
+
+ //----------------------------------------------------------------------
+ // Set permissions from a uint32_t that contains one or more bits from
+ // the lldb::Permissions
+ //----------------------------------------------------------------------
+ void SetLLDBPermissions(uint32_t permissions) {
+ m_read = (permissions & lldb::ePermissionsReadable) ? eYes : eNo;
+ m_write = (permissions & lldb::ePermissionsWritable) ? eYes : eNo;
+ m_execute = (permissions & lldb::ePermissionsExecutable) ? eYes : eNo;
+ }
+
+ bool operator==(const MemoryRegionInfo &rhs) const {
+ return m_range == rhs.m_range && m_read == rhs.m_read &&
+ m_write == rhs.m_write && m_execute == rhs.m_execute &&
+ m_mapped == rhs.m_mapped;
+ }
+
+ bool operator!=(const MemoryRegionInfo &rhs) const { return !(*this == rhs); }
+
+protected:
+ RangeType m_range;
+ OptionalBool m_read;
+ OptionalBool m_write;
+ OptionalBool m_execute;
+ OptionalBool m_mapped;
+ ConstString m_name;
+};
}
#endif // #ifndef lldb_MemoryRegionInfo_h
diff --git a/include/lldb/Target/ObjCLanguageRuntime.h b/include/lldb/Target/ObjCLanguageRuntime.h
index 75f096fdedfe..0a9ffa933bd1 100644
--- a/include/lldb/Target/ObjCLanguageRuntime.h
+++ b/include/lldb/Target/ObjCLanguageRuntime.h
@@ -21,500 +21,404 @@
#include "llvm/Support/Casting.h"
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Core/ThreadSafeDenseMap.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/DeclVendor.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Target/LanguageRuntime.h"
+#include "lldb/lldb-private.h"
class CommandObjectObjC_ClassTable_Dump;
namespace lldb_private {
-
+
class UtilityFunction;
-class ObjCLanguageRuntime :
- public LanguageRuntime
-{
+class ObjCLanguageRuntime : public LanguageRuntime {
public:
- enum class ObjCRuntimeVersions
- {
- eObjC_VersionUnknown = 0,
- eAppleObjC_V1 = 1,
- eAppleObjC_V2 = 2
- };
-
- typedef lldb::addr_t ObjCISA;
-
- class ClassDescriptor;
- typedef std::shared_ptr<ClassDescriptor> ClassDescriptorSP;
-
- // the information that we want to support retrieving from an ObjC class
- // this needs to be pure virtual since there are at least 2 different implementations
- // of the runtime, and more might come
- class ClassDescriptor
- {
- public:
- ClassDescriptor() :
- m_is_kvo (eLazyBoolCalculate),
- m_is_cf (eLazyBoolCalculate),
- m_type_wp ()
- {
- }
-
- virtual
- ~ClassDescriptor() = default;
-
- virtual ConstString
- GetClassName () = 0;
-
- virtual ClassDescriptorSP
- GetSuperclass () = 0;
-
- virtual ClassDescriptorSP
- GetMetaclass () const = 0;
-
- // virtual if any implementation has some other version-specific rules
- // but for the known v1/v2 this is all that needs to be done
- virtual bool
- IsKVO ()
- {
- if (m_is_kvo == eLazyBoolCalculate)
- {
- const char* class_name = GetClassName().AsCString();
- if (class_name && *class_name)
- m_is_kvo = (LazyBool)(strstr(class_name,"NSKVONotifying_") == class_name);
- }
- return (m_is_kvo == eLazyBoolYes);
- }
-
- // virtual if any implementation has some other version-specific rules
- // but for the known v1/v2 this is all that needs to be done
- virtual bool
- IsCFType ()
- {
- if (m_is_cf == eLazyBoolCalculate)
- {
- const char* class_name = GetClassName().AsCString();
- if (class_name && *class_name)
- m_is_cf = (LazyBool)(strcmp(class_name,"__NSCFType") == 0 ||
- strcmp(class_name,"NSCFType") == 0);
- }
- return (m_is_cf == eLazyBoolYes);
- }
-
- virtual bool
- IsValid () = 0;
-
- virtual bool
- GetTaggedPointerInfo(uint64_t* info_bits = nullptr,
- uint64_t* value_bits = nullptr,
- uint64_t* payload = nullptr) = 0;
-
- virtual uint64_t
- GetInstanceSize () = 0;
-
- // use to implement version-specific additional constraints on pointers
- virtual bool
- CheckPointer (lldb::addr_t value,
- uint32_t ptr_size) const
- {
- return true;
- }
-
- virtual ObjCISA
- GetISA () = 0;
-
- // This should return true iff the interface could be completed
- virtual bool
- Describe (std::function <void (ObjCISA)> const &superclass_func,
- std::function <bool (const char*, const char*)> const &instance_method_func,
- std::function <bool (const char*, const char*)> const &class_method_func,
- std::function <bool (const char *, const char *, lldb::addr_t, uint64_t)> const &ivar_func) const
- {
- return false;
- }
-
- lldb::TypeSP
- GetType ()
- {
- return m_type_wp.lock();
- }
-
- void
- SetType (const lldb::TypeSP &type_sp)
- {
- m_type_wp = type_sp;
- }
-
- struct iVarDescriptor {
- ConstString m_name;
- CompilerType m_type;
- uint64_t m_size;
- int32_t m_offset;
- };
-
- virtual size_t
- GetNumIVars ()
- {
- return 0;
- }
-
- virtual iVarDescriptor
- GetIVarAtIndex (size_t idx)
- {
- return iVarDescriptor();
- }
-
- protected:
- bool
- IsPointerValid (lldb::addr_t value,
- uint32_t ptr_size,
- bool allow_NULLs = false,
- bool allow_tagged = false,
- bool check_version_specific = false) const;
-
- private:
- LazyBool m_is_kvo;
- LazyBool m_is_cf;
- lldb::TypeWP m_type_wp;
- };
-
- class EncodingToType
- {
- public:
- virtual ~EncodingToType();
-
- virtual CompilerType RealizeType (ClangASTContext& ast_ctx, const char* name, bool for_expression);
- virtual CompilerType RealizeType (const char* name, bool for_expression);
-
- virtual CompilerType RealizeType (clang::ASTContext& ast_ctx, const char* name, bool for_expression) = 0;
-
- protected:
- std::unique_ptr<ClangASTContext> m_scratch_ast_ctx_ap;
- };
+ enum class ObjCRuntimeVersions {
+ eObjC_VersionUnknown = 0,
+ eAppleObjC_V1 = 1,
+ eAppleObjC_V2 = 2
+ };
+
+ typedef lldb::addr_t ObjCISA;
+
+ class ClassDescriptor;
+ typedef std::shared_ptr<ClassDescriptor> ClassDescriptorSP;
+
+ // the information that we want to support retrieving from an ObjC class
+ // this needs to be pure virtual since there are at least 2 different
+ // implementations
+ // of the runtime, and more might come
+ class ClassDescriptor {
+ public:
+ ClassDescriptor()
+ : m_is_kvo(eLazyBoolCalculate), m_is_cf(eLazyBoolCalculate),
+ m_type_wp() {}
+
+ virtual ~ClassDescriptor() = default;
+
+ virtual ConstString GetClassName() = 0;
+
+ virtual ClassDescriptorSP GetSuperclass() = 0;
+
+ virtual ClassDescriptorSP GetMetaclass() const = 0;
+
+ // virtual if any implementation has some other version-specific rules
+ // but for the known v1/v2 this is all that needs to be done
+ virtual bool IsKVO() {
+ if (m_is_kvo == eLazyBoolCalculate) {
+ const char *class_name = GetClassName().AsCString();
+ if (class_name && *class_name)
+ m_is_kvo =
+ (LazyBool)(strstr(class_name, "NSKVONotifying_") == class_name);
+ }
+ return (m_is_kvo == eLazyBoolYes);
+ }
- class ObjCExceptionPrecondition : public Breakpoint::BreakpointPrecondition
- {
- public:
- ObjCExceptionPrecondition();
+ // virtual if any implementation has some other version-specific rules
+ // but for the known v1/v2 this is all that needs to be done
+ virtual bool IsCFType() {
+ if (m_is_cf == eLazyBoolCalculate) {
+ const char *class_name = GetClassName().AsCString();
+ if (class_name && *class_name)
+ m_is_cf = (LazyBool)(strcmp(class_name, "__NSCFType") == 0 ||
+ strcmp(class_name, "NSCFType") == 0);
+ }
+ return (m_is_cf == eLazyBoolYes);
+ }
- ~ObjCExceptionPrecondition() override = default;
+ virtual bool IsValid() = 0;
- bool EvaluatePrecondition(StoppointCallbackContext &context) override;
- void GetDescription(Stream &stream, lldb::DescriptionLevel level) override;
- Error ConfigurePrecondition(Args &args) override;
+ virtual bool GetTaggedPointerInfo(uint64_t *info_bits = nullptr,
+ uint64_t *value_bits = nullptr,
+ uint64_t *payload = nullptr) = 0;
- protected:
- void AddClassName(const char *class_name);
+ virtual uint64_t GetInstanceSize() = 0;
- private:
- std::unordered_set<std::string> m_class_names;
- };
-
- class TaggedPointerVendor
- {
- public:
- virtual
- ~TaggedPointerVendor() = default;
+ // use to implement version-specific additional constraints on pointers
+ virtual bool CheckPointer(lldb::addr_t value, uint32_t ptr_size) const {
+ return true;
+ }
+
+ virtual ObjCISA GetISA() = 0;
- virtual bool
- IsPossibleTaggedPointer (lldb::addr_t ptr) = 0;
-
- virtual ObjCLanguageRuntime::ClassDescriptorSP
- GetClassDescriptor (lldb::addr_t ptr) = 0;
+ // This should return true iff the interface could be completed
+ virtual bool
+ Describe(std::function<void(ObjCISA)> const &superclass_func,
+ std::function<bool(const char *, const char *)> const
+ &instance_method_func,
+ std::function<bool(const char *, const char *)> const
+ &class_method_func,
+ std::function<bool(const char *, const char *, lldb::addr_t,
+ uint64_t)> const &ivar_func) const {
+ return false;
+ }
- protected:
- TaggedPointerVendor() = default;
+ lldb::TypeSP GetType() { return m_type_wp.lock(); }
- private:
- DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendor);
+ void SetType(const lldb::TypeSP &type_sp) { m_type_wp = type_sp; }
+
+ struct iVarDescriptor {
+ ConstString m_name;
+ CompilerType m_type;
+ uint64_t m_size;
+ int32_t m_offset;
};
-
- ~ObjCLanguageRuntime() override;
- virtual TaggedPointerVendor*
- GetTaggedPointerVendor ()
- {
- return nullptr;
- }
-
- typedef std::shared_ptr<EncodingToType> EncodingToTypeSP;
-
- virtual EncodingToTypeSP
- GetEncodingToType ();
-
- virtual ClassDescriptorSP
- GetClassDescriptor (ValueObject& in_value);
-
- ClassDescriptorSP
- GetNonKVOClassDescriptor (ValueObject& in_value);
-
- virtual ClassDescriptorSP
- GetClassDescriptorFromClassName (const ConstString &class_name);
-
- virtual ClassDescriptorSP
- GetClassDescriptorFromISA (ObjCISA isa);
-
- ClassDescriptorSP
- GetNonKVOClassDescriptor (ObjCISA isa);
-
- lldb::LanguageType
- GetLanguageType () const override
- {
- return lldb::eLanguageTypeObjC;
- }
-
- virtual bool
- IsModuleObjCLibrary (const lldb::ModuleSP &module_sp) = 0;
-
- virtual bool
- ReadObjCLibrary (const lldb::ModuleSP &module_sp) = 0;
-
- virtual bool
- HasReadObjCLibrary () = 0;
-
- virtual lldb::ThreadPlanSP
- GetStepThroughTrampolinePlan (Thread &thread, bool stop_others) = 0;
-
- lldb::addr_t
- LookupInMethodCache (lldb::addr_t class_addr, lldb::addr_t sel);
-
- void
- AddToMethodCache (lldb::addr_t class_addr, lldb::addr_t sel, lldb::addr_t impl_addr);
-
- TypeAndOrName
- LookupInClassNameCache (lldb::addr_t class_addr);
-
- void
- AddToClassNameCache (lldb::addr_t class_addr, const char *name, lldb::TypeSP type_sp);
-
- void
- AddToClassNameCache (lldb::addr_t class_addr, const TypeAndOrName &class_or_type_name);
-
- lldb::TypeSP
- LookupInCompleteClassCache (ConstString &name);
-
- virtual UtilityFunction *
- CreateObjectChecker (const char *) = 0;
-
- virtual ObjCRuntimeVersions
- GetRuntimeVersion () const
- {
- return ObjCRuntimeVersions::eObjC_VersionUnknown;
- }
-
- bool
- IsValidISA(ObjCISA isa)
- {
- UpdateISAToDescriptorMap();
- return m_isa_to_descriptor.count(isa) > 0;
+ virtual size_t GetNumIVars() { return 0; }
+
+ virtual iVarDescriptor GetIVarAtIndex(size_t idx) {
+ return iVarDescriptor();
}
- virtual void
- UpdateISAToDescriptorMapIfNeeded() = 0;
+ protected:
+ bool IsPointerValid(lldb::addr_t value, uint32_t ptr_size,
+ bool allow_NULLs = false, bool allow_tagged = false,
+ bool check_version_specific = false) const;
- void
- UpdateISAToDescriptorMap()
- {
- if (m_process && m_process->GetStopID() != m_isa_to_descriptor_stop_id)
- {
- UpdateISAToDescriptorMapIfNeeded ();
- }
- }
-
- virtual ObjCISA
- GetISA(const ConstString &name);
-
- virtual ConstString
- GetActualTypeName(ObjCISA isa);
-
- virtual ObjCISA
- GetParentClass(ObjCISA isa);
-
- virtual DeclVendor *
- GetDeclVendor()
- {
- return nullptr;
- }
-
- // Finds the byte offset of the child_type ivar in parent_type. If it can't find the
- // offset, returns LLDB_INVALID_IVAR_OFFSET.
-
- virtual size_t
- GetByteOffsetForIvar (CompilerType &parent_qual_type, const char *ivar_name);
-
- // Given the name of an Objective-C runtime symbol (e.g., ivar offset symbol),
- // try to determine from the runtime what the value of that symbol would be.
- // Useful when the underlying binary is stripped.
- virtual lldb::addr_t
- LookupRuntimeSymbol (const ConstString &name)
- {
- return LLDB_INVALID_ADDRESS;
- }
-
- bool
- HasNewLiteralsAndIndexing ()
- {
- if (m_has_new_literals_and_indexing == eLazyBoolCalculate)
- {
- if (CalculateHasNewLiteralsAndIndexing())
- m_has_new_literals_and_indexing = eLazyBoolYes;
- else
- m_has_new_literals_and_indexing = eLazyBoolNo;
- }
-
- return (m_has_new_literals_and_indexing == eLazyBoolYes);
+ private:
+ LazyBool m_is_kvo;
+ LazyBool m_is_cf;
+ lldb::TypeWP m_type_wp;
+ };
+
+ class EncodingToType {
+ public:
+ virtual ~EncodingToType();
+
+ virtual CompilerType RealizeType(ClangASTContext &ast_ctx, const char *name,
+ bool for_expression);
+ virtual CompilerType RealizeType(const char *name, bool for_expression);
+
+ virtual CompilerType RealizeType(clang::ASTContext &ast_ctx,
+ const char *name, bool for_expression) = 0;
+
+ protected:
+ std::unique_ptr<ClangASTContext> m_scratch_ast_ctx_ap;
+ };
+
+ class ObjCExceptionPrecondition : public Breakpoint::BreakpointPrecondition {
+ public:
+ ObjCExceptionPrecondition();
+
+ ~ObjCExceptionPrecondition() override = default;
+
+ bool EvaluatePrecondition(StoppointCallbackContext &context) override;
+ void GetDescription(Stream &stream, lldb::DescriptionLevel level) override;
+ Error ConfigurePrecondition(Args &args) override;
+
+ protected:
+ void AddClassName(const char *class_name);
+
+ private:
+ std::unordered_set<std::string> m_class_names;
+ };
+
+ class TaggedPointerVendor {
+ public:
+ virtual ~TaggedPointerVendor() = default;
+
+ virtual bool IsPossibleTaggedPointer(lldb::addr_t ptr) = 0;
+
+ virtual ObjCLanguageRuntime::ClassDescriptorSP
+ GetClassDescriptor(lldb::addr_t ptr) = 0;
+
+ protected:
+ TaggedPointerVendor() = default;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendor);
+ };
+
+ ~ObjCLanguageRuntime() override;
+
+ virtual TaggedPointerVendor *GetTaggedPointerVendor() { return nullptr; }
+
+ typedef std::shared_ptr<EncodingToType> EncodingToTypeSP;
+
+ virtual EncodingToTypeSP GetEncodingToType();
+
+ virtual ClassDescriptorSP GetClassDescriptor(ValueObject &in_value);
+
+ ClassDescriptorSP GetNonKVOClassDescriptor(ValueObject &in_value);
+
+ virtual ClassDescriptorSP
+ GetClassDescriptorFromClassName(const ConstString &class_name);
+
+ virtual ClassDescriptorSP GetClassDescriptorFromISA(ObjCISA isa);
+
+ ClassDescriptorSP GetNonKVOClassDescriptor(ObjCISA isa);
+
+ lldb::LanguageType GetLanguageType() const override {
+ return lldb::eLanguageTypeObjC;
+ }
+
+ virtual bool IsModuleObjCLibrary(const lldb::ModuleSP &module_sp) = 0;
+
+ virtual bool ReadObjCLibrary(const lldb::ModuleSP &module_sp) = 0;
+
+ virtual bool HasReadObjCLibrary() = 0;
+
+ virtual lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread,
+ bool stop_others) = 0;
+
+ lldb::addr_t LookupInMethodCache(lldb::addr_t class_addr, lldb::addr_t sel);
+
+ void AddToMethodCache(lldb::addr_t class_addr, lldb::addr_t sel,
+ lldb::addr_t impl_addr);
+
+ TypeAndOrName LookupInClassNameCache(lldb::addr_t class_addr);
+
+ void AddToClassNameCache(lldb::addr_t class_addr, const char *name,
+ lldb::TypeSP type_sp);
+
+ void AddToClassNameCache(lldb::addr_t class_addr,
+ const TypeAndOrName &class_or_type_name);
+
+ lldb::TypeSP LookupInCompleteClassCache(ConstString &name);
+
+ virtual UtilityFunction *CreateObjectChecker(const char *) = 0;
+
+ virtual ObjCRuntimeVersions GetRuntimeVersion() const {
+ return ObjCRuntimeVersions::eObjC_VersionUnknown;
+ }
+
+ bool IsValidISA(ObjCISA isa) {
+ UpdateISAToDescriptorMap();
+ return m_isa_to_descriptor.count(isa) > 0;
+ }
+
+ virtual void UpdateISAToDescriptorMapIfNeeded() = 0;
+
+ void UpdateISAToDescriptorMap() {
+ if (m_process && m_process->GetStopID() != m_isa_to_descriptor_stop_id) {
+ UpdateISAToDescriptorMapIfNeeded();
}
-
- virtual void
- SymbolsDidLoad (const ModuleList& module_list)
- {
- m_negative_complete_class_cache.clear();
+ }
+
+ virtual ObjCISA GetISA(const ConstString &name);
+
+ virtual ConstString GetActualTypeName(ObjCISA isa);
+
+ virtual ObjCISA GetParentClass(ObjCISA isa);
+
+ virtual DeclVendor *GetDeclVendor() { return nullptr; }
+
+ // Finds the byte offset of the child_type ivar in parent_type. If it can't
+ // find the
+ // offset, returns LLDB_INVALID_IVAR_OFFSET.
+
+ virtual size_t GetByteOffsetForIvar(CompilerType &parent_qual_type,
+ const char *ivar_name);
+
+ // Given the name of an Objective-C runtime symbol (e.g., ivar offset symbol),
+ // try to determine from the runtime what the value of that symbol would be.
+ // Useful when the underlying binary is stripped.
+ virtual lldb::addr_t LookupRuntimeSymbol(const ConstString &name) {
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ bool HasNewLiteralsAndIndexing() {
+ if (m_has_new_literals_and_indexing == eLazyBoolCalculate) {
+ if (CalculateHasNewLiteralsAndIndexing())
+ m_has_new_literals_and_indexing = eLazyBoolYes;
+ else
+ m_has_new_literals_and_indexing = eLazyBoolNo;
}
-
- bool
- GetTypeBitSize (const CompilerType& compiler_type,
- uint64_t &size) override;
+
+ return (m_has_new_literals_and_indexing == eLazyBoolYes);
+ }
+
+ virtual void SymbolsDidLoad(const ModuleList &module_list) {
+ m_negative_complete_class_cache.clear();
+ }
+
+ bool GetTypeBitSize(const CompilerType &compiler_type,
+ uint64_t &size) override;
protected:
- //------------------------------------------------------------------
- // Classes that inherit from ObjCLanguageRuntime can see and modify these
- //------------------------------------------------------------------
- ObjCLanguageRuntime(Process *process);
+ //------------------------------------------------------------------
+ // Classes that inherit from ObjCLanguageRuntime can see and modify these
+ //------------------------------------------------------------------
+ ObjCLanguageRuntime(Process *process);
- virtual bool CalculateHasNewLiteralsAndIndexing()
- {
- return false;
+ virtual bool CalculateHasNewLiteralsAndIndexing() { return false; }
+
+ bool ISAIsCached(ObjCISA isa) const {
+ return m_isa_to_descriptor.find(isa) != m_isa_to_descriptor.end();
+ }
+
+ bool AddClass(ObjCISA isa, const ClassDescriptorSP &descriptor_sp) {
+ if (isa != 0) {
+ m_isa_to_descriptor[isa] = descriptor_sp;
+ return true;
}
-
- bool
- ISAIsCached (ObjCISA isa) const
- {
- return m_isa_to_descriptor.find(isa) != m_isa_to_descriptor.end();
+ return false;
+ }
+
+ bool AddClass(ObjCISA isa, const ClassDescriptorSP &descriptor_sp,
+ const char *class_name);
+
+ bool AddClass(ObjCISA isa, const ClassDescriptorSP &descriptor_sp,
+ uint32_t class_name_hash) {
+ if (isa != 0) {
+ m_isa_to_descriptor[isa] = descriptor_sp;
+ m_hash_to_isa_map.insert(std::make_pair(class_name_hash, isa));
+ return true;
}
+ return false;
+ }
- bool
- AddClass (ObjCISA isa, const ClassDescriptorSP &descriptor_sp)
- {
- if (isa != 0)
- {
- m_isa_to_descriptor[isa] = descriptor_sp;
- return true;
- }
- return false;
+private:
+ // We keep a map of <Class,Selector>->Implementation so we don't have to call
+ // the resolver
+ // function over and over.
+
+ // FIXME: We need to watch for the loading of Protocols, and flush the cache
+ // for any
+ // class that we see so changed.
+
+ struct ClassAndSel {
+ ClassAndSel() {
+ sel_addr = LLDB_INVALID_ADDRESS;
+ class_addr = LLDB_INVALID_ADDRESS;
}
- bool
- AddClass (ObjCISA isa, const ClassDescriptorSP &descriptor_sp, const char *class_name);
+ ClassAndSel(lldb::addr_t in_sel_addr, lldb::addr_t in_class_addr)
+ : class_addr(in_class_addr), sel_addr(in_sel_addr) {}
- bool
- AddClass (ObjCISA isa, const ClassDescriptorSP &descriptor_sp, uint32_t class_name_hash)
- {
- if (isa != 0)
- {
- m_isa_to_descriptor[isa] = descriptor_sp;
- m_hash_to_isa_map.insert(std::make_pair(class_name_hash, isa));
- return true;
- }
+ bool operator==(const ClassAndSel &rhs) {
+ if (class_addr == rhs.class_addr && sel_addr == rhs.sel_addr)
+ return true;
+ else
return false;
}
-private:
- // We keep a map of <Class,Selector>->Implementation so we don't have to call the resolver
- // function over and over.
-
- // FIXME: We need to watch for the loading of Protocols, and flush the cache for any
- // class that we see so changed.
-
- struct ClassAndSel
- {
- ClassAndSel()
- {
- sel_addr = LLDB_INVALID_ADDRESS;
- class_addr = LLDB_INVALID_ADDRESS;
- }
-
- ClassAndSel (lldb::addr_t in_sel_addr, lldb::addr_t in_class_addr) :
- class_addr (in_class_addr),
- sel_addr(in_sel_addr)
- {
- }
-
- bool operator== (const ClassAndSel &rhs)
- {
- if (class_addr == rhs.class_addr
- && sel_addr == rhs.sel_addr)
- return true;
- else
- return false;
- }
-
- bool operator< (const ClassAndSel &rhs) const
- {
- if (class_addr < rhs.class_addr)
- return true;
- else if (class_addr > rhs.class_addr)
- return false;
- else
- {
- if (sel_addr < rhs.sel_addr)
- return true;
- else
- return false;
- }
- }
-
- lldb::addr_t class_addr;
- lldb::addr_t sel_addr;
- };
+ bool operator<(const ClassAndSel &rhs) const {
+ if (class_addr < rhs.class_addr)
+ return true;
+ else if (class_addr > rhs.class_addr)
+ return false;
+ else {
+ if (sel_addr < rhs.sel_addr)
+ return true;
+ else
+ return false;
+ }
+ }
+
+ lldb::addr_t class_addr;
+ lldb::addr_t sel_addr;
+ };
- typedef std::map<ClassAndSel,lldb::addr_t> MsgImplMap;
- typedef std::map<ObjCISA, ClassDescriptorSP> ISAToDescriptorMap;
- typedef std::multimap<uint32_t, ObjCISA> HashToISAMap;
- typedef ISAToDescriptorMap::iterator ISAToDescriptorIterator;
- typedef HashToISAMap::iterator HashToISAIterator;
- typedef ThreadSafeDenseMap<void*, uint64_t> TypeSizeCache;
+ typedef std::map<ClassAndSel, lldb::addr_t> MsgImplMap;
+ typedef std::map<ObjCISA, ClassDescriptorSP> ISAToDescriptorMap;
+ typedef std::multimap<uint32_t, ObjCISA> HashToISAMap;
+ typedef ISAToDescriptorMap::iterator ISAToDescriptorIterator;
+ typedef HashToISAMap::iterator HashToISAIterator;
+ typedef ThreadSafeDenseMap<void *, uint64_t> TypeSizeCache;
- MsgImplMap m_impl_cache;
- LazyBool m_has_new_literals_and_indexing;
- ISAToDescriptorMap m_isa_to_descriptor;
- HashToISAMap m_hash_to_isa_map;
- TypeSizeCache m_type_size_cache;
+ MsgImplMap m_impl_cache;
+ LazyBool m_has_new_literals_and_indexing;
+ ISAToDescriptorMap m_isa_to_descriptor;
+ HashToISAMap m_hash_to_isa_map;
+ TypeSizeCache m_type_size_cache;
protected:
- uint32_t m_isa_to_descriptor_stop_id;
-
- typedef std::map<ConstString, lldb::TypeWP> CompleteClassMap;
- CompleteClassMap m_complete_class_cache;
-
- struct ConstStringSetHelpers {
- size_t operator () (const ConstString& arg) const // for hashing
- {
- return (size_t)arg.GetCString();
- }
- bool operator () (const ConstString& arg1, const ConstString& arg2) const // for equality
- {
- return arg1.operator==(arg2);
- }
- };
- typedef std::unordered_set<ConstString, ConstStringSetHelpers, ConstStringSetHelpers> CompleteClassSet;
- CompleteClassSet m_negative_complete_class_cache;
+ uint32_t m_isa_to_descriptor_stop_id;
+
+ typedef std::map<ConstString, lldb::TypeWP> CompleteClassMap;
+ CompleteClassMap m_complete_class_cache;
+
+ struct ConstStringSetHelpers {
+ size_t operator()(const ConstString &arg) const // for hashing
+ {
+ return (size_t)arg.GetCString();
+ }
+ bool operator()(const ConstString &arg1,
+ const ConstString &arg2) const // for equality
+ {
+ return arg1.operator==(arg2);
+ }
+ };
+ typedef std::unordered_set<ConstString, ConstStringSetHelpers,
+ ConstStringSetHelpers>
+ CompleteClassSet;
+ CompleteClassSet m_negative_complete_class_cache;
+
+ ISAToDescriptorIterator GetDescriptorIterator(const ConstString &name);
- ISAToDescriptorIterator
- GetDescriptorIterator (const ConstString &name);
+ friend class ::CommandObjectObjC_ClassTable_Dump;
- friend class ::CommandObjectObjC_ClassTable_Dump;
-
- std::pair<ISAToDescriptorIterator,ISAToDescriptorIterator>
- GetDescriptorIteratorPair (bool update_if_needed = true);
+ std::pair<ISAToDescriptorIterator, ISAToDescriptorIterator>
+ GetDescriptorIteratorPair(bool update_if_needed = true);
- void
- ReadObjCLibraryIfNeeded (const ModuleList &module_list);
+ void ReadObjCLibraryIfNeeded(const ModuleList &module_list);
- DISALLOW_COPY_AND_ASSIGN (ObjCLanguageRuntime);
+ DISALLOW_COPY_AND_ASSIGN(ObjCLanguageRuntime);
};
} // namespace lldb_private
diff --git a/include/lldb/Target/OperatingSystem.h b/include/lldb/Target/OperatingSystem.h
index 74de5645da5a..24ded3f69723 100644
--- a/include/lldb/Target/OperatingSystem.h
+++ b/include/lldb/Target/OperatingSystem.h
@@ -1,4 +1,5 @@
-//===-- OperatingSystem.h ----------------------------------------------*- C++ -*-===//
+//===-- OperatingSystem.h ----------------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,84 +15,77 @@
// C++ Includes
// Other libraries and framework includes
-#include "lldb/lldb-private.h"
#include "lldb/Core/PluginInterface.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
-
+
//----------------------------------------------------------------------
/// @class OperatingSystem OperatingSystem.h "lldb/Target/OperatingSystem.h"
/// @brief A plug-in interface definition class for halted OS helpers.
///
-/// Halted OS plug-ins can be used by any process to locate and create
-/// OS objects, like threads, during the lifetime of a debug session.
+/// Halted OS plug-ins can be used by any process to locate and create
+/// OS objects, like threads, during the lifetime of a debug session.
/// This is commonly used when attaching to an operating system that is
/// halted, such as when debugging over JTAG or connecting to low level
/// kernel debug services.
//----------------------------------------------------------------------
-class OperatingSystem :
- public PluginInterface
-{
+class OperatingSystem : public PluginInterface {
public:
- //------------------------------------------------------------------
- /// Find a halted OS plugin for a given process.
- ///
- /// Scans the installed OperatingSystem plug-ins and tries to find
- /// an instance that matches the current target triple and
- /// executable.
- ///
- /// @param[in] process
- /// The process for which to try and locate a halted OS
- /// plug-in instance.
- ///
- /// @param[in] plugin_name
- /// An optional name of a specific halted OS plug-in that
- /// should be used. If NULL, pick the best plug-in.
- //------------------------------------------------------------------
- static OperatingSystem*
- FindPlugin (Process *process, const char *plugin_name);
-
- //------------------------------------------------------------------
- // Class Methods
- //------------------------------------------------------------------
- OperatingSystem (Process *process);
-
- ~OperatingSystem() override;
-
- //------------------------------------------------------------------
- // Plug-in Methods
- //------------------------------------------------------------------
- virtual bool
- UpdateThreadList (ThreadList &old_thread_list,
- ThreadList &real_thread_list,
- ThreadList &new_thread_list) = 0;
-
- virtual void
- ThreadWasSelected (Thread *thread) = 0;
-
- virtual lldb::RegisterContextSP
- CreateRegisterContextForThread (Thread *thread, lldb::addr_t reg_data_addr) = 0;
-
- virtual lldb::StopInfoSP
- CreateThreadStopReason (Thread *thread) = 0;
-
- virtual lldb::ThreadSP
- CreateThread (lldb::tid_t tid, lldb::addr_t context)
- {
- return lldb::ThreadSP();
- }
-
- virtual bool
- IsOperatingSystemPluginThread (const lldb::ThreadSP &thread_sp);
+ //------------------------------------------------------------------
+ /// Find a halted OS plugin for a given process.
+ ///
+ /// Scans the installed OperatingSystem plug-ins and tries to find
+ /// an instance that matches the current target triple and
+ /// executable.
+ ///
+ /// @param[in] process
+ /// The process for which to try and locate a halted OS
+ /// plug-in instance.
+ ///
+ /// @param[in] plugin_name
+ /// An optional name of a specific halted OS plug-in that
+ /// should be used. If NULL, pick the best plug-in.
+ //------------------------------------------------------------------
+ static OperatingSystem *FindPlugin(Process *process, const char *plugin_name);
+
+ //------------------------------------------------------------------
+ // Class Methods
+ //------------------------------------------------------------------
+ OperatingSystem(Process *process);
+
+ ~OperatingSystem() override;
+
+ //------------------------------------------------------------------
+ // Plug-in Methods
+ //------------------------------------------------------------------
+ virtual bool UpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &real_thread_list,
+ ThreadList &new_thread_list) = 0;
+
+ virtual void ThreadWasSelected(Thread *thread) = 0;
+
+ virtual lldb::RegisterContextSP
+ CreateRegisterContextForThread(Thread *thread,
+ lldb::addr_t reg_data_addr) = 0;
+
+ virtual lldb::StopInfoSP CreateThreadStopReason(Thread *thread) = 0;
+
+ virtual lldb::ThreadSP CreateThread(lldb::tid_t tid, lldb::addr_t context) {
+ return lldb::ThreadSP();
+ }
+
+ virtual bool IsOperatingSystemPluginThread(const lldb::ThreadSP &thread_sp);
protected:
- //------------------------------------------------------------------
- // Member variables.
- //------------------------------------------------------------------
- Process* m_process; ///< The process that this dynamic loader plug-in is tracking.
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ Process
+ *m_process; ///< The process that this dynamic loader plug-in is tracking.
private:
- DISALLOW_COPY_AND_ASSIGN (OperatingSystem);
+ DISALLOW_COPY_AND_ASSIGN(OperatingSystem);
};
} // namespace lldb_private
diff --git a/include/lldb/Target/PathMappingList.h b/include/lldb/Target/PathMappingList.h
index 1a486c4642dc..4e5a5693235a 100644
--- a/include/lldb/Target/PathMappingList.h
+++ b/include/lldb/Target/PathMappingList.h
@@ -21,153 +21,119 @@
namespace lldb_private {
-class PathMappingList
-{
+class PathMappingList {
public:
+ typedef void (*ChangedCallback)(const PathMappingList &path_list,
+ void *baton);
+
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ PathMappingList();
+
+ PathMappingList(ChangedCallback callback, void *callback_baton);
+
+ PathMappingList(const PathMappingList &rhs);
+
+ ~PathMappingList();
+
+ const PathMappingList &operator=(const PathMappingList &rhs);
+
+ void Append(const ConstString &path, const ConstString &replacement,
+ bool notify);
+
+ void Append(const PathMappingList &rhs, bool notify);
+
+ void Clear(bool notify);
+
+ // By default, dump all pairs.
+ void Dump(Stream *s, int pair_index = -1);
+
+ bool IsEmpty() const { return m_pairs.empty(); }
+
+ size_t GetSize() const { return m_pairs.size(); }
+
+ bool GetPathsAtIndex(uint32_t idx, ConstString &path,
+ ConstString &new_path) const;
+
+ void Insert(const ConstString &path, const ConstString &replacement,
+ uint32_t insert_idx, bool notify);
+
+ bool Remove(size_t index, bool notify);
+
+ bool Remove(const ConstString &path, bool notify);
+
+ bool Replace(const ConstString &path, const ConstString &replacement,
+ bool notify);
+
+ bool Replace(const ConstString &path, const ConstString &replacement,
+ uint32_t index, bool notify);
+ bool RemapPath(const ConstString &path, ConstString &new_path) const;
+
+ //------------------------------------------------------------------
+ /// Remaps a source file given \a path into \a new_path.
+ ///
+ /// Remaps \a path if any source remappings match. This function
+ /// does NOT stat the file system so it can be used in tight loops
+ /// where debug info is being parsed.
+ ///
+ /// @param[in] path
+ /// The original source file path to try and remap.
+ ///
+ /// @param[out] new_path
+ /// The newly remapped filespec that is may or may not exist.
+ ///
+ /// @return
+ /// /b true if \a path was successfully located and \a new_path
+ /// is filled in with a new source path, \b false otherwise.
+ //------------------------------------------------------------------
+ bool RemapPath(llvm::StringRef path, std::string &new_path) const;
+ bool RemapPath(const char *, std::string &) const = delete;
+
+ bool ReverseRemapPath(const ConstString &path, ConstString &new_path) const;
+
+ //------------------------------------------------------------------
+ /// Finds a source file given a file spec using the path remappings.
+ ///
+ /// Tries to resolve \a orig_spec by checking the path remappings.
+ /// It makes sure the file exists by checking with the file system,
+ /// so this call can be expensive if the remappings are on a network
+ /// or are even on the local file system, so use this function
+ /// sparingly (not in a tight debug info parsing loop).
+ ///
+ /// @param[in] orig_spec
+ /// The original source file path to try and remap.
+ ///
+ /// @param[out] new_spec
+ /// The newly remapped filespec that is guaranteed to exist.
+ ///
+ /// @return
+ /// /b true if \a orig_spec was successfully located and
+ /// \a new_spec is filled in with an existing file spec,
+ /// \b false otherwise.
+ //------------------------------------------------------------------
+ bool FindFile(const FileSpec &orig_spec, FileSpec &new_spec) const;
+
+ uint32_t FindIndexForPath(const ConstString &path) const;
+
+ uint32_t GetModificationID() const { return m_mod_id; }
- typedef void (*ChangedCallback) (const PathMappingList &path_list,
- void *baton);
-
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- PathMappingList ();
-
- PathMappingList (ChangedCallback callback,
- void *callback_baton);
-
- PathMappingList (const PathMappingList &rhs);
-
- ~PathMappingList ();
-
- const PathMappingList &
- operator =(const PathMappingList &rhs);
-
- void
- Append (const ConstString &path, const ConstString &replacement, bool notify);
-
- void
- Append (const PathMappingList &rhs, bool notify);
-
- void
- Clear (bool notify);
-
- // By default, dump all pairs.
- void
- Dump (Stream *s, int pair_index=-1);
-
- bool
- IsEmpty() const
- {
- return m_pairs.empty();
- }
-
- size_t
- GetSize () const
- {
- return m_pairs.size();
- }
-
- bool
- GetPathsAtIndex (uint32_t idx, ConstString &path, ConstString &new_path) const;
-
- void
- Insert (const ConstString &path,
- const ConstString &replacement,
- uint32_t insert_idx,
- bool notify);
-
- bool
- Remove (size_t index, bool notify);
-
- bool
- Remove (const ConstString &path, bool notify);
-
- bool
- Replace (const ConstString &path,
- const ConstString &replacement,
- bool notify);
-
- bool
- Replace (const ConstString &path,
- const ConstString &replacement,
- uint32_t index,
- bool notify);
- bool
- RemapPath (const ConstString &path, ConstString &new_path) const;
-
- //------------------------------------------------------------------
- /// Remaps a source file given \a path into \a new_path.
- ///
- /// Remaps \a path if any source remappings match. This function
- /// does NOT stat the file system so it can be used in tight loops
- /// where debug info is being parsed.
- ///
- /// @param[in] path
- /// The original source file path to try and remap.
- ///
- /// @param[out] new_path
- /// The newly remapped filespec that is may or may not exist.
- ///
- /// @return
- /// /b true if \a path was successfully located and \a new_path
- /// is filled in with a new source path, \b false otherwise.
- //------------------------------------------------------------------
- bool
- RemapPath (const char *path, std::string &new_path) const;
-
- bool
- ReverseRemapPath (const ConstString &path, ConstString &new_path) const;
-
- //------------------------------------------------------------------
- /// Finds a source file given a file spec using the path remappings.
- ///
- /// Tries to resolve \a orig_spec by checking the path remappings.
- /// It makes sure the file exists by checking with the file system,
- /// so this call can be expensive if the remappings are on a network
- /// or are even on the local file system, so use this function
- /// sparingly (not in a tight debug info parsing loop).
- ///
- /// @param[in] orig_spec
- /// The original source file path to try and remap.
- ///
- /// @param[out] new_spec
- /// The newly remapped filespec that is guaranteed to exist.
- ///
- /// @return
- /// /b true if \a orig_spec was successfully located and
- /// \a new_spec is filled in with an existing file spec,
- /// \b false otherwise.
- //------------------------------------------------------------------
- bool
- FindFile (const FileSpec &orig_spec, FileSpec &new_spec) const;
-
- uint32_t
- FindIndexForPath (const ConstString &path) const;
-
- uint32_t
- GetModificationID() const
- {
- return m_mod_id;
- }
protected:
- typedef std::pair <ConstString, ConstString> pair;
- typedef std::vector <pair> collection;
- typedef collection::iterator iterator;
- typedef collection::const_iterator const_iterator;
-
- iterator
- FindIteratorForPath (const ConstString &path);
-
- const_iterator
- FindIteratorForPath (const ConstString &path) const;
-
- collection m_pairs;
- ChangedCallback m_callback;
- void * m_callback_baton;
- uint32_t m_mod_id; // Incremented anytime anything is added or removed.
+ typedef std::pair<ConstString, ConstString> pair;
+ typedef std::vector<pair> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+
+ iterator FindIteratorForPath(const ConstString &path);
+
+ const_iterator FindIteratorForPath(const ConstString &path) const;
+
+ collection m_pairs;
+ ChangedCallback m_callback;
+ void *m_callback_baton;
+ uint32_t m_mod_id; // Incremented anytime anything is added or removed.
};
} // namespace lldb_private
-#endif // liblldb_PathMappingList_h_
+#endif // liblldb_PathMappingList_h_
diff --git a/include/lldb/Target/Platform.h b/include/lldb/Target/Platform.h
index 6fdd92db5680..9707093440a5 100644
--- a/include/lldb/Target/Platform.h
+++ b/include/lldb/Target/Platform.h
@@ -21,14 +21,14 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private-forward.h"
-#include "lldb/lldb-public.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Core/UserSettingsController.h"
-#include "lldb/Interpreter/Options.h"
#include "lldb/Host/FileSpec.h"
+#include "lldb/Interpreter/Options.h"
+#include "lldb/lldb-private-forward.h"
+#include "lldb/lldb-public.h"
// TODO pull NativeDelegate class out of NativeProcessProtocol so we
// can just forward ref the NativeDelegate rather than include it here.
@@ -37,1390 +37,1133 @@
namespace lldb_private {
class ModuleCache;
- enum MmapFlags {
- eMmapFlagsPrivate = 1,
- eMmapFlagsAnon = 2
- };
+enum MmapFlags { eMmapFlagsPrivate = 1, eMmapFlagsAnon = 2 };
+
+class PlatformProperties : public Properties {
+public:
+ PlatformProperties();
+
+ static ConstString GetSettingName();
+
+ bool GetUseModuleCache() const;
+ bool SetUseModuleCache(bool use_module_cache);
+
+ FileSpec GetModuleCacheDirectory() const;
+ bool SetModuleCacheDirectory(const FileSpec &dir_spec);
+};
+
+typedef std::shared_ptr<PlatformProperties> PlatformPropertiesSP;
+
+//----------------------------------------------------------------------
+/// @class Platform Platform.h "lldb/Target/Platform.h"
+/// @brief A plug-in interface definition class for debug platform that
+/// includes many platform abilities such as:
+/// @li getting platform information such as supported architectures,
+/// supported binary file formats and more
+/// @li launching new processes
+/// @li attaching to existing processes
+/// @li download/upload files
+/// @li execute shell commands
+/// @li listing and getting info for existing processes
+/// @li attaching and possibly debugging the platform's kernel
+//----------------------------------------------------------------------
+class Platform : public PluginInterface {
+public:
+ //------------------------------------------------------------------
+ /// Default Constructor
+ //------------------------------------------------------------------
+ Platform(bool is_host_platform);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ ///
+ /// The destructor is virtual since this class is designed to be
+ /// inherited from by the plug-in instance.
+ //------------------------------------------------------------------
+ ~Platform() override;
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static const PlatformPropertiesSP &GetGlobalPlatformProperties();
+
+ //------------------------------------------------------------------
+ /// Get the native host platform plug-in.
+ ///
+ /// There should only be one of these for each host that LLDB runs
+ /// upon that should be statically compiled in and registered using
+ /// preprocessor macros or other similar build mechanisms in a
+ /// PlatformSubclass::Initialize() function.
+ ///
+ /// This platform will be used as the default platform when launching
+ /// or attaching to processes unless another platform is specified.
+ //------------------------------------------------------------------
+ static lldb::PlatformSP GetHostPlatform();
+
+ static lldb::PlatformSP
+ GetPlatformForArchitecture(const ArchSpec &arch, ArchSpec *platform_arch_ptr);
+
+ static const char *GetHostPlatformName();
+
+ static void SetHostPlatform(const lldb::PlatformSP &platform_sp);
+
+ // Find an existing platform plug-in by name
+ static lldb::PlatformSP Find(const ConstString &name);
+
+ static lldb::PlatformSP Create(const ConstString &name, Error &error);
+
+ static lldb::PlatformSP Create(const ArchSpec &arch,
+ ArchSpec *platform_arch_ptr, Error &error);
+
+ static uint32_t GetNumConnectedRemotePlatforms();
+
+ static lldb::PlatformSP GetConnectedRemotePlatformAtIndex(uint32_t idx);
+
+ //------------------------------------------------------------------
+ /// Find a platform plugin for a given process.
+ ///
+ /// Scans the installed Platform plug-ins and tries to find
+ /// an instance that can be used for \a process
+ ///
+ /// @param[in] process
+ /// The process for which to try and locate a platform
+ /// plug-in instance.
+ ///
+ /// @param[in] plugin_name
+ /// An optional name of a specific platform plug-in that
+ /// should be used. If nullptr, pick the best plug-in.
+ //------------------------------------------------------------------
+ // static lldb::PlatformSP
+ // FindPlugin (Process *process, const ConstString &plugin_name);
+
+ //------------------------------------------------------------------
+ /// Set the target's executable based off of the existing
+ /// architecture information in \a target given a path to an
+ /// executable \a exe_file.
+ ///
+ /// Each platform knows the architectures that it supports and can
+ /// select the correct architecture slice within \a exe_file by
+ /// inspecting the architecture in \a target. If the target had an
+ /// architecture specified, then in can try and obey that request
+ /// and optionally fail if the architecture doesn't match up.
+ /// If no architecture is specified, the platform should select the
+ /// default architecture from \a exe_file. Any application bundles
+ /// or executable wrappers can also be inspected for the actual
+ /// application binary within the bundle that should be used.
+ ///
+ /// @return
+ /// Returns \b true if this Platform plug-in was able to find
+ /// a suitable executable, \b false otherwise.
+ //------------------------------------------------------------------
+ virtual Error ResolveExecutable(const ModuleSpec &module_spec,
+ lldb::ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr);
+
+ //------------------------------------------------------------------
+ /// Find a symbol file given a symbol file module specification.
+ ///
+ /// Each platform might have tricks to find symbol files for an
+ /// executable given information in a symbol file ModuleSpec. Some
+ /// platforms might also support symbol files that are bundles and
+ /// know how to extract the right symbol file given a bundle.
+ ///
+ /// @param[in] target
+ /// The target in which we are trying to resolve the symbol file.
+ /// The target has a list of modules that we might be able to
+ /// use in order to help find the right symbol file. If the
+ /// "m_file" or "m_platform_file" entries in the \a sym_spec
+ /// are filled in, then we might be able to locate a module in
+ /// the target, extract its UUID and locate a symbol file.
+ /// If just the "m_uuid" is specified, then we might be able
+ /// to find the module in the target that matches that UUID
+ /// and pair the symbol file along with it. If just "m_symbol_file"
+ /// is specified, we can use a variety of tricks to locate the
+ /// symbols in an SDK, PDK, or other development kit location.
+ ///
+ /// @param[in] sym_spec
+ /// A module spec that describes some information about the
+ /// symbol file we are trying to resolve. The ModuleSpec might
+ /// contain the following:
+ /// m_file - A full or partial path to an executable from the
+ /// target (might be empty).
+ /// m_platform_file - Another executable hint that contains
+ /// the path to the file as known on the
+ /// local/remote platform.
+ /// m_symbol_file - A full or partial path to a symbol file
+ /// or symbol bundle that should be used when
+ /// trying to resolve the symbol file.
+ /// m_arch - The architecture we are looking for when resolving
+ /// the symbol file.
+ /// m_uuid - The UUID of the executable and symbol file. This
+ /// can often be used to match up an executable with
+ /// a symbol file, or resolve an symbol file in a
+ /// symbol file bundle.
+ ///
+ /// @param[out] sym_file
+ /// The resolved symbol file spec if the returned error
+ /// indicates success.
+ ///
+ /// @return
+ /// Returns an error that describes success or failure.
+ //------------------------------------------------------------------
+ virtual Error ResolveSymbolFile(Target &target, const ModuleSpec &sym_spec,
+ FileSpec &sym_file);
+
+ //------------------------------------------------------------------
+ /// Resolves the FileSpec to a (possibly) remote path. Remote
+ /// platforms must override this to resolve to a path on the remote
+ /// side.
+ //------------------------------------------------------------------
+ virtual bool ResolveRemotePath(const FileSpec &platform_path,
+ FileSpec &resolved_platform_path);
+
+ //------------------------------------------------------------------
+ /// Get the OS version from a connected platform.
+ ///
+ /// Some platforms might not be connected to a remote platform, but
+ /// can figure out the OS version for a process. This is common for
+ /// simulator platforms that will run native programs on the current
+ /// host, but the simulator might be simulating a different OS. The
+ /// \a process parameter might be specified to help to determine
+ /// the OS version.
+ //------------------------------------------------------------------
+ virtual bool GetOSVersion(uint32_t &major, uint32_t &minor, uint32_t &update,
+ Process *process = nullptr);
+
+ bool SetOSVersion(uint32_t major, uint32_t minor, uint32_t update);
+
+ bool GetOSBuildString(std::string &s);
+
+ bool GetOSKernelDescription(std::string &s);
+
+ // Returns the name of the platform
+ ConstString GetName();
+
+ virtual const char *GetHostname();
+
+ virtual ConstString GetFullNameForDylib(ConstString basename);
+
+ virtual const char *GetDescription() = 0;
+
+ //------------------------------------------------------------------
+ /// Report the current status for this platform.
+ ///
+ /// The returned string usually involves returning the OS version
+ /// (if available), and any SDK directory that might be being used
+ /// for local file caching, and if connected a quick blurb about
+ /// what this platform is connected to.
+ //------------------------------------------------------------------
+ virtual void GetStatus(Stream &strm);
+
+ //------------------------------------------------------------------
+ // Subclasses must be able to fetch the current OS version
+ //
+ // Remote classes must be connected for this to succeed. Local
+ // subclasses don't need to override this function as it will just
+ // call the HostInfo::GetOSVersion().
+ //------------------------------------------------------------------
+ virtual bool GetRemoteOSVersion() { return false; }
+
+ virtual bool GetRemoteOSBuildString(std::string &s) {
+ s.clear();
+ return false;
+ }
+
+ virtual bool GetRemoteOSKernelDescription(std::string &s) {
+ s.clear();
+ return false;
+ }
+
+ // Remote Platform subclasses need to override this function
+ virtual ArchSpec GetRemoteSystemArchitecture() {
+ return ArchSpec(); // Return an invalid architecture
+ }
+
+ virtual FileSpec GetRemoteWorkingDirectory() { return m_working_dir; }
+
+ virtual bool SetRemoteWorkingDirectory(const FileSpec &working_dir);
+
+ virtual const char *GetUserName(uint32_t uid);
+
+ virtual const char *GetGroupName(uint32_t gid);
+
+ //------------------------------------------------------------------
+ /// Locate a file for a platform.
+ ///
+ /// The default implementation of this function will return the same
+ /// file patch in \a local_file as was in \a platform_file.
+ ///
+ /// @param[in] platform_file
+ /// The platform file path to locate and cache locally.
+ ///
+ /// @param[in] uuid_ptr
+ /// If we know the exact UUID of the file we are looking for, it
+ /// can be specified. If it is not specified, we might now know
+ /// the exact file. The UUID is usually some sort of MD5 checksum
+ /// for the file and is sometimes known by dynamic linkers/loaders.
+ /// If the UUID is known, it is best to supply it to platform
+ /// file queries to ensure we are finding the correct file, not
+ /// just a file at the correct path.
+ ///
+ /// @param[out] local_file
+ /// A locally cached version of the platform file. For platforms
+ /// that describe the current host computer, this will just be
+ /// the same file. For remote platforms, this file might come from
+ /// and SDK directory, or might need to be sync'ed over to the
+ /// current machine for efficient debugging access.
+ ///
+ /// @return
+ /// An error object.
+ //------------------------------------------------------------------
+ virtual Error GetFileWithUUID(const FileSpec &platform_file,
+ const UUID *uuid_ptr, FileSpec &local_file);
+
+ //----------------------------------------------------------------------
+ // Locate the scripting resource given a module specification.
+ //
+ // Locating the file should happen only on the local computer or using
+ // the current computers global settings.
+ //----------------------------------------------------------------------
+ virtual FileSpecList
+ LocateExecutableScriptingResources(Target *target, Module &module,
+ Stream *feedback_stream);
+
+ virtual Error GetSharedModule(const ModuleSpec &module_spec, Process *process,
+ lldb::ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr,
+ lldb::ModuleSP *old_module_sp_ptr,
+ bool *did_create_ptr);
+
+ virtual bool GetModuleSpec(const FileSpec &module_file_spec,
+ const ArchSpec &arch, ModuleSpec &module_spec);
+
+ virtual Error ConnectRemote(Args &args);
+
+ virtual Error DisconnectRemote();
+
+ //------------------------------------------------------------------
+ /// Get the platform's supported architectures in the order in which
+ /// they should be searched.
+ ///
+ /// @param[in] idx
+ /// A zero based architecture index
+ ///
+ /// @param[out] arch
+ /// A copy of the architecture at index if the return value is
+ /// \b true.
+ ///
+ /// @return
+ /// \b true if \a arch was filled in and is valid, \b false
+ /// otherwise.
+ //------------------------------------------------------------------
+ virtual bool GetSupportedArchitectureAtIndex(uint32_t idx,
+ ArchSpec &arch) = 0;
+
+ virtual size_t GetSoftwareBreakpointTrapOpcode(Target &target,
+ BreakpointSite *bp_site);
+
+ //------------------------------------------------------------------
+ /// Launch a new process on a platform, not necessarily for
+ /// debugging, it could be just for running the process.
+ //------------------------------------------------------------------
+ virtual Error LaunchProcess(ProcessLaunchInfo &launch_info);
+
+ //------------------------------------------------------------------
+ /// Perform expansion of the command-line for this launch info
+ /// This can potentially involve wildcard expansion
+ // environment variable replacement, and whatever other
+ // argument magic the platform defines as part of its typical
+ // user experience
+ //------------------------------------------------------------------
+ virtual Error ShellExpandArguments(ProcessLaunchInfo &launch_info);
+
+ //------------------------------------------------------------------
+ /// Kill process on a platform.
+ //------------------------------------------------------------------
+ virtual Error KillProcess(const lldb::pid_t pid);
+
+ //------------------------------------------------------------------
+ /// Lets a platform answer if it is compatible with a given
+ /// architecture and the target triple contained within.
+ //------------------------------------------------------------------
+ virtual bool IsCompatibleArchitecture(const ArchSpec &arch,
+ bool exact_arch_match,
+ ArchSpec *compatible_arch_ptr);
+
+ //------------------------------------------------------------------
+ /// Not all platforms will support debugging a process by spawning
+ /// somehow halted for a debugger (specified using the
+ /// "eLaunchFlagDebug" launch flag) and then attaching. If your
+ /// platform doesn't support this, override this function and return
+ /// false.
+ //------------------------------------------------------------------
+ virtual bool CanDebugProcess() { return true; }
+
+ //------------------------------------------------------------------
+ /// Subclasses do not need to implement this function as it uses
+ /// the Platform::LaunchProcess() followed by Platform::Attach ().
+ /// Remote platforms will want to subclass this function in order
+ /// to be able to intercept STDIO and possibly launch a separate
+ /// process that will debug the debuggee.
+ //------------------------------------------------------------------
+ virtual lldb::ProcessSP
+ DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
+ Target *target, // Can be nullptr, if nullptr create a new
+ // target, else use existing one
+ Error &error);
+
+ virtual lldb::ProcessSP ConnectProcess(llvm::StringRef connect_url,
+ llvm::StringRef plugin_name,
+ lldb_private::Debugger &debugger,
+ lldb_private::Target *target,
+ lldb_private::Error &error);
+
+ //------------------------------------------------------------------
+ /// Attach to an existing process using a process ID.
+ ///
+ /// Each platform subclass needs to implement this function and
+ /// attempt to attach to the process with the process ID of \a pid.
+ /// The platform subclass should return an appropriate ProcessSP
+ /// subclass that is attached to the process, or an empty shared
+ /// pointer with an appropriate error.
+ ///
+ /// @param[in] pid
+ /// The process ID that we should attempt to attach to.
+ ///
+ /// @return
+ /// An appropriate ProcessSP containing a valid shared pointer
+ /// to the default Process subclass for the platform that is
+ /// attached to the process, or an empty shared pointer with an
+ /// appropriate error fill into the \a error object.
+ //------------------------------------------------------------------
+ virtual lldb::ProcessSP Attach(ProcessAttachInfo &attach_info,
+ Debugger &debugger,
+ Target *target, // Can be nullptr, if nullptr
+ // create a new target, else
+ // use existing one
+ Error &error) = 0;
+
+ //------------------------------------------------------------------
+ /// Attach to an existing process by process name.
+ ///
+ /// This function is not meant to be overridden by Process
+ /// subclasses. It will first call
+ /// Process::WillAttach (const char *) and if that returns \b
+ /// true, Process::DoAttach (const char *) will be called to
+ /// actually do the attach. If DoAttach returns \b true, then
+ /// Process::DidAttach() will be called.
+ ///
+ /// @param[in] process_name
+ /// A process name to match against the current process list.
+ ///
+ /// @return
+ /// Returns \a pid if attaching was successful, or
+ /// LLDB_INVALID_PROCESS_ID if attaching fails.
+ //------------------------------------------------------------------
+ // virtual lldb::ProcessSP
+ // Attach (const char *process_name,
+ // bool wait_for_launch,
+ // Error &error) = 0;
+
+ //------------------------------------------------------------------
+ // The base class Platform will take care of the host platform.
+ // Subclasses will need to fill in the remote case.
+ //------------------------------------------------------------------
+ virtual uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info,
+ ProcessInstanceInfoList &proc_infos);
+
+ virtual bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info);
+
+ //------------------------------------------------------------------
+ // Set a breakpoint on all functions that can end up creating a thread
+ // for this platform. This is needed when running expressions and
+ // also for process control.
+ //------------------------------------------------------------------
+ virtual lldb::BreakpointSP SetThreadCreationBreakpoint(Target &target);
+
+ //------------------------------------------------------------------
+ // Given a target, find the local SDK directory if one exists on the
+ // current host.
+ //------------------------------------------------------------------
+ virtual lldb_private::ConstString
+ GetSDKDirectory(lldb_private::Target &target) {
+ return lldb_private::ConstString();
+ }
+
+ const std::string &GetRemoteURL() const { return m_remote_url; }
+
+ bool IsHost() const {
+ return m_is_host; // Is this the default host platform?
+ }
+
+ bool IsRemote() const { return !m_is_host; }
+
+ virtual bool IsConnected() const {
+ // Remote subclasses should override this function
+ return IsHost();
+ }
+
+ const ArchSpec &GetSystemArchitecture();
+
+ void SetSystemArchitecture(const ArchSpec &arch) {
+ m_system_arch = arch;
+ if (IsHost())
+ m_os_version_set_while_connected = m_system_arch.IsValid();
+ }
+
+ // Used for column widths
+ size_t GetMaxUserIDNameLength() const { return m_max_uid_name_len; }
+
+ // Used for column widths
+ size_t GetMaxGroupIDNameLength() const { return m_max_gid_name_len; }
+
+ const ConstString &GetSDKRootDirectory() const { return m_sdk_sysroot; }
+
+ void SetSDKRootDirectory(const ConstString &dir) { m_sdk_sysroot = dir; }
+
+ const ConstString &GetSDKBuild() const { return m_sdk_build; }
+
+ void SetSDKBuild(const ConstString &sdk_build) { m_sdk_build = sdk_build; }
+
+ // Override this to return true if your platform supports Clang modules.
+ // You may also need to override AddClangModuleCompilationOptions to pass the
+ // right Clang flags for your platform.
+ virtual bool SupportsModules() { return false; }
+
+ // Appends the platform-specific options required to find the modules for the
+ // current platform.
+ virtual void
+ AddClangModuleCompilationOptions(Target *target,
+ std::vector<std::string> &options);
+
+ FileSpec GetWorkingDirectory();
+
+ bool SetWorkingDirectory(const FileSpec &working_dir);
+
+ // There may be modules that we don't want to find by default for operations
+ // like "setting breakpoint by name".
+ // The platform will return "true" from this call if the passed in module
+ // happens to be one of these.
+
+ virtual bool
+ ModuleIsExcludedForUnconstrainedSearches(Target &target,
+ const lldb::ModuleSP &module_sp) {
+ return false;
+ }
+
+ virtual Error MakeDirectory(const FileSpec &file_spec, uint32_t permissions);
+
+ virtual Error GetFilePermissions(const FileSpec &file_spec,
+ uint32_t &file_permissions);
- class PlatformProperties : public Properties
- {
- public:
- PlatformProperties();
-
- static ConstString
- GetSettingName ();
-
- bool
- GetUseModuleCache () const;
- bool
- SetUseModuleCache (bool use_module_cache);
-
- FileSpec
- GetModuleCacheDirectory () const;
- bool
- SetModuleCacheDirectory (const FileSpec& dir_spec);
- };
-
- typedef std::shared_ptr<PlatformProperties> PlatformPropertiesSP;
-
- //----------------------------------------------------------------------
- /// @class Platform Platform.h "lldb/Target/Platform.h"
- /// @brief A plug-in interface definition class for debug platform that
- /// includes many platform abilities such as:
- /// @li getting platform information such as supported architectures,
- /// supported binary file formats and more
- /// @li launching new processes
- /// @li attaching to existing processes
- /// @li download/upload files
- /// @li execute shell commands
- /// @li listing and getting info for existing processes
- /// @li attaching and possibly debugging the platform's kernel
- //----------------------------------------------------------------------
- class Platform :
- public PluginInterface
- {
- public:
- //------------------------------------------------------------------
- /// Default Constructor
- //------------------------------------------------------------------
- Platform (bool is_host_platform);
-
- //------------------------------------------------------------------
- /// Destructor.
- ///
- /// The destructor is virtual since this class is designed to be
- /// inherited from by the plug-in instance.
- //------------------------------------------------------------------
- ~Platform() override;
-
- static void
- Initialize ();
-
- static void
- Terminate ();
-
- static const PlatformPropertiesSP &
- GetGlobalPlatformProperties ();
-
- //------------------------------------------------------------------
- /// Get the native host platform plug-in.
- ///
- /// There should only be one of these for each host that LLDB runs
- /// upon that should be statically compiled in and registered using
- /// preprocessor macros or other similar build mechanisms in a
- /// PlatformSubclass::Initialize() function.
- ///
- /// This platform will be used as the default platform when launching
- /// or attaching to processes unless another platform is specified.
- //------------------------------------------------------------------
- static lldb::PlatformSP
- GetHostPlatform ();
-
- static lldb::PlatformSP
- GetPlatformForArchitecture (const ArchSpec &arch,
- ArchSpec *platform_arch_ptr);
-
- static const char *
- GetHostPlatformName ();
-
- static void
- SetHostPlatform (const lldb::PlatformSP &platform_sp);
-
- // Find an existing platform plug-in by name
- static lldb::PlatformSP
- Find (const ConstString &name);
-
- static lldb::PlatformSP
- Create (const ConstString &name, Error &error);
-
- static lldb::PlatformSP
- Create (const ArchSpec &arch, ArchSpec *platform_arch_ptr, Error &error);
-
- static uint32_t
- GetNumConnectedRemotePlatforms ();
-
- static lldb::PlatformSP
- GetConnectedRemotePlatformAtIndex (uint32_t idx);
-
- //------------------------------------------------------------------
- /// Find a platform plugin for a given process.
- ///
- /// Scans the installed Platform plug-ins and tries to find
- /// an instance that can be used for \a process
- ///
- /// @param[in] process
- /// The process for which to try and locate a platform
- /// plug-in instance.
- ///
- /// @param[in] plugin_name
- /// An optional name of a specific platform plug-in that
- /// should be used. If nullptr, pick the best plug-in.
- //------------------------------------------------------------------
-// static lldb::PlatformSP
-// FindPlugin (Process *process, const ConstString &plugin_name);
-
- //------------------------------------------------------------------
- /// Set the target's executable based off of the existing
- /// architecture information in \a target given a path to an
- /// executable \a exe_file.
- ///
- /// Each platform knows the architectures that it supports and can
- /// select the correct architecture slice within \a exe_file by
- /// inspecting the architecture in \a target. If the target had an
- /// architecture specified, then in can try and obey that request
- /// and optionally fail if the architecture doesn't match up.
- /// If no architecture is specified, the platform should select the
- /// default architecture from \a exe_file. Any application bundles
- /// or executable wrappers can also be inspected for the actual
- /// application binary within the bundle that should be used.
- ///
- /// @return
- /// Returns \b true if this Platform plug-in was able to find
- /// a suitable executable, \b false otherwise.
- //------------------------------------------------------------------
- virtual Error
- ResolveExecutable (const ModuleSpec &module_spec,
- lldb::ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr);
-
- //------------------------------------------------------------------
- /// Find a symbol file given a symbol file module specification.
- ///
- /// Each platform might have tricks to find symbol files for an
- /// executable given information in a symbol file ModuleSpec. Some
- /// platforms might also support symbol files that are bundles and
- /// know how to extract the right symbol file given a bundle.
- ///
- /// @param[in] target
- /// The target in which we are trying to resolve the symbol file.
- /// The target has a list of modules that we might be able to
- /// use in order to help find the right symbol file. If the
- /// "m_file" or "m_platform_file" entries in the \a sym_spec
- /// are filled in, then we might be able to locate a module in
- /// the target, extract its UUID and locate a symbol file.
- /// If just the "m_uuid" is specified, then we might be able
- /// to find the module in the target that matches that UUID
- /// and pair the symbol file along with it. If just "m_symbol_file"
- /// is specified, we can use a variety of tricks to locate the
- /// symbols in an SDK, PDK, or other development kit location.
- ///
- /// @param[in] sym_spec
- /// A module spec that describes some information about the
- /// symbol file we are trying to resolve. The ModuleSpec might
- /// contain the following:
- /// m_file - A full or partial path to an executable from the
- /// target (might be empty).
- /// m_platform_file - Another executable hint that contains
- /// the path to the file as known on the
- /// local/remote platform.
- /// m_symbol_file - A full or partial path to a symbol file
- /// or symbol bundle that should be used when
- /// trying to resolve the symbol file.
- /// m_arch - The architecture we are looking for when resolving
- /// the symbol file.
- /// m_uuid - The UUID of the executable and symbol file. This
- /// can often be used to match up an executable with
- /// a symbol file, or resolve an symbol file in a
- /// symbol file bundle.
- ///
- /// @param[out] sym_file
- /// The resolved symbol file spec if the returned error
- /// indicates success.
- ///
- /// @return
- /// Returns an error that describes success or failure.
- //------------------------------------------------------------------
- virtual Error
- ResolveSymbolFile (Target &target,
- const ModuleSpec &sym_spec,
- FileSpec &sym_file);
-
- //------------------------------------------------------------------
- /// Resolves the FileSpec to a (possibly) remote path. Remote
- /// platforms must override this to resolve to a path on the remote
- /// side.
- //------------------------------------------------------------------
- virtual bool
- ResolveRemotePath (const FileSpec &platform_path,
- FileSpec &resolved_platform_path);
-
- //------------------------------------------------------------------
- /// Get the OS version from a connected platform.
- ///
- /// Some platforms might not be connected to a remote platform, but
- /// can figure out the OS version for a process. This is common for
- /// simulator platforms that will run native programs on the current
- /// host, but the simulator might be simulating a different OS. The
- /// \a process parameter might be specified to help to determine
- /// the OS version.
- //------------------------------------------------------------------
- virtual bool
- GetOSVersion (uint32_t &major,
- uint32_t &minor,
- uint32_t &update,
- Process *process = nullptr);
-
- bool
- SetOSVersion (uint32_t major,
- uint32_t minor,
- uint32_t update);
-
- bool
- GetOSBuildString (std::string &s);
-
- bool
- GetOSKernelDescription (std::string &s);
-
- // Returns the name of the platform
- ConstString
- GetName ();
-
- virtual const char *
- GetHostname ();
-
- virtual ConstString
- GetFullNameForDylib (ConstString basename);
-
- virtual const char *
- GetDescription () = 0;
-
- //------------------------------------------------------------------
- /// Report the current status for this platform.
- ///
- /// The returned string usually involves returning the OS version
- /// (if available), and any SDK directory that might be being used
- /// for local file caching, and if connected a quick blurb about
- /// what this platform is connected to.
- //------------------------------------------------------------------
- virtual void
- GetStatus (Stream &strm);
-
- //------------------------------------------------------------------
- // Subclasses must be able to fetch the current OS version
- //
- // Remote classes must be connected for this to succeed. Local
- // subclasses don't need to override this function as it will just
- // call the HostInfo::GetOSVersion().
- //------------------------------------------------------------------
- virtual bool
- GetRemoteOSVersion ()
- {
- return false;
- }
+ virtual Error SetFilePermissions(const FileSpec &file_spec,
+ uint32_t file_permissions);
- virtual bool
- GetRemoteOSBuildString (std::string &s)
- {
- s.clear();
- return false;
- }
-
- virtual bool
- GetRemoteOSKernelDescription (std::string &s)
- {
- s.clear();
- return false;
- }
+ virtual lldb::user_id_t OpenFile(const FileSpec &file_spec, uint32_t flags,
+ uint32_t mode, Error &error) {
+ return UINT64_MAX;
+ }
- // Remote Platform subclasses need to override this function
- virtual ArchSpec
- GetRemoteSystemArchitecture ()
- {
- return ArchSpec(); // Return an invalid architecture
- }
+ virtual bool CloseFile(lldb::user_id_t fd, Error &error) { return false; }
- virtual FileSpec
- GetRemoteWorkingDirectory()
- {
- return m_working_dir;
- }
-
- virtual bool
- SetRemoteWorkingDirectory(const FileSpec &working_dir);
-
- virtual const char *
- GetUserName (uint32_t uid);
-
- virtual const char *
- GetGroupName (uint32_t gid);
-
- //------------------------------------------------------------------
- /// Locate a file for a platform.
- ///
- /// The default implementation of this function will return the same
- /// file patch in \a local_file as was in \a platform_file.
- ///
- /// @param[in] platform_file
- /// The platform file path to locate and cache locally.
- ///
- /// @param[in] uuid_ptr
- /// If we know the exact UUID of the file we are looking for, it
- /// can be specified. If it is not specified, we might now know
- /// the exact file. The UUID is usually some sort of MD5 checksum
- /// for the file and is sometimes known by dynamic linkers/loaders.
- /// If the UUID is known, it is best to supply it to platform
- /// file queries to ensure we are finding the correct file, not
- /// just a file at the correct path.
- ///
- /// @param[out] local_file
- /// A locally cached version of the platform file. For platforms
- /// that describe the current host computer, this will just be
- /// the same file. For remote platforms, this file might come from
- /// and SDK directory, or might need to be sync'ed over to the
- /// current machine for efficient debugging access.
- ///
- /// @return
- /// An error object.
- //------------------------------------------------------------------
- virtual Error
- GetFileWithUUID (const FileSpec &platform_file,
- const UUID *uuid_ptr,
- FileSpec &local_file);
-
- //----------------------------------------------------------------------
- // Locate the scripting resource given a module specification.
- //
- // Locating the file should happen only on the local computer or using
- // the current computers global settings.
- //----------------------------------------------------------------------
- virtual FileSpecList
- LocateExecutableScriptingResources (Target *target,
- Module &module,
- Stream* feedback_stream);
-
- virtual Error
- GetSharedModule (const ModuleSpec &module_spec,
- Process* process,
- lldb::ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr,
- lldb::ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr);
-
- virtual bool
- GetModuleSpec (const FileSpec& module_file_spec,
- const ArchSpec& arch,
- ModuleSpec &module_spec);
-
- virtual Error
- ConnectRemote (Args& args);
-
- virtual Error
- DisconnectRemote ();
-
- //------------------------------------------------------------------
- /// Get the platform's supported architectures in the order in which
- /// they should be searched.
- ///
- /// @param[in] idx
- /// A zero based architecture index
- ///
- /// @param[out] arch
- /// A copy of the architecture at index if the return value is
- /// \b true.
- ///
- /// @return
- /// \b true if \a arch was filled in and is valid, \b false
- /// otherwise.
- //------------------------------------------------------------------
- virtual bool
- GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) = 0;
-
- virtual size_t
- GetSoftwareBreakpointTrapOpcode (Target &target,
- BreakpointSite *bp_site);
-
- //------------------------------------------------------------------
- /// Launch a new process on a platform, not necessarily for
- /// debugging, it could be just for running the process.
- //------------------------------------------------------------------
- virtual Error
- LaunchProcess (ProcessLaunchInfo &launch_info);
-
- //------------------------------------------------------------------
- /// Perform expansion of the command-line for this launch info
- /// This can potentially involve wildcard expansion
- // environment variable replacement, and whatever other
- // argument magic the platform defines as part of its typical
- // user experience
- //------------------------------------------------------------------
- virtual Error
- ShellExpandArguments (ProcessLaunchInfo &launch_info);
-
- //------------------------------------------------------------------
- /// Kill process on a platform.
- //------------------------------------------------------------------
- virtual Error
- KillProcess (const lldb::pid_t pid);
-
- //------------------------------------------------------------------
- /// Lets a platform answer if it is compatible with a given
- /// architecture and the target triple contained within.
- //------------------------------------------------------------------
- virtual bool
- IsCompatibleArchitecture (const ArchSpec &arch,
- bool exact_arch_match,
- ArchSpec *compatible_arch_ptr);
-
- //------------------------------------------------------------------
- /// Not all platforms will support debugging a process by spawning
- /// somehow halted for a debugger (specified using the
- /// "eLaunchFlagDebug" launch flag) and then attaching. If your
- /// platform doesn't support this, override this function and return
- /// false.
- //------------------------------------------------------------------
- virtual bool
- CanDebugProcess ()
- {
- return true;
- }
+ virtual lldb::user_id_t GetFileSize(const FileSpec &file_spec) {
+ return UINT64_MAX;
+ }
- //------------------------------------------------------------------
- /// Subclasses do not need to implement this function as it uses
- /// the Platform::LaunchProcess() followed by Platform::Attach ().
- /// Remote platforms will want to subclass this function in order
- /// to be able to intercept STDIO and possibly launch a separate
- /// process that will debug the debuggee.
- //------------------------------------------------------------------
- virtual lldb::ProcessSP
- DebugProcess (ProcessLaunchInfo &launch_info,
- Debugger &debugger,
- Target *target, // Can be nullptr, if nullptr create a new target, else use existing one
- Error &error);
-
- virtual lldb::ProcessSP
- ConnectProcess (const char* connect_url,
- const char* plugin_name,
- lldb_private::Debugger &debugger,
- lldb_private::Target *target,
- lldb_private::Error &error);
-
- //------------------------------------------------------------------
- /// Attach to an existing process using a process ID.
- ///
- /// Each platform subclass needs to implement this function and
- /// attempt to attach to the process with the process ID of \a pid.
- /// The platform subclass should return an appropriate ProcessSP
- /// subclass that is attached to the process, or an empty shared
- /// pointer with an appropriate error.
- ///
- /// @param[in] pid
- /// The process ID that we should attempt to attach to.
- ///
- /// @return
- /// An appropriate ProcessSP containing a valid shared pointer
- /// to the default Process subclass for the platform that is
- /// attached to the process, or an empty shared pointer with an
- /// appropriate error fill into the \a error object.
- //------------------------------------------------------------------
- virtual lldb::ProcessSP
- Attach (ProcessAttachInfo &attach_info,
- Debugger &debugger,
- Target *target, // Can be nullptr, if nullptr create a new target, else use existing one
- Error &error) = 0;
-
- //------------------------------------------------------------------
- /// Attach to an existing process by process name.
- ///
- /// This function is not meant to be overridden by Process
- /// subclasses. It will first call
- /// Process::WillAttach (const char *) and if that returns \b
- /// true, Process::DoAttach (const char *) will be called to
- /// actually do the attach. If DoAttach returns \b true, then
- /// Process::DidAttach() will be called.
- ///
- /// @param[in] process_name
- /// A process name to match against the current process list.
- ///
- /// @return
- /// Returns \a pid if attaching was successful, or
- /// LLDB_INVALID_PROCESS_ID if attaching fails.
- //------------------------------------------------------------------
-// virtual lldb::ProcessSP
-// Attach (const char *process_name,
-// bool wait_for_launch,
-// Error &error) = 0;
-
- //------------------------------------------------------------------
- // The base class Platform will take care of the host platform.
- // Subclasses will need to fill in the remote case.
- //------------------------------------------------------------------
- virtual uint32_t
- FindProcesses (const ProcessInstanceInfoMatch &match_info,
- ProcessInstanceInfoList &proc_infos);
-
- virtual bool
- GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &proc_info);
-
- //------------------------------------------------------------------
- // Set a breakpoint on all functions that can end up creating a thread
- // for this platform. This is needed when running expressions and
- // also for process control.
- //------------------------------------------------------------------
- virtual lldb::BreakpointSP
- SetThreadCreationBreakpoint (Target &target);
-
- //------------------------------------------------------------------
- // Given a target, find the local SDK directory if one exists on the
- // current host.
- //------------------------------------------------------------------
- virtual lldb_private::ConstString
- GetSDKDirectory (lldb_private::Target &target)
- {
- return lldb_private::ConstString();
- }
+ virtual uint64_t ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst,
+ uint64_t dst_len, Error &error) {
+ error.SetErrorStringWithFormat(
+ "Platform::ReadFile() is not supported in the %s platform",
+ GetName().GetCString());
+ return -1;
+ }
- const std::string &
- GetRemoteURL () const
- {
- return m_remote_url;
- }
+ virtual uint64_t WriteFile(lldb::user_id_t fd, uint64_t offset,
+ const void *src, uint64_t src_len, Error &error) {
+ error.SetErrorStringWithFormat(
+ "Platform::ReadFile() is not supported in the %s platform",
+ GetName().GetCString());
+ return -1;
+ }
- bool
- IsHost () const
- {
- return m_is_host; // Is this the default host platform?
- }
+ virtual Error GetFile(const FileSpec &source, const FileSpec &destination);
- bool
- IsRemote () const
- {
- return !m_is_host;
- }
-
- virtual bool
- IsConnected () const
- {
- // Remote subclasses should override this function
- return IsHost();
- }
-
- const ArchSpec &
- GetSystemArchitecture();
-
- void
- SetSystemArchitecture (const ArchSpec &arch)
- {
- m_system_arch = arch;
- if (IsHost())
- m_os_version_set_while_connected = m_system_arch.IsValid();
- }
+ virtual Error PutFile(const FileSpec &source, const FileSpec &destination,
+ uint32_t uid = UINT32_MAX, uint32_t gid = UINT32_MAX);
- // Used for column widths
- size_t
- GetMaxUserIDNameLength() const
- {
- return m_max_uid_name_len;
- }
+ virtual Error
+ CreateSymlink(const FileSpec &src, // The name of the link is in src
+ const FileSpec &dst); // The symlink points to dst
- // Used for column widths
- size_t
- GetMaxGroupIDNameLength() const
- {
- return m_max_gid_name_len;
- }
-
- const ConstString &
- GetSDKRootDirectory () const
- {
- return m_sdk_sysroot;
- }
+ //----------------------------------------------------------------------
+ /// Install a file or directory to the remote system.
+ ///
+ /// Install is similar to Platform::PutFile(), but it differs in that if
+ /// an application/framework/shared library is installed on a remote
+ /// platform and the remote platform requires something to be done to
+ /// register the application/framework/shared library, then this extra
+ /// registration can be done.
+ ///
+ /// @param[in] src
+ /// The source file/directory to install on the remote system.
+ ///
+ /// @param[in] dst
+ /// The destination file/directory where \a src will be installed.
+ /// If \a dst has no filename specified, then its filename will
+ /// be set from \a src. It \a dst has no directory specified, it
+ /// will use the platform working directory. If \a dst has a
+ /// directory specified, but the directory path is relative, the
+ /// platform working directory will be prepended to the relative
+ /// directory.
+ ///
+ /// @return
+ /// An error object that describes anything that went wrong.
+ //----------------------------------------------------------------------
+ virtual Error Install(const FileSpec &src, const FileSpec &dst);
+
+ virtual size_t GetEnvironment(StringList &environment);
+
+ virtual bool GetFileExists(const lldb_private::FileSpec &file_spec);
+
+ virtual Error Unlink(const FileSpec &file_spec);
+
+ virtual uint64_t ConvertMmapFlagsToPlatform(const ArchSpec &arch,
+ unsigned flags);
+
+ virtual bool GetSupportsRSync() { return m_supports_rsync; }
+
+ virtual void SetSupportsRSync(bool flag) { m_supports_rsync = flag; }
+
+ virtual const char *GetRSyncOpts() { return m_rsync_opts.c_str(); }
+
+ virtual void SetRSyncOpts(const char *opts) { m_rsync_opts.assign(opts); }
+
+ virtual const char *GetRSyncPrefix() { return m_rsync_prefix.c_str(); }
+
+ virtual void SetRSyncPrefix(const char *prefix) {
+ m_rsync_prefix.assign(prefix);
+ }
+
+ virtual bool GetSupportsSSH() { return m_supports_ssh; }
+
+ virtual void SetSupportsSSH(bool flag) { m_supports_ssh = flag; }
+
+ virtual const char *GetSSHOpts() { return m_ssh_opts.c_str(); }
+
+ virtual void SetSSHOpts(const char *opts) { m_ssh_opts.assign(opts); }
+
+ virtual bool GetIgnoresRemoteHostname() { return m_ignores_remote_hostname; }
+
+ virtual void SetIgnoresRemoteHostname(bool flag) {
+ m_ignores_remote_hostname = flag;
+ }
+
+ virtual lldb_private::OptionGroupOptions *
+ GetConnectionOptions(CommandInterpreter &interpreter) {
+ return nullptr;
+ }
+
+ virtual lldb_private::Error RunShellCommand(
+ const char *command, // Shouldn't be nullptr
+ const FileSpec &working_dir, // Pass empty FileSpec to use the current
+ // working directory
+ int *status_ptr, // Pass nullptr if you don't want the process exit status
+ int *signo_ptr, // Pass nullptr if you don't want the signal that caused
+ // the process to exit
+ std::string
+ *command_output, // Pass nullptr if you don't want the command output
+ uint32_t timeout_sec); // Timeout in seconds to wait for shell program to
+ // finish
+
+ virtual void SetLocalCacheDirectory(const char *local);
+
+ virtual const char *GetLocalCacheDirectory();
+
+ virtual std::string GetPlatformSpecificConnectionInformation() { return ""; }
+
+ virtual bool CalculateMD5(const FileSpec &file_spec, uint64_t &low,
+ uint64_t &high);
+
+ virtual int32_t GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) {
+ return 1;
+ }
+
+ virtual const lldb::UnixSignalsSP &GetRemoteUnixSignals();
+
+ const lldb::UnixSignalsSP &GetUnixSignals();
+
+ //------------------------------------------------------------------
+ /// Locate a queue name given a thread's qaddr
+ ///
+ /// On a system using libdispatch ("Grand Central Dispatch") style
+ /// queues, a thread may be associated with a GCD queue or not,
+ /// and a queue may be associated with multiple threads.
+ /// The process/thread must provide a way to find the "dispatch_qaddr"
+ /// for each thread, and from that dispatch_qaddr this Platform method
+ /// will locate the queue name and provide that.
+ ///
+ /// @param[in] process
+ /// A process is required for reading memory.
+ ///
+ /// @param[in] dispatch_qaddr
+ /// The dispatch_qaddr for this thread.
+ ///
+ /// @return
+ /// The name of the queue, if there is one. An empty string
+ /// means that this thread is not associated with a dispatch
+ /// queue.
+ //------------------------------------------------------------------
+ virtual std::string
+ GetQueueNameForThreadQAddress(Process *process, lldb::addr_t dispatch_qaddr) {
+ return "";
+ }
+
+ //------------------------------------------------------------------
+ /// Locate a queue ID given a thread's qaddr
+ ///
+ /// On a system using libdispatch ("Grand Central Dispatch") style
+ /// queues, a thread may be associated with a GCD queue or not,
+ /// and a queue may be associated with multiple threads.
+ /// The process/thread must provide a way to find the "dispatch_qaddr"
+ /// for each thread, and from that dispatch_qaddr this Platform method
+ /// will locate the queue ID and provide that.
+ ///
+ /// @param[in] process
+ /// A process is required for reading memory.
+ ///
+ /// @param[in] dispatch_qaddr
+ /// The dispatch_qaddr for this thread.
+ ///
+ /// @return
+ /// The queue_id for this thread, if this thread is associated
+ /// with a dispatch queue. Else LLDB_INVALID_QUEUE_ID is returned.
+ //------------------------------------------------------------------
+ virtual lldb::queue_id_t
+ GetQueueIDForThreadQAddress(Process *process, lldb::addr_t dispatch_qaddr) {
+ return LLDB_INVALID_QUEUE_ID;
+ }
+
+ //------------------------------------------------------------------
+ /// Provide a list of trap handler function names for this platform
+ ///
+ /// The unwinder needs to treat trap handlers specially -- the stack
+ /// frame may not be aligned correctly for a trap handler (the kernel
+ /// often won't perturb the stack pointer, or won't re-align it properly,
+ /// in the process of calling the handler) and the frame above the handler
+ /// needs to be treated by the unwinder's "frame 0" rules instead of its
+ /// "middle of the stack frame" rules.
+ ///
+ /// In a user process debugging scenario, the list of trap handlers is
+ /// typically just "_sigtramp".
+ ///
+ /// The Platform base class provides the m_trap_handlers ivar but it does
+ /// not populate it. Subclasses should add the names of the asynchronous
+ /// signal handler routines as needed. For most Unix platforms, add
+ /// _sigtramp.
+ ///
+ /// @return
+ /// A list of symbol names. The list may be empty.
+ //------------------------------------------------------------------
+ virtual const std::vector<ConstString> &GetTrapHandlerSymbolNames();
+
+ //------------------------------------------------------------------
+ /// Find a support executable that may not live within in the
+ /// standard locations related to LLDB.
+ ///
+ /// Executable might exist within the Platform SDK directories, or
+ /// in standard tool directories within the current IDE that is
+ /// running LLDB.
+ ///
+ /// @param[in] basename
+ /// The basename of the executable to locate in the current
+ /// platform.
+ ///
+ /// @return
+ /// A FileSpec pointing to the executable on disk, or an invalid
+ /// FileSpec if the executable cannot be found.
+ //------------------------------------------------------------------
+ virtual FileSpec LocateExecutable(const char *basename) { return FileSpec(); }
+
+ //------------------------------------------------------------------
+ /// Allow the platform to set preferred memory cache line size. If non-zero
+ /// (and the user
+ /// has not set cache line size explicitly), this value will be used as the
+ /// cache line
+ /// size for memory reads.
+ //------------------------------------------------------------------
+ virtual uint32_t GetDefaultMemoryCacheLineSize() { return 0; }
+
+ //------------------------------------------------------------------
+ /// Load a shared library into this process.
+ ///
+ /// Try and load a shared library into the current process. This
+ /// call might fail in the dynamic loader plug-in says it isn't safe
+ /// to try and load shared libraries at the moment.
+ ///
+ /// @param[in] process
+ /// The process to load the image.
+ ///
+ /// @param[in] local_file
+ /// The file spec that points to the shared library that you want
+ /// to load if the library is located on the host. The library will
+ /// be copied over to the location specified by remote_file or into
+ /// the current working directory with the same filename if the
+ /// remote_file isn't specified.
+ ///
+ /// @param[in] remote_file
+ /// If local_file is specified then the location where the library
+ /// should be copied over from the host. If local_file isn't
+ /// specified, then the path for the shared library on the target
+ /// what you want to load.
+ ///
+ /// @param[out] error
+ /// An error object that gets filled in with any errors that
+ /// might occur when trying to load the shared library.
+ ///
+ /// @return
+ /// A token that represents the shared library that can be
+ /// later used to unload the shared library. A value of
+ /// LLDB_INVALID_IMAGE_TOKEN will be returned if the shared
+ /// library can't be opened.
+ //------------------------------------------------------------------
+ uint32_t LoadImage(lldb_private::Process *process,
+ const lldb_private::FileSpec &local_file,
+ const lldb_private::FileSpec &remote_file,
+ lldb_private::Error &error);
+
+ virtual uint32_t DoLoadImage(lldb_private::Process *process,
+ const lldb_private::FileSpec &remote_file,
+ lldb_private::Error &error);
+
+ virtual Error UnloadImage(lldb_private::Process *process,
+ uint32_t image_token);
+
+ //------------------------------------------------------------------
+ /// Connect to all processes waiting for a debugger to attach
+ ///
+ /// If the platform have a list of processes waiting for a debugger
+ /// to connect to them then connect to all of these pending processes.
+ ///
+ /// @param[in] debugger
+ /// The debugger used for the connect.
+ ///
+ /// @param[out] error
+ /// If an error occurred during the connect then this object will
+ /// contain the error message.
+ ///
+ /// @return
+ /// The number of processes we are successfully connected to.
+ //------------------------------------------------------------------
+ virtual size_t ConnectToWaitingProcesses(lldb_private::Debugger &debugger,
+ lldb_private::Error &error);
+
+protected:
+ bool m_is_host;
+ // Set to true when we are able to actually set the OS version while
+ // being connected. For remote platforms, we might set the version ahead
+ // of time before we actually connect and this version might change when
+ // we actually connect to a remote platform. For the host platform this
+ // will be set to the once we call HostInfo::GetOSVersion().
+ bool m_os_version_set_while_connected;
+ bool m_system_arch_set_while_connected;
+ ConstString
+ m_sdk_sysroot; // the root location of where the SDK files are all located
+ ConstString m_sdk_build;
+ FileSpec m_working_dir; // The working directory which is used when installing
+ // modules that have no install path set
+ std::string m_remote_url;
+ std::string m_name;
+ uint32_t m_major_os_version;
+ uint32_t m_minor_os_version;
+ uint32_t m_update_os_version;
+ ArchSpec
+ m_system_arch; // The architecture of the kernel or the remote platform
+ typedef std::map<uint32_t, ConstString> IDToNameMap;
+ // Mutex for modifying Platform data structures that should only be used for
+ // non-reentrant code
+ std::mutex m_mutex;
+ IDToNameMap m_uid_map;
+ IDToNameMap m_gid_map;
+ size_t m_max_uid_name_len;
+ size_t m_max_gid_name_len;
+ bool m_supports_rsync;
+ std::string m_rsync_opts;
+ std::string m_rsync_prefix;
+ bool m_supports_ssh;
+ std::string m_ssh_opts;
+ bool m_ignores_remote_hostname;
+ std::string m_local_cache_directory;
+ std::vector<ConstString> m_trap_handlers;
+ bool m_calculated_trap_handlers;
+ const std::unique_ptr<ModuleCache> m_module_cache;
+
+ //------------------------------------------------------------------
+ /// Ask the Platform subclass to fill in the list of trap handler names
+ ///
+ /// For most Unix user process environments, this will be a single
+ /// function name, _sigtramp. More specialized environments may have
+ /// additional handler names. The unwinder code needs to know when a
+ /// trap handler is on the stack because the unwind rules for the frame
+ /// that caused the trap are different.
+ ///
+ /// The base class Platform ivar m_trap_handlers should be updated by
+ /// the Platform subclass when this method is called. If there are no
+ /// predefined trap handlers, this method may be a no-op.
+ //------------------------------------------------------------------
+ virtual void CalculateTrapHandlerSymbolNames() = 0;
+
+ const char *GetCachedUserName(uint32_t uid) {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ // return the empty string if our string is NULL
+ // so we can tell when things were in the negative
+ // cached (didn't find a valid user name, don't keep
+ // trying)
+ const auto pos = m_uid_map.find(uid);
+ return ((pos != m_uid_map.end()) ? pos->second.AsCString("") : nullptr);
+ }
+
+ const char *SetCachedUserName(uint32_t uid, const char *name,
+ size_t name_len) {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ ConstString const_name(name);
+ m_uid_map[uid] = const_name;
+ if (m_max_uid_name_len < name_len)
+ m_max_uid_name_len = name_len;
+ // Const strings lives forever in our const string pool, so we can return
+ // the const char *
+ return const_name.GetCString();
+ }
+
+ void SetUserNameNotFound(uint32_t uid) {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ m_uid_map[uid] = ConstString();
+ }
+
+ void ClearCachedUserNames() {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ m_uid_map.clear();
+ }
+
+ const char *GetCachedGroupName(uint32_t gid) {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ // return the empty string if our string is NULL
+ // so we can tell when things were in the negative
+ // cached (didn't find a valid group name, don't keep
+ // trying)
+ const auto pos = m_gid_map.find(gid);
+ return ((pos != m_gid_map.end()) ? pos->second.AsCString("") : nullptr);
+ }
+
+ const char *SetCachedGroupName(uint32_t gid, const char *name,
+ size_t name_len) {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ ConstString const_name(name);
+ m_gid_map[gid] = const_name;
+ if (m_max_gid_name_len < name_len)
+ m_max_gid_name_len = name_len;
+ // Const strings lives forever in our const string pool, so we can return
+ // the const char *
+ return const_name.GetCString();
+ }
+
+ void SetGroupNameNotFound(uint32_t gid) {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ m_gid_map[gid] = ConstString();
+ }
+
+ void ClearCachedGroupNames() {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ m_gid_map.clear();
+ }
+
+ Error GetCachedExecutable(ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr,
+ Platform &remote_platform);
+
+ virtual Error DownloadModuleSlice(const FileSpec &src_file_spec,
+ const uint64_t src_offset,
+ const uint64_t src_size,
+ const FileSpec &dst_file_spec);
+
+ virtual Error DownloadSymbolFile(const lldb::ModuleSP &module_sp,
+ const FileSpec &dst_file_spec);
+
+ virtual const char *GetCacheHostname();
+
+private:
+ typedef std::function<Error(const ModuleSpec &)> ModuleResolver;
+
+ Error GetRemoteSharedModule(const ModuleSpec &module_spec, Process *process,
+ lldb::ModuleSP &module_sp,
+ const ModuleResolver &module_resolver,
+ bool *did_create_ptr);
- void
- SetSDKRootDirectory (const ConstString &dir)
- {
- m_sdk_sysroot = dir;
- }
+ bool GetCachedSharedModule(const ModuleSpec &module_spec,
+ lldb::ModuleSP &module_sp, bool *did_create_ptr);
- const ConstString &
- GetSDKBuild () const
- {
- return m_sdk_build;
- }
-
- void
- SetSDKBuild (const ConstString &sdk_build)
- {
- m_sdk_build = sdk_build;
- }
-
- // Override this to return true if your platform supports Clang modules.
- // You may also need to override AddClangModuleCompilationOptions to pass the right Clang flags for your platform.
- virtual bool
- SupportsModules () { return false; }
-
- // Appends the platform-specific options required to find the modules for the current platform.
- virtual void
- AddClangModuleCompilationOptions (Target *target, std::vector<std::string> &options);
-
- FileSpec
- GetWorkingDirectory();
-
- bool
- SetWorkingDirectory(const FileSpec &working_dir);
-
- // There may be modules that we don't want to find by default for operations like "setting breakpoint by name".
- // The platform will return "true" from this call if the passed in module happens to be one of these.
-
- virtual bool
- ModuleIsExcludedForUnconstrainedSearches (Target &target, const lldb::ModuleSP &module_sp)
- {
- return false;
- }
-
- virtual Error
- MakeDirectory(const FileSpec &file_spec, uint32_t permissions);
-
- virtual Error
- GetFilePermissions(const FileSpec &file_spec, uint32_t &file_permissions);
-
- virtual Error
- SetFilePermissions(const FileSpec &file_spec, uint32_t file_permissions);
-
- virtual lldb::user_id_t
- OpenFile (const FileSpec& file_spec,
- uint32_t flags,
- uint32_t mode,
- Error &error)
- {
- return UINT64_MAX;
- }
-
- virtual bool
- CloseFile (lldb::user_id_t fd,
- Error &error)
- {
- return false;
- }
-
- virtual lldb::user_id_t
- GetFileSize (const FileSpec& file_spec)
- {
- return UINT64_MAX;
- }
+ Error LoadCachedExecutable(const ModuleSpec &module_spec,
+ lldb::ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr,
+ Platform &remote_platform);
- virtual uint64_t
- ReadFile (lldb::user_id_t fd,
- uint64_t offset,
- void *dst,
- uint64_t dst_len,
- Error &error)
- {
- error.SetErrorStringWithFormat ("Platform::ReadFile() is not supported in the %s platform", GetName().GetCString());
- return -1;
- }
-
- virtual uint64_t
- WriteFile (lldb::user_id_t fd,
- uint64_t offset,
- const void* src,
- uint64_t src_len,
- Error &error)
- {
- error.SetErrorStringWithFormat ("Platform::ReadFile() is not supported in the %s platform", GetName().GetCString());
- return -1;
- }
-
- virtual Error
- GetFile (const FileSpec& source,
- const FileSpec& destination);
-
- virtual Error
- PutFile (const FileSpec& source,
- const FileSpec& destination,
- uint32_t uid = UINT32_MAX,
- uint32_t gid = UINT32_MAX);
-
- virtual Error
- CreateSymlink(const FileSpec &src, // The name of the link is in src
- const FileSpec &dst); // The symlink points to dst
-
- //----------------------------------------------------------------------
- /// Install a file or directory to the remote system.
- ///
- /// Install is similar to Platform::PutFile(), but it differs in that if
- /// an application/framework/shared library is installed on a remote
- /// platform and the remote platform requires something to be done to
- /// register the application/framework/shared library, then this extra
- /// registration can be done.
- ///
- /// @param[in] src
- /// The source file/directory to install on the remote system.
- ///
- /// @param[in] dst
- /// The destination file/directory where \a src will be installed.
- /// If \a dst has no filename specified, then its filename will
- /// be set from \a src. It \a dst has no directory specified, it
- /// will use the platform working directory. If \a dst has a
- /// directory specified, but the directory path is relative, the
- /// platform working directory will be prepended to the relative
- /// directory.
- ///
- /// @return
- /// An error object that describes anything that went wrong.
- //----------------------------------------------------------------------
- virtual Error
- Install (const FileSpec& src, const FileSpec& dst);
-
- virtual size_t
- GetEnvironment (StringList &environment);
-
- virtual bool
- GetFileExists (const lldb_private::FileSpec& file_spec);
-
- virtual Error
- Unlink(const FileSpec &file_spec);
-
- virtual uint64_t
- ConvertMmapFlagsToPlatform(const ArchSpec &arch, unsigned flags);
-
- virtual bool
- GetSupportsRSync ()
- {
- return m_supports_rsync;
- }
-
- virtual void
- SetSupportsRSync(bool flag)
- {
- m_supports_rsync = flag;
- }
-
- virtual const char*
- GetRSyncOpts ()
- {
- return m_rsync_opts.c_str();
- }
-
- virtual void
- SetRSyncOpts (const char* opts)
- {
- m_rsync_opts.assign(opts);
- }
-
- virtual const char*
- GetRSyncPrefix ()
- {
- return m_rsync_prefix.c_str();
- }
-
- virtual void
- SetRSyncPrefix (const char* prefix)
- {
- m_rsync_prefix.assign(prefix);
- }
-
- virtual bool
- GetSupportsSSH ()
- {
- return m_supports_ssh;
- }
-
- virtual void
- SetSupportsSSH(bool flag)
- {
- m_supports_ssh = flag;
- }
-
- virtual const char*
- GetSSHOpts ()
- {
- return m_ssh_opts.c_str();
- }
-
- virtual void
- SetSSHOpts (const char* opts)
- {
- m_ssh_opts.assign(opts);
- }
-
- virtual bool
- GetIgnoresRemoteHostname ()
- {
- return m_ignores_remote_hostname;
- }
-
- virtual void
- SetIgnoresRemoteHostname(bool flag)
- {
- m_ignores_remote_hostname = flag;
- }
-
- virtual lldb_private::OptionGroupOptions *
- GetConnectionOptions (CommandInterpreter& interpreter)
- {
- return nullptr;
- }
-
- virtual lldb_private::Error
- RunShellCommand(const char *command, // Shouldn't be nullptr
- const FileSpec &working_dir, // Pass empty FileSpec to use the current working directory
- int *status_ptr, // Pass nullptr if you don't want the process exit status
- int *signo_ptr, // Pass nullptr if you don't want the signal that caused the process to exit
- std::string *command_output, // Pass nullptr if you don't want the command output
- uint32_t timeout_sec); // Timeout in seconds to wait for shell program to finish
-
- virtual void
- SetLocalCacheDirectory (const char* local);
-
- virtual const char*
- GetLocalCacheDirectory ();
-
- virtual std::string
- GetPlatformSpecificConnectionInformation()
- {
- return "";
- }
-
- virtual bool
- CalculateMD5 (const FileSpec& file_spec,
- uint64_t &low,
- uint64_t &high);
-
- virtual int32_t
- GetResumeCountForLaunchInfo (ProcessLaunchInfo &launch_info)
- {
- return 1;
- }
+ FileSpec GetModuleCacheRoot();
- virtual const lldb::UnixSignalsSP &
- GetRemoteUnixSignals();
-
- const lldb::UnixSignalsSP &
- GetUnixSignals();
-
- //------------------------------------------------------------------
- /// Locate a queue name given a thread's qaddr
- ///
- /// On a system using libdispatch ("Grand Central Dispatch") style
- /// queues, a thread may be associated with a GCD queue or not,
- /// and a queue may be associated with multiple threads.
- /// The process/thread must provide a way to find the "dispatch_qaddr"
- /// for each thread, and from that dispatch_qaddr this Platform method
- /// will locate the queue name and provide that.
- ///
- /// @param[in] process
- /// A process is required for reading memory.
- ///
- /// @param[in] dispatch_qaddr
- /// The dispatch_qaddr for this thread.
- ///
- /// @return
- /// The name of the queue, if there is one. An empty string
- /// means that this thread is not associated with a dispatch
- /// queue.
- //------------------------------------------------------------------
- virtual std::string
- GetQueueNameForThreadQAddress (Process *process, lldb::addr_t dispatch_qaddr)
- {
- return "";
- }
+ DISALLOW_COPY_AND_ASSIGN(Platform);
+};
- //------------------------------------------------------------------
- /// Locate a queue ID given a thread's qaddr
- ///
- /// On a system using libdispatch ("Grand Central Dispatch") style
- /// queues, a thread may be associated with a GCD queue or not,
- /// and a queue may be associated with multiple threads.
- /// The process/thread must provide a way to find the "dispatch_qaddr"
- /// for each thread, and from that dispatch_qaddr this Platform method
- /// will locate the queue ID and provide that.
- ///
- /// @param[in] process
- /// A process is required for reading memory.
- ///
- /// @param[in] dispatch_qaddr
- /// The dispatch_qaddr for this thread.
- ///
- /// @return
- /// The queue_id for this thread, if this thread is associated
- /// with a dispatch queue. Else LLDB_INVALID_QUEUE_ID is returned.
- //------------------------------------------------------------------
- virtual lldb::queue_id_t
- GetQueueIDForThreadQAddress (Process *process, lldb::addr_t dispatch_qaddr)
- {
- return LLDB_INVALID_QUEUE_ID;
- }
+class PlatformList {
+public:
+ PlatformList() : m_mutex(), m_platforms(), m_selected_platform_sp() {}
- //------------------------------------------------------------------
- /// Provide a list of trap handler function names for this platform
- ///
- /// The unwinder needs to treat trap handlers specially -- the stack
- /// frame may not be aligned correctly for a trap handler (the kernel
- /// often won't perturb the stack pointer, or won't re-align it properly,
- /// in the process of calling the handler) and the frame above the handler
- /// needs to be treated by the unwinder's "frame 0" rules instead of its
- /// "middle of the stack frame" rules.
- ///
- /// In a user process debugging scenario, the list of trap handlers is
- /// typically just "_sigtramp".
- ///
- /// The Platform base class provides the m_trap_handlers ivar but it does
- /// not populate it. Subclasses should add the names of the asynchronous
- /// signal handler routines as needed. For most Unix platforms, add _sigtramp.
- ///
- /// @return
- /// A list of symbol names. The list may be empty.
- //------------------------------------------------------------------
- virtual const std::vector<ConstString> &
- GetTrapHandlerSymbolNames ();
-
- //------------------------------------------------------------------
- /// Find a support executable that may not live within in the
- /// standard locations related to LLDB.
- ///
- /// Executable might exist within the Platform SDK directories, or
- /// in standard tool directories within the current IDE that is
- /// running LLDB.
- ///
- /// @param[in] basename
- /// The basename of the executable to locate in the current
- /// platform.
- ///
- /// @return
- /// A FileSpec pointing to the executable on disk, or an invalid
- /// FileSpec if the executable cannot be found.
- //------------------------------------------------------------------
- virtual FileSpec
- LocateExecutable (const char *basename)
- {
- return FileSpec();
- }
+ ~PlatformList() = default;
- //------------------------------------------------------------------
- /// Allow the platform to set preferred memory cache line size. If non-zero (and the user
- /// has not set cache line size explicitly), this value will be used as the cache line
- /// size for memory reads.
- //------------------------------------------------------------------
- virtual uint32_t
- GetDefaultMemoryCacheLineSize() { return 0; }
-
- //------------------------------------------------------------------
- /// Load a shared library into this process.
- ///
- /// Try and load a shared library into the current process. This
- /// call might fail in the dynamic loader plug-in says it isn't safe
- /// to try and load shared libraries at the moment.
- ///
- /// @param[in] process
- /// The process to load the image.
- ///
- /// @param[in] local_file
- /// The file spec that points to the shared library that you want
- /// to load if the library is located on the host. The library will
- /// be copied over to the location specified by remote_file or into
- /// the current working directory with the same filename if the
- /// remote_file isn't specified.
- ///
- /// @param[in] remote_file
- /// If local_file is specified then the location where the library
- /// should be copied over from the host. If local_file isn't
- /// specified, then the path for the shared library on the target
- /// what you want to load.
- ///
- /// @param[out] error
- /// An error object that gets filled in with any errors that
- /// might occur when trying to load the shared library.
- ///
- /// @return
- /// A token that represents the shared library that can be
- /// later used to unload the shared library. A value of
- /// LLDB_INVALID_IMAGE_TOKEN will be returned if the shared
- /// library can't be opened.
- //------------------------------------------------------------------
- uint32_t
- LoadImage (lldb_private::Process* process,
- const lldb_private::FileSpec& local_file,
- const lldb_private::FileSpec& remote_file,
- lldb_private::Error& error);
-
- virtual uint32_t
- DoLoadImage (lldb_private::Process* process,
- const lldb_private::FileSpec& remote_file,
- lldb_private::Error& error);
-
- virtual Error
- UnloadImage (lldb_private::Process* process, uint32_t image_token);
-
- //------------------------------------------------------------------
- /// Connect to all processes waiting for a debugger to attach
- ///
- /// If the platform have a list of processes waiting for a debugger
- /// to connect to them then connect to all of these pending processes.
- ///
- /// @param[in] debugger
- /// The debugger used for the connect.
- ///
- /// @param[out] error
- /// If an error occurred during the connect then this object will
- /// contain the error message.
- ///
- /// @return
- /// The number of processes we are succesfully connected to.
- //------------------------------------------------------------------
- virtual size_t
- ConnectToWaitingProcesses(lldb_private::Debugger& debugger, lldb_private::Error& error);
-
- protected:
- bool m_is_host;
- // Set to true when we are able to actually set the OS version while
- // being connected. For remote platforms, we might set the version ahead
- // of time before we actually connect and this version might change when
- // we actually connect to a remote platform. For the host platform this
- // will be set to the once we call HostInfo::GetOSVersion().
- bool m_os_version_set_while_connected;
- bool m_system_arch_set_while_connected;
- ConstString m_sdk_sysroot; // the root location of where the SDK files are all located
- ConstString m_sdk_build;
- FileSpec m_working_dir; // The working directory which is used when installing modules that have no install path set
- std::string m_remote_url;
- std::string m_name;
- uint32_t m_major_os_version;
- uint32_t m_minor_os_version;
- uint32_t m_update_os_version;
- ArchSpec m_system_arch; // The architecture of the kernel or the remote platform
- typedef std::map<uint32_t, ConstString> IDToNameMap;
- // Mutex for modifying Platform data structures that should only be used for non-reentrant code
- std::mutex m_mutex;
- IDToNameMap m_uid_map;
- IDToNameMap m_gid_map;
- size_t m_max_uid_name_len;
- size_t m_max_gid_name_len;
- bool m_supports_rsync;
- std::string m_rsync_opts;
- std::string m_rsync_prefix;
- bool m_supports_ssh;
- std::string m_ssh_opts;
- bool m_ignores_remote_hostname;
- std::string m_local_cache_directory;
- std::vector<ConstString> m_trap_handlers;
- bool m_calculated_trap_handlers;
- const std::unique_ptr<ModuleCache> m_module_cache;
-
- //------------------------------------------------------------------
- /// Ask the Platform subclass to fill in the list of trap handler names
- ///
- /// For most Unix user process environments, this will be a single
- /// function name, _sigtramp. More specialized environments may have
- /// additional handler names. The unwinder code needs to know when a
- /// trap handler is on the stack because the unwind rules for the frame
- /// that caused the trap are different.
- ///
- /// The base class Platform ivar m_trap_handlers should be updated by
- /// the Platform subclass when this method is called. If there are no
- /// predefined trap handlers, this method may be a no-op.
- //------------------------------------------------------------------
- virtual void
- CalculateTrapHandlerSymbolNames () = 0;
-
- const char *
- GetCachedUserName(uint32_t uid)
- {
- std::lock_guard<std::mutex> guard(m_mutex);
- // return the empty string if our string is NULL
- // so we can tell when things were in the negative
- // cached (didn't find a valid user name, don't keep
- // trying)
- const auto pos = m_uid_map.find(uid);
- return ((pos != m_uid_map.end()) ? pos->second.AsCString("") : nullptr);
- }
+ void Append(const lldb::PlatformSP &platform_sp, bool set_selected) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ m_platforms.push_back(platform_sp);
+ if (set_selected)
+ m_selected_platform_sp = m_platforms.back();
+ }
- const char *
- SetCachedUserName(uint32_t uid, const char *name, size_t name_len)
- {
- std::lock_guard<std::mutex> guard(m_mutex);
- ConstString const_name(name);
- m_uid_map[uid] = const_name;
- if (m_max_uid_name_len < name_len)
- m_max_uid_name_len = name_len;
- // Const strings lives forever in our const string pool, so we can return the const char *
- return const_name.GetCString();
- }
+ size_t GetSize() {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ return m_platforms.size();
+ }
- void
- SetUserNameNotFound(uint32_t uid)
- {
- std::lock_guard<std::mutex> guard(m_mutex);
- m_uid_map[uid] = ConstString();
+ lldb::PlatformSP GetAtIndex(uint32_t idx) {
+ lldb::PlatformSP platform_sp;
+ {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ if (idx < m_platforms.size())
+ platform_sp = m_platforms[idx];
+ }
+ return platform_sp;
+ }
+
+ //------------------------------------------------------------------
+ /// Select the active platform.
+ ///
+ /// In order to debug remotely, other platform's can be remotely
+ /// connected to and set as the selected platform for any subsequent
+ /// debugging. This allows connection to remote targets and allows
+ /// the ability to discover process info, launch and attach to remote
+ /// processes.
+ //------------------------------------------------------------------
+ lldb::PlatformSP GetSelectedPlatform() {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ if (!m_selected_platform_sp && !m_platforms.empty())
+ m_selected_platform_sp = m_platforms.front();
+
+ return m_selected_platform_sp;
+ }
+
+ void SetSelectedPlatform(const lldb::PlatformSP &platform_sp) {
+ if (platform_sp) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ const size_t num_platforms = m_platforms.size();
+ for (size_t idx = 0; idx < num_platforms; ++idx) {
+ if (m_platforms[idx].get() == platform_sp.get()) {
+ m_selected_platform_sp = m_platforms[idx];
+ return;
}
+ }
+ m_platforms.push_back(platform_sp);
+ m_selected_platform_sp = m_platforms.back();
+ }
+ }
- void
- ClearCachedUserNames()
- {
- std::lock_guard<std::mutex> guard(m_mutex);
- m_uid_map.clear();
- }
+protected:
+ typedef std::vector<lldb::PlatformSP> collection;
+ mutable std::recursive_mutex m_mutex;
+ collection m_platforms;
+ lldb::PlatformSP m_selected_platform_sp;
- const char *
- GetCachedGroupName(uint32_t gid)
- {
- std::lock_guard<std::mutex> guard(m_mutex);
- // return the empty string if our string is NULL
- // so we can tell when things were in the negative
- // cached (didn't find a valid group name, don't keep
- // trying)
- const auto pos = m_gid_map.find(gid);
- return ((pos != m_gid_map.end()) ? pos->second.AsCString("") : nullptr);
- }
+private:
+ DISALLOW_COPY_AND_ASSIGN(PlatformList);
+};
- const char *
- SetCachedGroupName(uint32_t gid, const char *name, size_t name_len)
- {
- std::lock_guard<std::mutex> guard(m_mutex);
- ConstString const_name(name);
- m_gid_map[gid] = const_name;
- if (m_max_gid_name_len < name_len)
- m_max_gid_name_len = name_len;
- // Const strings lives forever in our const string pool, so we can return the const char *
- return const_name.GetCString();
- }
+class OptionGroupPlatformRSync : public lldb_private::OptionGroup {
+public:
+ OptionGroupPlatformRSync() = default;
- void
- SetGroupNameNotFound(uint32_t gid)
- {
- std::lock_guard<std::mutex> guard(m_mutex);
- m_gid_map[gid] = ConstString();
- }
+ ~OptionGroupPlatformRSync() override = default;
- void
- ClearCachedGroupNames()
- {
- std::lock_guard<std::mutex> guard(m_mutex);
- m_gid_map.clear();
- }
+ lldb_private::Error
+ SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
+ ExecutionContext *execution_context) override;
- Error
- GetCachedExecutable (ModuleSpec &module_spec,
- lldb::ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr,
- Platform &remote_platform);
+ void OptionParsingStarting(ExecutionContext *execution_context) override;
- virtual Error
- DownloadModuleSlice (const FileSpec& src_file_spec,
- const uint64_t src_offset,
- const uint64_t src_size,
- const FileSpec& dst_file_spec);
-
- virtual Error
- DownloadSymbolFile (const lldb::ModuleSP& module_sp,
- const FileSpec& dst_file_spec);
-
- virtual const char *
- GetCacheHostname ();
-
- private:
- typedef std::function<Error (const ModuleSpec &)> ModuleResolver;
-
- Error
- GetRemoteSharedModule (const ModuleSpec &module_spec,
- Process* process,
- lldb::ModuleSP &module_sp,
- const ModuleResolver &module_resolver,
- bool *did_create_ptr);
-
- bool
- GetCachedSharedModule (const ModuleSpec& module_spec,
- lldb::ModuleSP &module_sp,
- bool *did_create_ptr);
-
- Error
- LoadCachedExecutable (const ModuleSpec &module_spec,
- lldb::ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr,
- Platform &remote_platform);
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override;
- FileSpec
- GetModuleCacheRoot ();
+ // Options table: Required for subclasses of Options.
- DISALLOW_COPY_AND_ASSIGN (Platform);
- };
+ static lldb_private::OptionDefinition g_option_table[];
- class PlatformList
- {
- public:
- PlatformList() : m_mutex(), m_platforms(), m_selected_platform_sp() {}
-
- ~PlatformList() = default;
-
- void
- Append(const lldb::PlatformSP &platform_sp, bool set_selected)
- {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- m_platforms.push_back(platform_sp);
- if (set_selected)
- m_selected_platform_sp = m_platforms.back();
- }
+ // Instance variables to hold the values for command options.
- size_t
- GetSize()
- {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- return m_platforms.size();
- }
+ bool m_rsync;
+ std::string m_rsync_opts;
+ std::string m_rsync_prefix;
+ bool m_ignores_remote_hostname;
- lldb::PlatformSP
- GetAtIndex(uint32_t idx)
- {
- lldb::PlatformSP platform_sp;
- {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- if (idx < m_platforms.size())
- platform_sp = m_platforms[idx];
- }
- return platform_sp;
- }
+private:
+ DISALLOW_COPY_AND_ASSIGN(OptionGroupPlatformRSync);
+};
- //------------------------------------------------------------------
- /// Select the active platform.
- ///
- /// In order to debug remotely, other platform's can be remotely
- /// connected to and set as the selected platform for any subsequent
- /// debugging. This allows connection to remote targets and allows
- /// the ability to discover process info, launch and attach to remote
- /// processes.
- //------------------------------------------------------------------
- lldb::PlatformSP
- GetSelectedPlatform()
- {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- if (!m_selected_platform_sp && !m_platforms.empty())
- m_selected_platform_sp = m_platforms.front();
-
- return m_selected_platform_sp;
- }
+class OptionGroupPlatformSSH : public lldb_private::OptionGroup {
+public:
+ OptionGroupPlatformSSH() = default;
- void
- SetSelectedPlatform(const lldb::PlatformSP &platform_sp)
- {
- if (platform_sp)
- {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- const size_t num_platforms = m_platforms.size();
- for (size_t idx = 0; idx < num_platforms; ++idx)
- {
- if (m_platforms[idx].get() == platform_sp.get())
- {
- m_selected_platform_sp = m_platforms[idx];
- return;
- }
- }
- m_platforms.push_back(platform_sp);
- m_selected_platform_sp = m_platforms.back();
- }
- }
+ ~OptionGroupPlatformSSH() override = default;
- protected:
- typedef std::vector<lldb::PlatformSP> collection;
- mutable std::recursive_mutex m_mutex;
- collection m_platforms;
- lldb::PlatformSP m_selected_platform_sp;
+ lldb_private::Error
+ SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
+ ExecutionContext *execution_context) override;
- private:
- DISALLOW_COPY_AND_ASSIGN (PlatformList);
- };
+ void OptionParsingStarting(ExecutionContext *execution_context) override;
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override;
+
+ // Options table: Required for subclasses of Options.
+
+ static lldb_private::OptionDefinition g_option_table[];
+
+ // Instance variables to hold the values for command options.
+
+ bool m_ssh;
+ std::string m_ssh_opts;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(OptionGroupPlatformSSH);
+};
+
+class OptionGroupPlatformCaching : public lldb_private::OptionGroup {
+public:
+ OptionGroupPlatformCaching() = default;
+
+ ~OptionGroupPlatformCaching() override = default;
+
+ lldb_private::Error
+ SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
+ ExecutionContext *execution_context) override;
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override;
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override;
+
+ // Options table: Required for subclasses of Options.
+
+ static lldb_private::OptionDefinition g_option_table[];
+
+ // Instance variables to hold the values for command options.
+
+ std::string m_cache_dir;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(OptionGroupPlatformCaching);
+};
- class OptionGroupPlatformRSync : public lldb_private::OptionGroup
- {
- public:
- OptionGroupPlatformRSync() = default;
-
- ~OptionGroupPlatformRSync() override = default;
-
- lldb_private::Error
- SetOptionValue(CommandInterpreter &interpreter,
- uint32_t option_idx,
- const char *option_value) override;
-
- void
- OptionParsingStarting(CommandInterpreter &interpreter) override;
-
- const lldb_private::OptionDefinition*
- GetDefinitions() override;
-
- uint32_t
- GetNumDefinitions() override;
-
- // Options table: Required for subclasses of Options.
-
- static lldb_private::OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- bool m_rsync;
- std::string m_rsync_opts;
- std::string m_rsync_prefix;
- bool m_ignores_remote_hostname;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(OptionGroupPlatformRSync);
- };
-
- class OptionGroupPlatformSSH : public lldb_private::OptionGroup
- {
- public:
- OptionGroupPlatformSSH() = default;
-
- ~OptionGroupPlatformSSH() override = default;
-
- lldb_private::Error
- SetOptionValue(CommandInterpreter &interpreter,
- uint32_t option_idx,
- const char *option_value) override;
-
- void
- OptionParsingStarting(CommandInterpreter &interpreter) override;
-
- uint32_t
- GetNumDefinitions() override;
-
- const lldb_private::OptionDefinition*
- GetDefinitions() override;
-
- // Options table: Required for subclasses of Options.
-
- static lldb_private::OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- bool m_ssh;
- std::string m_ssh_opts;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(OptionGroupPlatformSSH);
- };
-
- class OptionGroupPlatformCaching : public lldb_private::OptionGroup
- {
- public:
- OptionGroupPlatformCaching() = default;
-
- ~OptionGroupPlatformCaching() override = default;
-
- lldb_private::Error
- SetOptionValue(CommandInterpreter &interpreter,
- uint32_t option_idx,
- const char *option_value) override;
-
- void
- OptionParsingStarting(CommandInterpreter &interpreter) override;
-
- uint32_t
- GetNumDefinitions() override;
-
- const lldb_private::OptionDefinition*
- GetDefinitions() override;
-
- // Options table: Required for subclasses of Options.
-
- static lldb_private::OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- std::string m_cache_dir;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(OptionGroupPlatformCaching);
- };
-
} // namespace lldb_private
#endif // liblldb_Platform_h_
diff --git a/include/lldb/Target/Process.h b/include/lldb/Target/Process.h
index 57787f2f8f39..251dfe6a17c0 100644
--- a/include/lldb/Target/Process.h
+++ b/include/lldb/Target/Process.h
@@ -16,16 +16,17 @@
#include <limits.h>
// C++ Includes
+#include <chrono>
#include <list>
#include <memory>
#include <mutex>
#include <string>
-#include <vector>
#include <unordered_set>
+#include <vector>
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
+#include "lldb/Breakpoint/BreakpointSiteList.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Broadcaster.h"
#include "lldb/Core/Communication.h"
@@ -33,88 +34,74 @@
#include "lldb/Core/Event.h"
#include "lldb/Core/Listener.h"
#include "lldb/Core/LoadedModuleInfoList.h"
-#include "lldb/Core/ThreadSafeValue.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Core/StructuredData.h"
+#include "lldb/Core/ThreadSafeValue.h"
#include "lldb/Core/UserSettingsController.h"
-#include "lldb/Breakpoint/BreakpointSiteList.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Host/ProcessRunLock.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Target/InstrumentationRuntime.h"
#include "lldb/Target/Memory.h"
#include "lldb/Target/ProcessInfo.h"
#include "lldb/Target/ProcessLaunchInfo.h"
#include "lldb/Target/QueueList.h"
#include "lldb/Target/ThreadList.h"
-#include "lldb/Target/InstrumentationRuntime.h"
+#include "lldb/lldb-private.h"
+
+#include "llvm/ADT/ArrayRef.h"
namespace lldb_private {
-template <typename B, typename S>
-struct Range;
+template <typename B, typename S> struct Range;
//----------------------------------------------------------------------
// ProcessProperties
//----------------------------------------------------------------------
-class ProcessProperties : public Properties
-{
+class ProcessProperties : public Properties {
public:
- // Pass nullptr for "process" if the ProcessProperties are to be the global copy
- ProcessProperties (lldb_private::Process *process);
-
- ~ProcessProperties() override;
-
- bool
- GetDisableMemoryCache() const;
-
- uint64_t
- GetMemoryCacheLineSize () const;
-
- Args
- GetExtraStartupCommands () const;
-
- void
- SetExtraStartupCommands (const Args &args);
-
- FileSpec
- GetPythonOSPluginPath () const;
-
- void
- SetPythonOSPluginPath (const FileSpec &file);
-
- bool
- GetIgnoreBreakpointsInExpressions () const;
-
- void
- SetIgnoreBreakpointsInExpressions (bool ignore);
-
- bool
- GetUnwindOnErrorInExpressions () const;
-
- void
- SetUnwindOnErrorInExpressions (bool ignore);
-
- bool
- GetStopOnSharedLibraryEvents () const;
-
- void
- SetStopOnSharedLibraryEvents (bool stop);
-
- bool
- GetDetachKeepsStopped () const;
-
- void
- SetDetachKeepsStopped (bool keep_stopped);
-
- bool
- GetWarningsOptimization () const;
+ // Pass nullptr for "process" if the ProcessProperties are to be the global
+ // copy
+ ProcessProperties(lldb_private::Process *process);
+
+ ~ProcessProperties() override;
+
+ bool GetDisableMemoryCache() const;
+
+ uint64_t GetMemoryCacheLineSize() const;
+
+ Args GetExtraStartupCommands() const;
+
+ void SetExtraStartupCommands(const Args &args);
+
+ FileSpec GetPythonOSPluginPath() const;
+
+ void SetPythonOSPluginPath(const FileSpec &file);
+
+ bool GetIgnoreBreakpointsInExpressions() const;
+
+ void SetIgnoreBreakpointsInExpressions(bool ignore);
+
+ bool GetUnwindOnErrorInExpressions() const;
+
+ void SetUnwindOnErrorInExpressions(bool ignore);
+
+ bool GetStopOnSharedLibraryEvents() const;
+
+ void SetStopOnSharedLibraryEvents(bool stop);
+
+ bool GetDetachKeepsStopped() const;
+
+ void SetDetachKeepsStopped(bool keep_stopped);
+
+ bool GetWarningsOptimization() const;
protected:
- static void
- OptionValueChangedCallback (void *baton, OptionValue *option_value);
+ static void OptionValueChangedCallback(void *baton,
+ OptionValue *option_value);
- Process * m_process; // Can be nullptr for global ProcessProperties
+ Process *m_process; // Can be nullptr for global ProcessProperties
};
typedef std::shared_ptr<ProcessProperties> ProcessPropertiesSP;
@@ -125,103 +112,55 @@ typedef std::shared_ptr<ProcessProperties> ProcessPropertiesSP;
// Describes an existing process and any discoverable information that
// pertains to that process.
//----------------------------------------------------------------------
-class ProcessInstanceInfo : public ProcessInfo
-{
+class ProcessInstanceInfo : public ProcessInfo {
public:
- ProcessInstanceInfo () :
- ProcessInfo (),
- m_euid (UINT32_MAX),
- m_egid (UINT32_MAX),
- m_parent_pid (LLDB_INVALID_PROCESS_ID)
- {
- }
+ ProcessInstanceInfo()
+ : ProcessInfo(), m_euid(UINT32_MAX), m_egid(UINT32_MAX),
+ m_parent_pid(LLDB_INVALID_PROCESS_ID) {}
- ProcessInstanceInfo (const char *name,
- const ArchSpec &arch,
- lldb::pid_t pid) :
- ProcessInfo (name, arch, pid),
- m_euid (UINT32_MAX),
- m_egid (UINT32_MAX),
- m_parent_pid (LLDB_INVALID_PROCESS_ID)
- {
- }
-
- void
- Clear ()
- {
- ProcessInfo::Clear();
- m_euid = UINT32_MAX;
- m_egid = UINT32_MAX;
- m_parent_pid = LLDB_INVALID_PROCESS_ID;
- }
-
- uint32_t
- GetEffectiveUserID() const
- {
- return m_euid;
- }
+ ProcessInstanceInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid)
+ : ProcessInfo(name, arch, pid), m_euid(UINT32_MAX), m_egid(UINT32_MAX),
+ m_parent_pid(LLDB_INVALID_PROCESS_ID) {}
- uint32_t
- GetEffectiveGroupID() const
- {
- return m_egid;
- }
-
- bool
- EffectiveUserIDIsValid () const
- {
- return m_euid != UINT32_MAX;
- }
+ void Clear() {
+ ProcessInfo::Clear();
+ m_euid = UINT32_MAX;
+ m_egid = UINT32_MAX;
+ m_parent_pid = LLDB_INVALID_PROCESS_ID;
+ }
- bool
- EffectiveGroupIDIsValid () const
- {
- return m_egid != UINT32_MAX;
- }
+ uint32_t GetEffectiveUserID() const { return m_euid; }
- void
- SetEffectiveUserID (uint32_t uid)
- {
- m_euid = uid;
- }
-
- void
- SetEffectiveGroupID (uint32_t gid)
- {
- m_egid = gid;
- }
+ uint32_t GetEffectiveGroupID() const { return m_egid; }
- lldb::pid_t
- GetParentProcessID () const
- {
- return m_parent_pid;
- }
-
- void
- SetParentProcessID (lldb::pid_t pid)
- {
- m_parent_pid = pid;
- }
-
- bool
- ParentProcessIDIsValid() const
- {
- return m_parent_pid != LLDB_INVALID_PROCESS_ID;
- }
-
- void
- Dump (Stream &s, Platform *platform) const;
+ bool EffectiveUserIDIsValid() const { return m_euid != UINT32_MAX; }
+
+ bool EffectiveGroupIDIsValid() const { return m_egid != UINT32_MAX; }
+
+ void SetEffectiveUserID(uint32_t uid) { m_euid = uid; }
+
+ void SetEffectiveGroupID(uint32_t gid) { m_egid = gid; }
+
+ lldb::pid_t GetParentProcessID() const { return m_parent_pid; }
+
+ void SetParentProcessID(lldb::pid_t pid) { m_parent_pid = pid; }
- static void
- DumpTableHeader (Stream &s, Platform *platform, bool show_args, bool verbose);
+ bool ParentProcessIDIsValid() const {
+ return m_parent_pid != LLDB_INVALID_PROCESS_ID;
+ }
+
+ void Dump(Stream &s, Platform *platform) const;
+
+ static void DumpTableHeader(Stream &s, Platform *platform, bool show_args,
+ bool verbose);
+
+ void DumpAsTableRow(Stream &s, Platform *platform, bool show_args,
+ bool verbose) const;
- void
- DumpAsTableRow (Stream &s, Platform *platform, bool show_args, bool verbose) const;
-
protected:
- uint32_t m_euid;
- uint32_t m_egid;
- lldb::pid_t m_parent_pid;
+ uint32_t m_euid;
+ uint32_t m_egid;
+ lldb::pid_t m_parent_pid;
};
//----------------------------------------------------------------------
@@ -229,230 +168,132 @@ protected:
//
// Describes any information that is required to attach to a process.
//----------------------------------------------------------------------
-
-class ProcessAttachInfo : public ProcessInstanceInfo
-{
+
+class ProcessAttachInfo : public ProcessInstanceInfo {
public:
- ProcessAttachInfo() :
- ProcessInstanceInfo(),
- m_listener_sp(),
- m_hijack_listener_sp(),
- m_plugin_name (),
- m_resume_count (0),
- m_wait_for_launch (false),
- m_ignore_existing (true),
- m_continue_once_attached (false),
- m_detach_on_error (true),
- m_async (false)
- {
- }
+ ProcessAttachInfo()
+ : ProcessInstanceInfo(), m_listener_sp(), m_hijack_listener_sp(),
+ m_plugin_name(), m_resume_count(0), m_wait_for_launch(false),
+ m_ignore_existing(true), m_continue_once_attached(false),
+ m_detach_on_error(true), m_async(false) {}
- ProcessAttachInfo (const ProcessLaunchInfo &launch_info) :
- ProcessInstanceInfo(),
- m_listener_sp(),
- m_hijack_listener_sp(),
- m_plugin_name (),
- m_resume_count (0),
- m_wait_for_launch (false),
- m_ignore_existing (true),
- m_continue_once_attached (false),
- m_detach_on_error (true),
- m_async (false)
- {
- ProcessInfo::operator= (launch_info);
- SetProcessPluginName (launch_info.GetProcessPluginName());
- SetResumeCount (launch_info.GetResumeCount());
- SetListener(launch_info.GetListener());
- SetHijackListener(launch_info.GetHijackListener());
- m_detach_on_error = launch_info.GetDetachOnError();
- }
-
- bool
- GetWaitForLaunch () const
- {
- return m_wait_for_launch;
- }
-
- void
- SetWaitForLaunch (bool b)
- {
- m_wait_for_launch = b;
- }
+ ProcessAttachInfo(const ProcessLaunchInfo &launch_info)
+ : ProcessInstanceInfo(), m_listener_sp(), m_hijack_listener_sp(),
+ m_plugin_name(), m_resume_count(0), m_wait_for_launch(false),
+ m_ignore_existing(true), m_continue_once_attached(false),
+ m_detach_on_error(true), m_async(false) {
+ ProcessInfo::operator=(launch_info);
+ SetProcessPluginName(launch_info.GetProcessPluginName());
+ SetResumeCount(launch_info.GetResumeCount());
+ SetListener(launch_info.GetListener());
+ SetHijackListener(launch_info.GetHijackListener());
+ m_detach_on_error = launch_info.GetDetachOnError();
+ }
- bool
- GetAsync () const
- {
- return m_async;
- }
+ bool GetWaitForLaunch() const { return m_wait_for_launch; }
- void
- SetAsync (bool b)
- {
- m_async = b;
- }
+ void SetWaitForLaunch(bool b) { m_wait_for_launch = b; }
- bool
- GetIgnoreExisting () const
- {
- return m_ignore_existing;
- }
-
- void
- SetIgnoreExisting (bool b)
- {
- m_ignore_existing = b;
- }
+ bool GetAsync() const { return m_async; }
- bool
- GetContinueOnceAttached () const
- {
- return m_continue_once_attached;
- }
-
- void
- SetContinueOnceAttached (bool b)
- {
- m_continue_once_attached = b;
- }
+ void SetAsync(bool b) { m_async = b; }
- uint32_t
- GetResumeCount () const
- {
- return m_resume_count;
- }
-
- void
- SetResumeCount (uint32_t c)
- {
- m_resume_count = c;
- }
-
- const char *
- GetProcessPluginName () const
- {
- return (m_plugin_name.empty() ? nullptr : m_plugin_name.c_str());
- }
-
- void
- SetProcessPluginName (const char *plugin)
- {
- if (plugin && plugin[0])
- m_plugin_name.assign (plugin);
- else
- m_plugin_name.clear();
- }
+ bool GetIgnoreExisting() const { return m_ignore_existing; }
- void
- Clear ()
- {
- ProcessInstanceInfo::Clear();
- m_plugin_name.clear();
- m_resume_count = 0;
- m_wait_for_launch = false;
- m_ignore_existing = true;
- m_continue_once_attached = false;
- }
+ void SetIgnoreExisting(bool b) { m_ignore_existing = b; }
- bool
- ProcessInfoSpecified () const
- {
- if (GetExecutableFile())
- return true;
- if (GetProcessID() != LLDB_INVALID_PROCESS_ID)
- return true;
- if (GetParentProcessID() != LLDB_INVALID_PROCESS_ID)
- return true;
- return false;
- }
-
- lldb::ListenerSP
- GetHijackListener () const
- {
- return m_hijack_listener_sp;
- }
-
- void
- SetHijackListener (const lldb::ListenerSP &listener_sp)
- {
- m_hijack_listener_sp = listener_sp;
- }
-
- bool
- GetDetachOnError () const
- {
- return m_detach_on_error;
- }
-
- void
- SetDetachOnError (bool enable)
- {
- m_detach_on_error = enable;
- }
+ bool GetContinueOnceAttached() const { return m_continue_once_attached; }
- // Get and set the actual listener that will be used for the process events
- lldb::ListenerSP
- GetListener () const
- {
- return m_listener_sp;
- }
+ void SetContinueOnceAttached(bool b) { m_continue_once_attached = b; }
- void
- SetListener (const lldb::ListenerSP &listener_sp)
- {
- m_listener_sp = listener_sp;
- }
+ uint32_t GetResumeCount() const { return m_resume_count; }
+
+ void SetResumeCount(uint32_t c) { m_resume_count = c; }
+
+ const char *GetProcessPluginName() const {
+ return (m_plugin_name.empty() ? nullptr : m_plugin_name.c_str());
+ }
+
+ void SetProcessPluginName(llvm::StringRef plugin) { m_plugin_name = plugin; }
- lldb::ListenerSP
- GetListenerForProcess (Debugger &debugger);
+ void Clear() {
+ ProcessInstanceInfo::Clear();
+ m_plugin_name.clear();
+ m_resume_count = 0;
+ m_wait_for_launch = false;
+ m_ignore_existing = true;
+ m_continue_once_attached = false;
+ }
+
+ bool ProcessInfoSpecified() const {
+ if (GetExecutableFile())
+ return true;
+ if (GetProcessID() != LLDB_INVALID_PROCESS_ID)
+ return true;
+ if (GetParentProcessID() != LLDB_INVALID_PROCESS_ID)
+ return true;
+ return false;
+ }
+
+ lldb::ListenerSP GetHijackListener() const { return m_hijack_listener_sp; }
+
+ void SetHijackListener(const lldb::ListenerSP &listener_sp) {
+ m_hijack_listener_sp = listener_sp;
+ }
+
+ bool GetDetachOnError() const { return m_detach_on_error; }
+
+ void SetDetachOnError(bool enable) { m_detach_on_error = enable; }
+
+ // Get and set the actual listener that will be used for the process events
+ lldb::ListenerSP GetListener() const { return m_listener_sp; }
+
+ void SetListener(const lldb::ListenerSP &listener_sp) {
+ m_listener_sp = listener_sp;
+ }
+
+ lldb::ListenerSP GetListenerForProcess(Debugger &debugger);
protected:
- lldb::ListenerSP m_listener_sp;
- lldb::ListenerSP m_hijack_listener_sp;
- std::string m_plugin_name;
- uint32_t m_resume_count; // How many times do we resume after launching
- bool m_wait_for_launch;
- bool m_ignore_existing;
- bool m_continue_once_attached; // Supports the use-case scenario of immediately continuing the process once attached.
- bool m_detach_on_error; // If we are debugging remotely, instruct the stub to detach rather than killing the target on error.
- bool m_async; // Use an async attach where we start the attach and return immediately (used by GUI programs with --waitfor so they can call SBProcess::Stop() to cancel attach)
+ lldb::ListenerSP m_listener_sp;
+ lldb::ListenerSP m_hijack_listener_sp;
+ std::string m_plugin_name;
+ uint32_t m_resume_count; // How many times do we resume after launching
+ bool m_wait_for_launch;
+ bool m_ignore_existing;
+ bool m_continue_once_attached; // Supports the use-case scenario of
+ // immediately continuing the process once
+ // attached.
+ bool m_detach_on_error; // If we are debugging remotely, instruct the stub to
+ // detach rather than killing the target on error.
+ bool m_async; // Use an async attach where we start the attach and return
+ // immediately (used by GUI programs with --waitfor so they can
+ // call SBProcess::Stop() to cancel attach)
};
-class ProcessLaunchCommandOptions : public Options
-{
+class ProcessLaunchCommandOptions : public Options {
public:
- ProcessLaunchCommandOptions (CommandInterpreter &interpreter) :
- Options(interpreter)
- {
- // Keep default values of all options in one place: OptionParsingStarting ()
- OptionParsingStarting ();
- }
+ ProcessLaunchCommandOptions() : Options() {
+ // Keep default values of all options in one place: OptionParsingStarting ()
+ OptionParsingStarting(nullptr);
+ }
- ~ProcessLaunchCommandOptions() override = default;
+ ~ProcessLaunchCommandOptions() override = default;
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override;
-
- void
- OptionParsingStarting() override
- {
- launch_info.Clear();
- disable_aslr = eLazyBoolCalculate;
- }
-
- const OptionDefinition*
- GetDefinitions() override
- {
- return g_option_table;
- }
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- ProcessLaunchInfo launch_info;
- lldb_private::LazyBool disable_aslr;
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override;
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ launch_info.Clear();
+ disable_aslr = eLazyBoolCalculate;
+ }
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override;
+
+ // Instance variables to hold the values for command options.
+
+ ProcessLaunchInfo launch_info;
+ lldb_private::LazyBool disable_aslr;
};
//----------------------------------------------------------------------
@@ -461,3129 +302,2874 @@ public:
// A class to help matching one ProcessInstanceInfo to another.
//----------------------------------------------------------------------
-class ProcessInstanceInfoMatch
-{
+class ProcessInstanceInfoMatch {
public:
- ProcessInstanceInfoMatch () :
- m_match_info (),
- m_name_match_type (eNameMatchIgnore),
- m_match_all_users (false)
- {
- }
+ ProcessInstanceInfoMatch()
+ : m_match_info(), m_name_match_type(eNameMatchIgnore),
+ m_match_all_users(false) {}
- ProcessInstanceInfoMatch (const char *process_name,
- NameMatchType process_name_match_type) :
- m_match_info (),
- m_name_match_type (process_name_match_type),
- m_match_all_users (false)
- {
- m_match_info.GetExecutableFile().SetFile(process_name, false);
- }
+ ProcessInstanceInfoMatch(const char *process_name,
+ NameMatchType process_name_match_type)
+ : m_match_info(), m_name_match_type(process_name_match_type),
+ m_match_all_users(false) {
+ m_match_info.GetExecutableFile().SetFile(process_name, false);
+ }
- ProcessInstanceInfo &
- GetProcessInfo ()
- {
- return m_match_info;
- }
+ ProcessInstanceInfo &GetProcessInfo() { return m_match_info; }
- const ProcessInstanceInfo &
- GetProcessInfo () const
- {
- return m_match_info;
- }
-
- bool
- GetMatchAllUsers () const
- {
- return m_match_all_users;
- }
+ const ProcessInstanceInfo &GetProcessInfo() const { return m_match_info; }
- void
- SetMatchAllUsers (bool b)
- {
- m_match_all_users = b;
- }
+ bool GetMatchAllUsers() const { return m_match_all_users; }
- NameMatchType
- GetNameMatchType () const
- {
- return m_name_match_type;
- }
+ void SetMatchAllUsers(bool b) { m_match_all_users = b; }
- void
- SetNameMatchType (NameMatchType name_match_type)
- {
- m_name_match_type = name_match_type;
- }
-
- bool
- NameMatches (const char *process_name) const;
+ NameMatchType GetNameMatchType() const { return m_name_match_type; }
+
+ void SetNameMatchType(NameMatchType name_match_type) {
+ m_name_match_type = name_match_type;
+ }
- bool
- Matches (const ProcessInstanceInfo &proc_info) const;
+ bool NameMatches(const char *process_name) const;
- bool
- MatchAllProcesses () const;
- void
- Clear ();
+ bool Matches(const ProcessInstanceInfo &proc_info) const;
+
+ bool MatchAllProcesses() const;
+ void Clear();
protected:
- ProcessInstanceInfo m_match_info;
- NameMatchType m_name_match_type;
- bool m_match_all_users;
+ ProcessInstanceInfo m_match_info;
+ NameMatchType m_name_match_type;
+ bool m_match_all_users;
};
-class ProcessInstanceInfoList
-{
+class ProcessInstanceInfoList {
public:
- ProcessInstanceInfoList() = default;
+ ProcessInstanceInfoList() = default;
- void
- Clear()
- {
- m_infos.clear();
- }
-
- size_t
- GetSize()
- {
- return m_infos.size();
- }
-
- void
- Append (const ProcessInstanceInfo &info)
- {
- m_infos.push_back (info);
- }
+ void Clear() { m_infos.clear(); }
- const char *
- GetProcessNameAtIndex (size_t idx)
- {
- return ((idx < m_infos.size()) ? m_infos[idx].GetName() : nullptr);
- }
+ size_t GetSize() { return m_infos.size(); }
- size_t
- GetProcessNameLengthAtIndex (size_t idx)
- {
- return ((idx < m_infos.size()) ? m_infos[idx].GetNameLength() : 0);
- }
+ void Append(const ProcessInstanceInfo &info) { m_infos.push_back(info); }
- lldb::pid_t
- GetProcessIDAtIndex (size_t idx)
- {
- return ((idx < m_infos.size()) ? m_infos[idx].GetProcessID() : 0);
- }
+ const char *GetProcessNameAtIndex(size_t idx) {
+ return ((idx < m_infos.size()) ? m_infos[idx].GetName() : nullptr);
+ }
- bool
- GetInfoAtIndex (size_t idx, ProcessInstanceInfo &info)
- {
- if (idx < m_infos.size())
- {
- info = m_infos[idx];
- return true;
- }
- return false;
- }
-
- // You must ensure "idx" is valid before calling this function
- const ProcessInstanceInfo &
- GetProcessInfoAtIndex (size_t idx) const
- {
- assert (idx < m_infos.size());
- return m_infos[idx];
+ size_t GetProcessNameLengthAtIndex(size_t idx) {
+ return ((idx < m_infos.size()) ? m_infos[idx].GetNameLength() : 0);
+ }
+
+ lldb::pid_t GetProcessIDAtIndex(size_t idx) {
+ return ((idx < m_infos.size()) ? m_infos[idx].GetProcessID() : 0);
+ }
+
+ bool GetInfoAtIndex(size_t idx, ProcessInstanceInfo &info) {
+ if (idx < m_infos.size()) {
+ info = m_infos[idx];
+ return true;
}
-
+ return false;
+ }
+
+ // You must ensure "idx" is valid before calling this function
+ const ProcessInstanceInfo &GetProcessInfoAtIndex(size_t idx) const {
+ assert(idx < m_infos.size());
+ return m_infos[idx];
+ }
+
protected:
- typedef std::vector<ProcessInstanceInfo> collection;
- collection m_infos;
+ typedef std::vector<ProcessInstanceInfo> collection;
+ collection m_infos;
};
-// This class tracks the Modification state of the process. Things that can currently modify
-// the program are running the program (which will up the StopID) and writing memory (which
-// will up the MemoryID.)
+// This class tracks the Modification state of the process. Things that can
+// currently modify
+// the program are running the program (which will up the StopID) and writing
+// memory (which
+// will up the MemoryID.)
// FIXME: Should we also include modification of register states?
-class ProcessModID
-{
- friend bool operator== (const ProcessModID &lhs, const ProcessModID &rhs);
+class ProcessModID {
+ friend bool operator==(const ProcessModID &lhs, const ProcessModID &rhs);
+
public:
- ProcessModID () :
- m_stop_id (0),
- m_last_natural_stop_id(0),
- m_resume_id (0),
- m_memory_id (0),
- m_last_user_expression_resume (0),
- m_running_user_expression (false)
- {}
-
- ProcessModID (const ProcessModID &rhs) :
- m_stop_id (rhs.m_stop_id),
- m_memory_id (rhs.m_memory_id)
- {}
-
- const ProcessModID & operator= (const ProcessModID &rhs)
- {
- if (this != &rhs)
- {
- m_stop_id = rhs.m_stop_id;
- m_memory_id = rhs.m_memory_id;
- }
- return *this;
- }
-
- ~ProcessModID() = default;
-
- void BumpStopID () {
- m_stop_id++;
- if (!IsLastResumeForUserExpression())
- m_last_natural_stop_id++;
- }
-
- void BumpMemoryID () { m_memory_id++; }
-
- void BumpResumeID () {
- m_resume_id++;
- if (m_running_user_expression > 0)
- m_last_user_expression_resume = m_resume_id;
- }
-
- uint32_t GetStopID() const { return m_stop_id; }
- uint32_t GetLastNaturalStopID() const { return m_last_natural_stop_id; }
- uint32_t GetMemoryID () const { return m_memory_id; }
- uint32_t GetResumeID () const { return m_resume_id; }
- uint32_t GetLastUserExpressionResumeID () const { return m_last_user_expression_resume; }
-
- bool MemoryIDEqual (const ProcessModID &compare) const
- {
- return m_memory_id == compare.m_memory_id;
- }
-
- bool StopIDEqual (const ProcessModID &compare) const
- {
- return m_stop_id == compare.m_stop_id;
- }
-
- void SetInvalid ()
- {
- m_stop_id = UINT32_MAX;
- }
-
- bool IsValid () const
- {
- return m_stop_id != UINT32_MAX;
- }
-
- bool
- IsLastResumeForUserExpression () const
- {
- // If we haven't yet resumed the target, then it can't be for a user expression...
- if (m_resume_id == 0)
- return false;
-
- return m_resume_id == m_last_user_expression_resume;
- }
-
- void
- SetRunningUserExpression (bool on)
- {
- if (on)
- m_running_user_expression++;
- else
- m_running_user_expression--;
- }
+ ProcessModID()
+ : m_stop_id(0), m_last_natural_stop_id(0), m_resume_id(0), m_memory_id(0),
+ m_last_user_expression_resume(0), m_running_user_expression(false) {}
- void
- SetStopEventForLastNaturalStopID (lldb::EventSP event_sp)
- {
- m_last_natural_stop_event = event_sp;
- }
+ ProcessModID(const ProcessModID &rhs)
+ : m_stop_id(rhs.m_stop_id), m_memory_id(rhs.m_memory_id) {}
- lldb::EventSP GetStopEventForStopID (uint32_t stop_id) const
- {
- if (stop_id == m_last_natural_stop_id)
- return m_last_natural_stop_event;
- return lldb::EventSP();
+ const ProcessModID &operator=(const ProcessModID &rhs) {
+ if (this != &rhs) {
+ m_stop_id = rhs.m_stop_id;
+ m_memory_id = rhs.m_memory_id;
}
+ return *this;
+ }
+
+ ~ProcessModID() = default;
+
+ void BumpStopID() {
+ m_stop_id++;
+ if (!IsLastResumeForUserExpression())
+ m_last_natural_stop_id++;
+ }
+
+ void BumpMemoryID() { m_memory_id++; }
+
+ void BumpResumeID() {
+ m_resume_id++;
+ if (m_running_user_expression > 0)
+ m_last_user_expression_resume = m_resume_id;
+ }
+
+ uint32_t GetStopID() const { return m_stop_id; }
+ uint32_t GetLastNaturalStopID() const { return m_last_natural_stop_id; }
+ uint32_t GetMemoryID() const { return m_memory_id; }
+ uint32_t GetResumeID() const { return m_resume_id; }
+ uint32_t GetLastUserExpressionResumeID() const {
+ return m_last_user_expression_resume;
+ }
+
+ bool MemoryIDEqual(const ProcessModID &compare) const {
+ return m_memory_id == compare.m_memory_id;
+ }
+
+ bool StopIDEqual(const ProcessModID &compare) const {
+ return m_stop_id == compare.m_stop_id;
+ }
+
+ void SetInvalid() { m_stop_id = UINT32_MAX; }
+
+ bool IsValid() const { return m_stop_id != UINT32_MAX; }
+
+ bool IsLastResumeForUserExpression() const {
+ // If we haven't yet resumed the target, then it can't be for a user
+ // expression...
+ if (m_resume_id == 0)
+ return false;
+
+ return m_resume_id == m_last_user_expression_resume;
+ }
+
+ void SetRunningUserExpression(bool on) {
+ if (on)
+ m_running_user_expression++;
+ else
+ m_running_user_expression--;
+ }
+
+ void SetStopEventForLastNaturalStopID(lldb::EventSP event_sp) {
+ m_last_natural_stop_event = event_sp;
+ }
+
+ lldb::EventSP GetStopEventForStopID(uint32_t stop_id) const {
+ if (stop_id == m_last_natural_stop_id)
+ return m_last_natural_stop_event;
+ return lldb::EventSP();
+ }
private:
- uint32_t m_stop_id;
- uint32_t m_last_natural_stop_id;
- uint32_t m_resume_id;
- uint32_t m_memory_id;
- uint32_t m_last_user_expression_resume;
- uint32_t m_running_user_expression;
- lldb::EventSP m_last_natural_stop_event;
+ uint32_t m_stop_id;
+ uint32_t m_last_natural_stop_id;
+ uint32_t m_resume_id;
+ uint32_t m_memory_id;
+ uint32_t m_last_user_expression_resume;
+ uint32_t m_running_user_expression;
+ lldb::EventSP m_last_natural_stop_event;
};
-inline bool operator== (const ProcessModID &lhs, const ProcessModID &rhs)
-{
- if (lhs.StopIDEqual (rhs)
- && lhs.MemoryIDEqual (rhs))
- return true;
- else
- return false;
+inline bool operator==(const ProcessModID &lhs, const ProcessModID &rhs) {
+ if (lhs.StopIDEqual(rhs) && lhs.MemoryIDEqual(rhs))
+ return true;
+ else
+ return false;
}
-inline bool operator!= (const ProcessModID &lhs, const ProcessModID &rhs)
-{
- return (!lhs.StopIDEqual (rhs) || !lhs.MemoryIDEqual (rhs));
+inline bool operator!=(const ProcessModID &lhs, const ProcessModID &rhs) {
+ return (!lhs.StopIDEqual(rhs) || !lhs.MemoryIDEqual(rhs));
}
-
+
//----------------------------------------------------------------------
/// @class Process Process.h "lldb/Target/Process.h"
/// @brief A plug-in interface definition class for debugging a process.
//----------------------------------------------------------------------
-class Process :
- public std::enable_shared_from_this<Process>,
- public ProcessProperties,
- public UserID,
- public Broadcaster,
- public ExecutionContextScope,
- public PluginInterface
-{
- friend class FunctionCaller; // For WaitForStateChangeEventsPrivate
- friend class Debugger; // For PopProcessIOHandler and ProcessIOHandlerIsActive
- friend class ProcessEventData;
- friend class StopInfo;
- friend class Target;
- friend class ThreadList;
+class Process : public std::enable_shared_from_this<Process>,
+ public ProcessProperties,
+ public UserID,
+ public Broadcaster,
+ public ExecutionContextScope,
+ public PluginInterface {
+ friend class FunctionCaller; // For WaitForStateChangeEventsPrivate
+ friend class Debugger; // For PopProcessIOHandler and ProcessIOHandlerIsActive
+ friend class ProcessEventData;
+ friend class StopInfo;
+ friend class Target;
+ friend class ThreadList;
public:
- //------------------------------------------------------------------
- /// Broadcaster event bits definitions.
- //------------------------------------------------------------------
- enum
- {
- eBroadcastBitStateChanged = (1 << 0),
- eBroadcastBitInterrupt = (1 << 1),
- eBroadcastBitSTDOUT = (1 << 2),
- eBroadcastBitSTDERR = (1 << 3),
- eBroadcastBitProfileData = (1 << 4)
- };
-
- enum
- {
- eBroadcastInternalStateControlStop = (1<<0),
- eBroadcastInternalStateControlPause = (1<<1),
- eBroadcastInternalStateControlResume = (1<<2)
- };
-
- //------------------------------------------------------------------
- /// Process warning types.
- //------------------------------------------------------------------
- enum Warnings
- {
- eWarningsOptimization = 1
- };
-
- typedef Range<lldb::addr_t, lldb::addr_t> LoadRange;
- // We use a read/write lock to allow on or more clients to
- // access the process state while the process is stopped (reader).
- // We lock the write lock to control access to the process
- // while it is running (readers, or clients that want the process
- // stopped can block waiting for the process to stop, or just
- // try to lock it to see if they can immediately access the stopped
- // process. If the try read lock fails, then the process is running.
- typedef ProcessRunLock::ProcessRunLocker StopLocker;
-
- // These two functions fill out the Broadcaster interface:
-
- static ConstString &GetStaticBroadcasterClass ();
-
- ConstString &GetBroadcasterClass() const override
- {
- return GetStaticBroadcasterClass();
- }
-
- //------------------------------------------------------------------
- /// A notification structure that can be used by clients to listen
- /// for changes in a process's lifetime.
- ///
- /// @see RegisterNotificationCallbacks (const Notifications&)
- /// @see UnregisterNotificationCallbacks (const Notifications&)
- //------------------------------------------------------------------
+ //------------------------------------------------------------------
+ /// Broadcaster event bits definitions.
+ //------------------------------------------------------------------
+ enum {
+ eBroadcastBitStateChanged = (1 << 0),
+ eBroadcastBitInterrupt = (1 << 1),
+ eBroadcastBitSTDOUT = (1 << 2),
+ eBroadcastBitSTDERR = (1 << 3),
+ eBroadcastBitProfileData = (1 << 4),
+ eBroadcastBitStructuredData = (1 << 5),
+ };
+
+ enum {
+ eBroadcastInternalStateControlStop = (1 << 0),
+ eBroadcastInternalStateControlPause = (1 << 1),
+ eBroadcastInternalStateControlResume = (1 << 2)
+ };
+
+ //------------------------------------------------------------------
+ /// Process warning types.
+ //------------------------------------------------------------------
+ enum Warnings { eWarningsOptimization = 1 };
+
+ typedef Range<lldb::addr_t, lldb::addr_t> LoadRange;
+ // We use a read/write lock to allow on or more clients to
+ // access the process state while the process is stopped (reader).
+ // We lock the write lock to control access to the process
+ // while it is running (readers, or clients that want the process
+ // stopped can block waiting for the process to stop, or just
+ // try to lock it to see if they can immediately access the stopped
+ // process. If the try read lock fails, then the process is running.
+ typedef ProcessRunLock::ProcessRunLocker StopLocker;
+
+ // These two functions fill out the Broadcaster interface:
+
+ static ConstString &GetStaticBroadcasterClass();
+
+ ConstString &GetBroadcasterClass() const override {
+ return GetStaticBroadcasterClass();
+ }
+
+//------------------------------------------------------------------
+/// A notification structure that can be used by clients to listen
+/// for changes in a process's lifetime.
+///
+/// @see RegisterNotificationCallbacks (const Notifications&)
+/// @see UnregisterNotificationCallbacks (const Notifications&)
+//------------------------------------------------------------------
#ifndef SWIG
- typedef struct
- {
- void *baton;
- void (*initialize)(void *baton, Process *process);
- void (*process_state_changed) (void *baton, Process *process, lldb::StateType state);
- } Notifications;
-
- class ProcessEventData :
- public EventData
- {
- friend class Process;
-
- public:
- ProcessEventData ();
- ProcessEventData (const lldb::ProcessSP &process, lldb::StateType state);
-
- ~ProcessEventData() override;
-
- static const ConstString &
- GetFlavorString ();
-
- const ConstString &
- GetFlavor() const override;
-
- lldb::ProcessSP
- GetProcessSP() const
- {
- return m_process_wp.lock();
- }
-
- lldb::StateType
- GetState() const
- {
- return m_state;
- }
- bool
- GetRestarted () const
- {
- return m_restarted;
- }
-
- size_t
- GetNumRestartedReasons ()
- {
- return m_restarted_reasons.size();
- }
-
- const char *
- GetRestartedReasonAtIndex(size_t idx)
- {
- return ((idx < m_restarted_reasons.size()) ? m_restarted_reasons[idx].c_str() : nullptr);
- }
-
- bool
- GetInterrupted () const
- {
- return m_interrupted;
- }
-
- void
- Dump(Stream *s) const override;
-
- void
- DoOnRemoval(Event *event_ptr) override;
-
- static const Process::ProcessEventData *
- GetEventDataFromEvent (const Event *event_ptr);
-
- static lldb::ProcessSP
- GetProcessFromEvent (const Event *event_ptr);
-
- static lldb::StateType
- GetStateFromEvent (const Event *event_ptr);
-
- static bool
- GetRestartedFromEvent (const Event *event_ptr);
-
- static size_t
- GetNumRestartedReasons(const Event *event_ptr);
-
- static const char *
- GetRestartedReasonAtIndex(const Event *event_ptr, size_t idx);
-
- static void
- AddRestartedReason (Event *event_ptr, const char *reason);
-
- static void
- SetRestartedInEvent (Event *event_ptr, bool new_value);
-
- static bool
- GetInterruptedFromEvent (const Event *event_ptr);
-
- static void
- SetInterruptedInEvent (Event *event_ptr, bool new_value);
-
- static bool
- SetUpdateStateOnRemoval (Event *event_ptr);
-
- private:
- void
- SetUpdateStateOnRemoval()
- {
- m_update_state++;
- }
-
- void
- SetRestarted (bool new_value)
- {
- m_restarted = new_value;
- }
-
- void
- SetInterrupted (bool new_value)
- {
- m_interrupted = new_value;
- }
-
- void
- AddRestartedReason (const char *reason)
- {
- m_restarted_reasons.push_back(reason);
- }
-
- lldb::ProcessWP m_process_wp;
- lldb::StateType m_state;
- std::vector<std::string> m_restarted_reasons;
- bool m_restarted; // For "eStateStopped" events, this is true if the target was automatically restarted.
- int m_update_state;
- bool m_interrupted;
-
- DISALLOW_COPY_AND_ASSIGN (ProcessEventData);
- };
-#endif // SWIG
+ typedef struct {
+ void *baton;
+ void (*initialize)(void *baton, Process *process);
+ void (*process_state_changed)(void *baton, Process *process,
+ lldb::StateType state);
+ } Notifications;
- //------------------------------------------------------------------
- /// Construct with a shared pointer to a target, and the Process listener.
- /// Uses the Host UnixSignalsSP by default.
- //------------------------------------------------------------------
- Process(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp);
-
- //------------------------------------------------------------------
- /// Construct with a shared pointer to a target, the Process listener,
- /// and the appropriate UnixSignalsSP for the process.
- //------------------------------------------------------------------
- Process(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const lldb::UnixSignalsSP &unix_signals_sp);
-
- //------------------------------------------------------------------
- /// Destructor.
- ///
- /// The destructor is virtual since this class is designed to be
- /// inherited from by the plug-in instance.
- //------------------------------------------------------------------
- ~Process() override;
-
- static void
- SettingsInitialize ();
-
- static void
- SettingsTerminate ();
-
- static const ProcessPropertiesSP &
- GetGlobalProperties();
-
- //------------------------------------------------------------------
- /// Find a Process plug-in that can debug \a module using the
- /// currently selected architecture.
- ///
- /// Scans all loaded plug-in interfaces that implement versions of
- /// the Process plug-in interface and returns the first instance
- /// that can debug the file.
- ///
- /// @param[in] module_sp
- /// The module shared pointer that this process will debug.
- ///
- /// @param[in] plugin_name
- /// If nullptr, select the best plug-in for the binary. If non-nullptr
- /// then look for a plugin whose PluginInfo's name matches
- /// this string.
- ///
- /// @see Process::CanDebug ()
- //------------------------------------------------------------------
- static lldb::ProcessSP
- FindPlugin (lldb::TargetSP target_sp,
- const char *plugin_name,
- lldb::ListenerSP listener_sp,
- const FileSpec *crash_file_path);
-
- //------------------------------------------------------------------
- /// Static function that can be used with the \b host function
- /// Host::StartMonitoringChildProcess ().
- ///
- /// This function can be used by lldb_private::Process subclasses
- /// when they want to watch for a local process and have its exit
- /// status automatically set when the host child process exits.
- /// Subclasses should call Host::StartMonitoringChildProcess ()
- /// with:
- /// callback = Process::SetHostProcessExitStatus
- /// pid = Process::GetID()
- /// monitor_signals = false
- //------------------------------------------------------------------
- static bool
- SetProcessExitStatus(lldb::pid_t pid, // The process ID we want to monitor
- bool exited,
- int signo, // Zero for no signal
- int status); // Exit value of process if signal is zero
-
- lldb::ByteOrder
- GetByteOrder () const;
-
- uint32_t
- GetAddressByteSize () const;
-
- uint32_t
- GetUniqueID() const
- {
- return m_process_unique_id;
- }
+ class ProcessEventData : public EventData {
+ friend class Process;
- //------------------------------------------------------------------
- /// Check if a plug-in instance can debug the file in \a module.
- ///
- /// Each plug-in is given a chance to say whether it can debug
- /// the file in \a module. If the Process plug-in instance can
- /// debug a file on the current system, it should return \b true.
- ///
- /// @return
- /// Returns \b true if this Process plug-in instance can
- /// debug the executable, \b false otherwise.
- //------------------------------------------------------------------
- virtual bool
- CanDebug (lldb::TargetSP target,
- bool plugin_specified_by_name) = 0;
-
- //------------------------------------------------------------------
- /// This object is about to be destroyed, do any necessary cleanup.
- ///
- /// Subclasses that override this method should always call this
- /// superclass method.
- //------------------------------------------------------------------
- virtual void
- Finalize();
-
- //------------------------------------------------------------------
- /// Return whether this object is valid (i.e. has not been finalized.)
- ///
- /// @return
- /// Returns \b true if this Process has not been finalized
- /// and \b false otherwise.
- //------------------------------------------------------------------
- bool
- IsValid() const
- {
- return !m_finalize_called;
- }
+ public:
+ ProcessEventData();
+ ProcessEventData(const lldb::ProcessSP &process, lldb::StateType state);
- //------------------------------------------------------------------
- /// Return a multi-word command object that can be used to expose
- /// plug-in specific commands.
- ///
- /// This object will be used to resolve plug-in commands and can be
- /// triggered by a call to:
- ///
- /// (lldb) process commmand <args>
- ///
- /// @return
- /// A CommandObject which can be one of the concrete subclasses
- /// of CommandObject like CommandObjectRaw, CommandObjectParsed,
- /// or CommandObjectMultiword.
- //------------------------------------------------------------------
- virtual CommandObject *
- GetPluginCommandObject()
- {
- return nullptr;
- }
+ ~ProcessEventData() override;
- //------------------------------------------------------------------
- /// Launch a new process.
- ///
- /// Launch a new process by spawning a new process using the
- /// target object's executable module's file as the file to launch.
- ///
- /// This function is not meant to be overridden by Process
- /// subclasses. It will first call Process::WillLaunch (Module *)
- /// and if that returns \b true, Process::DoLaunch (Module*,
- /// char const *[],char const *[],const char *,const char *,
- /// const char *) will be called to actually do the launching. If
- /// DoLaunch returns \b true, then Process::DidLaunch() will be
- /// called.
- ///
- /// @param[in] launch_info
- /// Details regarding the environment, STDIN/STDOUT/STDERR
- /// redirection, working path, etc. related to the requested launch.
- ///
- /// @return
- /// An error object. Call GetID() to get the process ID if
- /// the error object is success.
- //------------------------------------------------------------------
- virtual Error
- Launch (ProcessLaunchInfo &launch_info);
-
- virtual Error
- LoadCore ();
-
- virtual Error
- DoLoadCore ()
- {
- Error error;
- error.SetErrorStringWithFormat("error: %s does not support loading core files.", GetPluginName().GetCString());
- return error;
- }
+ static const ConstString &GetFlavorString();
- //------------------------------------------------------------------
- /// Get the dynamic loader plug-in for this process.
- ///
- /// The default action is to let the DynamicLoader plug-ins check
- /// the main executable and the DynamicLoader will select itself
- /// automatically. Subclasses can override this if inspecting the
- /// executable is not desired, or if Process subclasses can only
- /// use a specific DynamicLoader plug-in.
- //------------------------------------------------------------------
- virtual DynamicLoader *
- GetDynamicLoader ();
-
- //------------------------------------------------------------------
- // Returns AUXV structure found in many ELF-based environments.
- //
- // The default action is to return an empty data buffer.
- //
- // @return
- // A data buffer containing the contents of the AUXV data.
- //------------------------------------------------------------------
- virtual const lldb::DataBufferSP
- GetAuxvData();
-
- //------------------------------------------------------------------
- /// Sometimes processes know how to retrieve and load shared libraries.
- /// This is normally done by DynamicLoader plug-ins, but sometimes the
- /// connection to the process allows retrieving this information. The
- /// dynamic loader plug-ins can use this function if they can't
- /// determine the current shared library load state.
- ///
- /// @return
- /// The number of shared libraries that were loaded
- //------------------------------------------------------------------
- virtual size_t
- LoadModules ()
- {
- return 0;
- }
+ const ConstString &GetFlavor() const override;
- virtual size_t
- LoadModules (LoadedModuleInfoList &)
- {
- return 0;
- }
+ lldb::ProcessSP GetProcessSP() const { return m_process_wp.lock(); }
-protected:
- virtual JITLoaderList &
- GetJITLoaders ();
+ lldb::StateType GetState() const { return m_state; }
+ bool GetRestarted() const { return m_restarted; }
-public:
- //------------------------------------------------------------------
- /// Get the system runtime plug-in for this process.
- ///
- /// @return
- /// Returns a pointer to the SystemRuntime plugin for this Process
- /// if one is available. Else returns nullptr.
- //------------------------------------------------------------------
- virtual SystemRuntime *
- GetSystemRuntime ();
-
- //------------------------------------------------------------------
- /// Attach to an existing process using the process attach info.
- ///
- /// This function is not meant to be overridden by Process
- /// subclasses. It will first call WillAttach (lldb::pid_t)
- /// or WillAttach (const char *), and if that returns \b
- /// true, DoAttach (lldb::pid_t) or DoAttach (const char *) will
- /// be called to actually do the attach. If DoAttach returns \b
- /// true, then Process::DidAttach() will be called.
- ///
- /// @param[in] pid
- /// The process ID that we should attempt to attach to.
- ///
- /// @return
- /// Returns \a pid if attaching was successful, or
- /// LLDB_INVALID_PROCESS_ID if attaching fails.
- //------------------------------------------------------------------
- virtual Error
- Attach (ProcessAttachInfo &attach_info);
-
- //------------------------------------------------------------------
- /// Attach to a remote system via a URL
- ///
- /// @param[in] strm
- /// A stream where output intended for the user
- /// (if the driver has a way to display that) generated during
- /// the connection. This may be nullptr if no output is needed.A
- ///
- /// @param[in] remote_url
- /// The URL format that we are connecting to.
- ///
- /// @return
- /// Returns an error object.
- //------------------------------------------------------------------
- virtual Error
- ConnectRemote (Stream *strm, const char *remote_url);
-
- bool
- GetShouldDetach () const
- {
- return m_should_detach;
- }
+ size_t GetNumRestartedReasons() { return m_restarted_reasons.size(); }
- void
- SetShouldDetach (bool b)
- {
- m_should_detach = b;
+ const char *GetRestartedReasonAtIndex(size_t idx) {
+ return ((idx < m_restarted_reasons.size())
+ ? m_restarted_reasons[idx].c_str()
+ : nullptr);
}
- //------------------------------------------------------------------
- /// Get the image information address for the current process.
- ///
- /// Some runtimes have system functions that can help dynamic
- /// loaders locate the dynamic loader information needed to observe
- /// shared libraries being loaded or unloaded. This function is
- /// in the Process interface (as opposed to the DynamicLoader
- /// interface) to ensure that remote debugging can take advantage of
- /// this functionality.
- ///
- /// @return
- /// The address of the dynamic loader information, or
- /// LLDB_INVALID_ADDRESS if this is not supported by this
- /// interface.
- //------------------------------------------------------------------
- virtual lldb::addr_t
- GetImageInfoAddress ();
-
- //------------------------------------------------------------------
- /// Called when the process is about to broadcast a public stop.
- ///
- /// There are public and private stops. Private stops are when the
- /// process is doing things like stepping and the client doesn't
- /// need to know about starts and stop that implement a thread plan.
- /// Single stepping over a source line in code might end up being
- /// implemented by one or more process starts and stops. Public stops
- /// are when clients will be notified that the process is stopped.
- /// These events typically trigger UI updates (thread stack frames to
- /// be displayed, variables to be displayed, and more). This function
- /// can be overriden and allows process subclasses to do something
- /// before the eBroadcastBitStateChanged event is sent to public
- /// clients.
- //------------------------------------------------------------------
- virtual void
- WillPublicStop ()
- {
- }
+ bool GetInterrupted() const { return m_interrupted; }
- //------------------------------------------------------------------
- /// Register for process and thread notifications.
- ///
- /// Clients can register notification callbacks by filling out a
- /// Process::Notifications structure and calling this function.
- ///
- /// @param[in] callbacks
- /// A structure that contains the notification baton and
- /// callback functions.
- ///
- /// @see Process::Notifications
- //------------------------------------------------------------------
-#ifndef SWIG
- void
- RegisterNotificationCallbacks (const Process::Notifications& callbacks);
-#endif
+ void Dump(Stream *s) const override;
- //------------------------------------------------------------------
- /// Unregister for process and thread notifications.
- ///
- /// Clients can unregister notification callbacks by passing a copy of
- /// the original baton and callbacks in \a callbacks.
- ///
- /// @param[in] callbacks
- /// A structure that contains the notification baton and
- /// callback functions.
- ///
- /// @return
- /// Returns \b true if the notification callbacks were
- /// successfully removed from the process, \b false otherwise.
- ///
- /// @see Process::Notifications
- //------------------------------------------------------------------
-#ifndef SWIG
- bool
- UnregisterNotificationCallbacks (const Process::Notifications& callbacks);
-#endif
+ void DoOnRemoval(Event *event_ptr) override;
- //==================================================================
- // Built in Process Control functions
- //==================================================================
- //------------------------------------------------------------------
- /// Resumes all of a process's threads as configured using the
- /// Thread run control functions.
- ///
- /// Threads for a process should be updated with one of the run
- /// control actions (resume, step, or suspend) that they should take
- /// when the process is resumed. If no run control action is given
- /// to a thread it will be resumed by default.
- ///
- /// This function is not meant to be overridden by Process
- /// subclasses. This function will take care of disabling any
- /// breakpoints that threads may be stopped at, single stepping, and
- /// re-enabling breakpoints, and enabling the basic flow control
- /// that the plug-in instances need not worry about.
- ///
- /// N.B. This function also sets the Write side of the Run Lock,
- /// which is unset when the corresponding stop event is pulled off
- /// the Public Event Queue. If you need to resume the process without
- /// setting the Run Lock, use PrivateResume (though you should only do
- /// that from inside the Process class.
- ///
- /// @return
- /// Returns an error object.
- ///
- /// @see Thread:Resume()
- /// @see Thread:Step()
- /// @see Thread:Suspend()
- //------------------------------------------------------------------
- Error
- Resume();
-
- Error
- ResumeSynchronous (Stream *stream);
-
- //------------------------------------------------------------------
- /// Halts a running process.
- ///
- /// This function is not meant to be overridden by Process
- /// subclasses.
- /// If the process is successfully halted, a eStateStopped
- /// process event with GetInterrupted will be broadcast. If false, we will
- /// halt the process with no events generated by the halt.
- ///
- /// @param[in] clear_thread_plans
- /// If true, when the process stops, clear all thread plans.
- ///
- /// @param[in] use_run_lock
- /// Whether to release the run lock after the stop.
- ///
- /// @return
- /// Returns an error object. If the error is empty, the process is halted.
- /// otherwise the halt has failed.
- //------------------------------------------------------------------
- Error
- Halt (bool clear_thread_plans = false, bool use_run_lock = true);
-
- //------------------------------------------------------------------
- /// Detaches from a running or stopped process.
- ///
- /// This function is not meant to be overridden by Process
- /// subclasses.
- ///
- /// @param[in] keep_stopped
- /// If true, don't resume the process on detach.
- ///
- /// @return
- /// Returns an error object.
- //------------------------------------------------------------------
- Error
- Detach (bool keep_stopped);
-
- //------------------------------------------------------------------
- /// Kills the process and shuts down all threads that were spawned
- /// to track and monitor the process.
- ///
- /// This function is not meant to be overridden by Process
- /// subclasses.
- ///
- /// @param[in] force_kill
- /// Whether lldb should force a kill (instead of a detach) from
- /// the inferior process. Normally if lldb launched a binary and
- /// Destory is called, lldb kills it. If lldb attached to a
- /// running process and Destory is called, lldb detaches. If
- /// this behavior needs to be over-ridden, this is the bool that
- /// can be used.
- ///
- /// @return
- /// Returns an error object.
- //------------------------------------------------------------------
- Error
- Destroy(bool force_kill);
-
- //------------------------------------------------------------------
- /// Sends a process a UNIX signal \a signal.
- ///
- /// This function is not meant to be overridden by Process
- /// subclasses.
- ///
- /// @return
- /// Returns an error object.
- //------------------------------------------------------------------
- Error
- Signal (int signal);
-
- void
- SetUnixSignals(lldb::UnixSignalsSP &&signals_sp);
-
- const lldb::UnixSignalsSP &
- GetUnixSignals();
-
- //==================================================================
- // Plug-in Process Control Overrides
- //==================================================================
-
- //------------------------------------------------------------------
- /// Called before attaching to a process.
- ///
- /// Allow Process plug-ins to execute some code before attaching a
- /// process.
- ///
- /// @return
- /// Returns an error object.
- //------------------------------------------------------------------
- virtual Error
- WillAttachToProcessWithID (lldb::pid_t pid)
- {
- return Error();
- }
+ static const Process::ProcessEventData *
+ GetEventDataFromEvent(const Event *event_ptr);
- //------------------------------------------------------------------
- /// Called before attaching to a process.
- ///
- /// Allow Process plug-ins to execute some code before attaching a
- /// process.
- ///
- /// @return
- /// Returns an error object.
- //------------------------------------------------------------------
- virtual Error
- WillAttachToProcessWithName (const char *process_name, bool wait_for_launch)
- {
- return Error();
- }
+ static lldb::ProcessSP GetProcessFromEvent(const Event *event_ptr);
- //------------------------------------------------------------------
- /// Attach to a remote system via a URL
- ///
- /// @param[in] strm
- /// A stream where output intended for the user
- /// (if the driver has a way to display that) generated during
- /// the connection. This may be nullptr if no output is needed.A
- ///
- /// @param[in] remote_url
- /// The URL format that we are connecting to.
- ///
- /// @return
- /// Returns an error object.
- //------------------------------------------------------------------
- virtual Error
- DoConnectRemote (Stream *strm, const char *remote_url)
- {
- Error error;
- error.SetErrorString ("remote connections are not supported");
- return error;
- }
+ static lldb::StateType GetStateFromEvent(const Event *event_ptr);
- //------------------------------------------------------------------
- /// Attach to an existing process using a process ID.
- ///
- /// @param[in] pid
- /// The process ID that we should attempt to attach to.
- ///
- /// @param[in] attach_info
- /// Information on how to do the attach. For example, GetUserID()
- /// will return the uid to attach as.
- ///
- /// @return
- /// Returns a successful Error attaching was successful, or
- /// an appropriate (possibly platform-specific) error code if
- /// attaching fails.
- /// hanming : need flag
- //------------------------------------------------------------------
- virtual Error
- DoAttachToProcessWithID (lldb::pid_t pid, const ProcessAttachInfo &attach_info)
- {
- Error error;
- error.SetErrorStringWithFormat("error: %s does not support attaching to a process by pid", GetPluginName().GetCString());
- return error;
- }
+ static bool GetRestartedFromEvent(const Event *event_ptr);
- //------------------------------------------------------------------
- /// Attach to an existing process using a partial process name.
- ///
- /// @param[in] process_name
- /// The name of the process to attach to.
- ///
- /// @param[in] attach_info
- /// Information on how to do the attach. For example, GetUserID()
- /// will return the uid to attach as.
- ///
- /// @return
- /// Returns a successful Error attaching was successful, or
- /// an appropriate (possibly platform-specific) error code if
- /// attaching fails.
- //------------------------------------------------------------------
- virtual Error
- DoAttachToProcessWithName (const char *process_name, const ProcessAttachInfo &attach_info)
- {
- Error error;
- error.SetErrorString("attach by name is not supported");
- return error;
- }
+ static size_t GetNumRestartedReasons(const Event *event_ptr);
- //------------------------------------------------------------------
- /// Called after attaching a process.
- ///
- /// @param[in] process_arch
- /// If you can figure out the process architecture after attach, fill it in here.
- ///
- /// Allow Process plug-ins to execute some code after attaching to
- /// a process.
- //------------------------------------------------------------------
- virtual void
- DidAttach (ArchSpec &process_arch)
- {
- process_arch.Clear();
- }
+ static const char *GetRestartedReasonAtIndex(const Event *event_ptr,
+ size_t idx);
- //------------------------------------------------------------------
- /// Called after a process re-execs itself.
- ///
- /// Allow Process plug-ins to execute some code after a process has
- /// exec'ed itself. Subclasses typically should override DoDidExec()
- /// as the lldb_private::Process class needs to remove its dynamic
- /// loader, runtime, ABI and other plug-ins, as well as unload all
- /// shared libraries.
- //------------------------------------------------------------------
- virtual void
- DidExec ();
-
- //------------------------------------------------------------------
- /// Subclasses of Process should implement this function if they
- /// need to do anything after a process exec's itself.
- //------------------------------------------------------------------
- virtual void
- DoDidExec ()
- {
- }
+ static void AddRestartedReason(Event *event_ptr, const char *reason);
- //------------------------------------------------------------------
- /// Called before launching to a process.
- ///
- /// Allow Process plug-ins to execute some code before launching a
- /// process.
- ///
- /// @return
- /// Returns an error object.
- //------------------------------------------------------------------
- virtual Error
- WillLaunch (Module* module)
- {
- return Error();
- }
+ static void SetRestartedInEvent(Event *event_ptr, bool new_value);
- //------------------------------------------------------------------
- /// Launch a new process.
- ///
- /// Launch a new process by spawning a new process using
- /// \a exe_module's file as the file to launch. Launch details are
- /// provided in \a launch_info.
- ///
- /// @param[in] exe_module
- /// The module from which to extract the file specification and
- /// launch.
- ///
- /// @param[in] launch_info
- /// Details (e.g. arguments, stdio redirection, etc.) for the
- /// requested launch.
- ///
- /// @return
- /// An Error instance indicating success or failure of the
- /// operation.
- //------------------------------------------------------------------
- virtual Error
- DoLaunch (Module *exe_module,
- ProcessLaunchInfo &launch_info)
- {
- Error error;
- error.SetErrorStringWithFormat("error: %s does not support launching processes", GetPluginName().GetCString());
- return error;
- }
+ static bool GetInterruptedFromEvent(const Event *event_ptr);
- //------------------------------------------------------------------
- /// Called after launching a process.
- ///
- /// Allow Process plug-ins to execute some code after launching
- /// a process.
- //------------------------------------------------------------------
- virtual void
- DidLaunch () {}
-
- //------------------------------------------------------------------
- /// Called before resuming to a process.
- ///
- /// Allow Process plug-ins to execute some code before resuming a
- /// process.
- ///
- /// @return
- /// Returns an error object.
- //------------------------------------------------------------------
- virtual Error
- WillResume () { return Error(); }
-
- //------------------------------------------------------------------
- /// Resumes all of a process's threads as configured using the
- /// Thread run control functions.
- ///
- /// Threads for a process should be updated with one of the run
- /// control actions (resume, step, or suspend) that they should take
- /// when the process is resumed. If no run control action is given
- /// to a thread it will be resumed by default.
- ///
- /// @return
- /// Returns \b true if the process successfully resumes using
- /// the thread run control actions, \b false otherwise.
- ///
- /// @see Thread:Resume()
- /// @see Thread:Step()
- /// @see Thread:Suspend()
- //------------------------------------------------------------------
- virtual Error
- DoResume ()
- {
- Error error;
- error.SetErrorStringWithFormat("error: %s does not support resuming processes", GetPluginName().GetCString());
- return error;
- }
+ static void SetInterruptedInEvent(Event *event_ptr, bool new_value);
- //------------------------------------------------------------------
- /// Called after resuming a process.
- ///
- /// Allow Process plug-ins to execute some code after resuming
- /// a process.
- //------------------------------------------------------------------
- virtual void
- DidResume () {}
-
- //------------------------------------------------------------------
- /// Called before halting to a process.
- ///
- /// Allow Process plug-ins to execute some code before halting a
- /// process.
- ///
- /// @return
- /// Returns an error object.
- //------------------------------------------------------------------
- virtual Error
- WillHalt () { return Error(); }
-
- //------------------------------------------------------------------
- /// Halts a running process.
- ///
- /// DoHalt must produce one and only one stop StateChanged event if it actually
- /// stops the process. If the stop happens through some natural event (for
- /// instance a SIGSTOP), then forwarding that event will do. Otherwise, you must
- /// generate the event manually. This function is called from the context of the
- /// private state thread.
- ///
- /// @param[out] caused_stop
- /// If true, then this Halt caused the stop, otherwise, the
- /// process was already stopped.
- ///
- /// @return
- /// Returns \b true if the process successfully halts, \b false
- /// otherwise.
- //------------------------------------------------------------------
- virtual Error
- DoHalt (bool &caused_stop)
- {
- Error error;
- error.SetErrorStringWithFormat("error: %s does not support halting processes", GetPluginName().GetCString());
- return error;
- }
+ static bool SetUpdateStateOnRemoval(Event *event_ptr);
- //------------------------------------------------------------------
- /// Called after halting a process.
- ///
- /// Allow Process plug-ins to execute some code after halting
- /// a process.
- //------------------------------------------------------------------
- virtual void
- DidHalt () {}
-
- //------------------------------------------------------------------
- /// Called before detaching from a process.
- ///
- /// Allow Process plug-ins to execute some code before detaching
- /// from a process.
- ///
- /// @return
- /// Returns an error object.
- //------------------------------------------------------------------
- virtual Error
- WillDetach ()
- {
- return Error();
- }
+ private:
+ void SetUpdateStateOnRemoval() { m_update_state++; }
- //------------------------------------------------------------------
- /// Detaches from a running or stopped process.
- ///
- /// @return
- /// Returns \b true if the process successfully detaches, \b
- /// false otherwise.
- //------------------------------------------------------------------
- virtual Error
- DoDetach (bool keep_stopped)
- {
- Error error;
- error.SetErrorStringWithFormat("error: %s does not support detaching from processes", GetPluginName().GetCString());
- return error;
- }
+ void SetRestarted(bool new_value) { m_restarted = new_value; }
- //------------------------------------------------------------------
- /// Called after detaching from a process.
- ///
- /// Allow Process plug-ins to execute some code after detaching
- /// from a process.
- //------------------------------------------------------------------
- virtual void
- DidDetach () {}
-
- virtual bool
- DetachRequiresHalt() { return false; }
-
- //------------------------------------------------------------------
- /// Called before sending a signal to a process.
- ///
- /// Allow Process plug-ins to execute some code before sending a
- /// signal to a process.
- ///
- /// @return
- /// Returns no error if it is safe to proceed with a call to
- /// Process::DoSignal(int), otherwise an error describing what
- /// prevents the signal from being sent.
- //------------------------------------------------------------------
- virtual Error
- WillSignal () { return Error(); }
-
- //------------------------------------------------------------------
- /// Sends a process a UNIX signal \a signal.
- ///
- /// @return
- /// Returns an error object.
- //------------------------------------------------------------------
- virtual Error
- DoSignal (int signal)
- {
- Error error;
- error.SetErrorStringWithFormat("error: %s does not support sending signals to processes", GetPluginName().GetCString());
- return error;
- }
+ void SetInterrupted(bool new_value) { m_interrupted = new_value; }
- virtual Error
- WillDestroy () { return Error(); }
-
- virtual Error
- DoDestroy () = 0;
-
- virtual void
- DidDestroy () { }
-
- virtual bool
- DestroyRequiresHalt() { return true; }
-
- //------------------------------------------------------------------
- /// Called after sending a signal to a process.
- ///
- /// Allow Process plug-ins to execute some code after sending a
- /// signal to a process.
- //------------------------------------------------------------------
- virtual void
- DidSignal () {}
-
- //------------------------------------------------------------------
- /// Currently called as part of ShouldStop.
- /// FIXME: Should really happen when the target stops before the
- /// event is taken from the queue...
- ///
- /// This callback is called as the event
- /// is about to be queued up to allow Process plug-ins to execute
- /// some code prior to clients being notified that a process was
- /// stopped. Common operations include updating the thread list,
- /// invalidating any thread state (registers, stack, etc) prior to
- /// letting the notification go out.
- ///
- //------------------------------------------------------------------
- virtual void
- RefreshStateAfterStop () = 0;
-
- //------------------------------------------------------------------
- /// Sometimes the connection to a process can detect the host OS
- /// version that the process is running on. The current platform
- /// should be checked first in case the platform is connected, but
- /// clients can fall back onto this function if the platform fails
- /// to identify the host OS version. The platform should be checked
- /// first in case you are running a simulator platform that might
- /// itself be running natively, but have different heuristics for
- /// figuring out which OS is is emulating.
- ///
- /// @param[out] major
- /// The major OS version, or UINT32_MAX if it can't be determined
- ///
- /// @param[out] minor
- /// The minor OS version, or UINT32_MAX if it can't be determined
- ///
- /// @param[out] update
- /// The update OS version, or UINT32_MAX if it can't be determined
- ///
- /// @return
- /// Returns \b true if the host OS version info was filled in
- /// and \b false otherwise.
- //------------------------------------------------------------------
- virtual bool
- GetHostOSVersion(uint32_t &major,
- uint32_t &minor,
- uint32_t &update)
- {
- major = UINT32_MAX;
- minor = UINT32_MAX;
- update = UINT32_MAX;
- return false;
+ void AddRestartedReason(const char *reason) {
+ m_restarted_reasons.push_back(reason);
}
+ lldb::ProcessWP m_process_wp;
+ lldb::StateType m_state;
+ std::vector<std::string> m_restarted_reasons;
+ bool m_restarted; // For "eStateStopped" events, this is true if the target
+ // was automatically restarted.
+ int m_update_state;
+ bool m_interrupted;
- //------------------------------------------------------------------
- /// Get the target object pointer for this module.
- ///
- /// @return
- /// A Target object pointer to the target that owns this
- /// module.
- //------------------------------------------------------------------
- Target &
- GetTarget ()
- {
- return *m_target_sp.lock();
- }
-
- //------------------------------------------------------------------
- /// Get the const target object pointer for this module.
- ///
- /// @return
- /// A const Target object pointer to the target that owns this
- /// module.
- //------------------------------------------------------------------
- const Target &
- GetTarget () const
- {
- return *m_target_sp.lock();
- }
+ DISALLOW_COPY_AND_ASSIGN(ProcessEventData);
+ };
+#endif // SWIG
- //------------------------------------------------------------------
- /// Flush all data in the process.
- ///
- /// Flush the memory caches, all threads, and any other cached data
- /// in the process.
- ///
- /// This function can be called after a world changing event like
- /// adding a new symbol file, or after the process makes a large
- /// context switch (from boot ROM to booted into an OS).
- //------------------------------------------------------------------
- void
- Flush ();
-
- //------------------------------------------------------------------
- /// Get accessor for the current process state.
- ///
- /// @return
- /// The current state of the process.
- ///
- /// @see lldb::StateType
- //------------------------------------------------------------------
- lldb::StateType
- GetState ();
-
- lldb::ExpressionResults
- RunThreadPlan(ExecutionContext &exe_ctx, lldb::ThreadPlanSP &thread_plan_sp,
- const EvaluateExpressionOptions &options, DiagnosticManager &diagnostic_manager);
-
- static const char *
- ExecutionResultAsCString(lldb::ExpressionResults result);
-
- void
- GetStatus (Stream &ostrm);
-
- size_t
- GetThreadStatus (Stream &ostrm,
- bool only_threads_with_stop_reason,
- uint32_t start_frame,
- uint32_t num_frames,
- uint32_t num_frames_with_source);
-
- void
- SendAsyncInterrupt ();
-
- //------------------------------------------------------------------
- // Notify this process class that modules got loaded.
- //
- // If subclasses override this method, they must call this version
- // before doing anything in the subclass version of the function.
- //------------------------------------------------------------------
- virtual void
- ModulesDidLoad (ModuleList &module_list);
-
- //------------------------------------------------------------------
- /// Retrieve the list of shared libraries that are loaded for this process
- ///
- /// For certain platforms, the time it takes for the DynamicLoader plugin to
- /// read all of the shared libraries out of memory over a slow communication
- /// channel may be too long. In that instance, the gdb-remote stub may be
- /// able to retrieve the necessary information about the solibs out of memory
- /// and return a concise summary sufficient for the DynamicLoader plugin.
- ///
- /// @param [in] image_list_address
- /// The address where the table of shared libraries is stored in memory,
- /// if that is appropriate for this platform. Else this may be
- /// passed as LLDB_INVALID_ADDRESS.
- ///
- /// @param [in] image_count
- /// The number of shared libraries that are present in this process, if
- /// that is appropriate for this platofrm Else this may be passed as
- /// LLDB_INVALID_ADDRESS.
- ///
- /// @return
- /// A StructureDataSP object which, if non-empty, will contain the
- /// information the DynamicLoader needs to get the initial scan of
- /// solibs resolved.
- //------------------------------------------------------------------
- virtual lldb_private::StructuredData::ObjectSP
- GetLoadedDynamicLibrariesInfos (lldb::addr_t image_list_address, lldb::addr_t image_count)
- {
- return StructuredData::ObjectSP();
- }
+ //------------------------------------------------------------------
+ /// Construct with a shared pointer to a target, and the Process listener.
+ /// Uses the Host UnixSignalsSP by default.
+ //------------------------------------------------------------------
+ Process(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp);
+
+ //------------------------------------------------------------------
+ /// Construct with a shared pointer to a target, the Process listener,
+ /// and the appropriate UnixSignalsSP for the process.
+ //------------------------------------------------------------------
+ Process(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
+ const lldb::UnixSignalsSP &unix_signals_sp);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ ///
+ /// The destructor is virtual since this class is designed to be
+ /// inherited from by the plug-in instance.
+ //------------------------------------------------------------------
+ ~Process() override;
+
+ static void SettingsInitialize();
+
+ static void SettingsTerminate();
+
+ static const ProcessPropertiesSP &GetGlobalProperties();
+
+ //------------------------------------------------------------------
+ /// Find a Process plug-in that can debug \a module using the
+ /// currently selected architecture.
+ ///
+ /// Scans all loaded plug-in interfaces that implement versions of
+ /// the Process plug-in interface and returns the first instance
+ /// that can debug the file.
+ ///
+ /// @param[in] module_sp
+ /// The module shared pointer that this process will debug.
+ ///
+ /// @param[in] plugin_name
+ /// If nullptr, select the best plug-in for the binary. If non-nullptr
+ /// then look for a plugin whose PluginInfo's name matches
+ /// this string.
+ ///
+ /// @see Process::CanDebug ()
+ //------------------------------------------------------------------
+ static lldb::ProcessSP FindPlugin(lldb::TargetSP target_sp,
+ llvm::StringRef plugin_name,
+ lldb::ListenerSP listener_sp,
+ const FileSpec *crash_file_path);
+
+ //------------------------------------------------------------------
+ /// Static function that can be used with the \b host function
+ /// Host::StartMonitoringChildProcess ().
+ ///
+ /// This function can be used by lldb_private::Process subclasses
+ /// when they want to watch for a local process and have its exit
+ /// status automatically set when the host child process exits.
+ /// Subclasses should call Host::StartMonitoringChildProcess ()
+ /// with:
+ /// callback = Process::SetHostProcessExitStatus
+ /// pid = Process::GetID()
+ /// monitor_signals = false
+ //------------------------------------------------------------------
+ static bool
+ SetProcessExitStatus(lldb::pid_t pid, // The process ID we want to monitor
+ bool exited,
+ int signo, // Zero for no signal
+ int status); // Exit value of process if signal is zero
+
+ lldb::ByteOrder GetByteOrder() const;
+
+ uint32_t GetAddressByteSize() const;
+
+ uint32_t GetUniqueID() const { return m_process_unique_id; }
+
+ //------------------------------------------------------------------
+ /// Check if a plug-in instance can debug the file in \a module.
+ ///
+ /// Each plug-in is given a chance to say whether it can debug
+ /// the file in \a module. If the Process plug-in instance can
+ /// debug a file on the current system, it should return \b true.
+ ///
+ /// @return
+ /// Returns \b true if this Process plug-in instance can
+ /// debug the executable, \b false otherwise.
+ //------------------------------------------------------------------
+ virtual bool CanDebug(lldb::TargetSP target,
+ bool plugin_specified_by_name) = 0;
+
+ //------------------------------------------------------------------
+ /// This object is about to be destroyed, do any necessary cleanup.
+ ///
+ /// Subclasses that override this method should always call this
+ /// superclass method.
+ //------------------------------------------------------------------
+ virtual void Finalize();
+
+ //------------------------------------------------------------------
+ /// Return whether this object is valid (i.e. has not been finalized.)
+ ///
+ /// @return
+ /// Returns \b true if this Process has not been finalized
+ /// and \b false otherwise.
+ //------------------------------------------------------------------
+ bool IsValid() const { return !m_finalize_called; }
+
+ //------------------------------------------------------------------
+ /// Return a multi-word command object that can be used to expose
+ /// plug-in specific commands.
+ ///
+ /// This object will be used to resolve plug-in commands and can be
+ /// triggered by a call to:
+ ///
+ /// (lldb) process commmand <args>
+ ///
+ /// @return
+ /// A CommandObject which can be one of the concrete subclasses
+ /// of CommandObject like CommandObjectRaw, CommandObjectParsed,
+ /// or CommandObjectMultiword.
+ //------------------------------------------------------------------
+ virtual CommandObject *GetPluginCommandObject() { return nullptr; }
+
+ //------------------------------------------------------------------
+ /// Launch a new process.
+ ///
+ /// Launch a new process by spawning a new process using the
+ /// target object's executable module's file as the file to launch.
+ ///
+ /// This function is not meant to be overridden by Process
+ /// subclasses. It will first call Process::WillLaunch (Module *)
+ /// and if that returns \b true, Process::DoLaunch (Module*,
+ /// char const *[],char const *[],const char *,const char *,
+ /// const char *) will be called to actually do the launching. If
+ /// DoLaunch returns \b true, then Process::DidLaunch() will be
+ /// called.
+ ///
+ /// @param[in] launch_info
+ /// Details regarding the environment, STDIN/STDOUT/STDERR
+ /// redirection, working path, etc. related to the requested launch.
+ ///
+ /// @return
+ /// An error object. Call GetID() to get the process ID if
+ /// the error object is success.
+ //------------------------------------------------------------------
+ virtual Error Launch(ProcessLaunchInfo &launch_info);
+
+ virtual Error LoadCore();
+
+ virtual Error DoLoadCore() {
+ Error error;
+ error.SetErrorStringWithFormat(
+ "error: %s does not support loading core files.",
+ GetPluginName().GetCString());
+ return error;
+ }
+
+ //------------------------------------------------------------------
+ /// Get the dynamic loader plug-in for this process.
+ ///
+ /// The default action is to let the DynamicLoader plug-ins check
+ /// the main executable and the DynamicLoader will select itself
+ /// automatically. Subclasses can override this if inspecting the
+ /// executable is not desired, or if Process subclasses can only
+ /// use a specific DynamicLoader plug-in.
+ //------------------------------------------------------------------
+ virtual DynamicLoader *GetDynamicLoader();
+
+ //------------------------------------------------------------------
+ // Returns AUXV structure found in many ELF-based environments.
+ //
+ // The default action is to return an empty data buffer.
+ //
+ // @return
+ // A data buffer containing the contents of the AUXV data.
+ //------------------------------------------------------------------
+ virtual const lldb::DataBufferSP GetAuxvData();
+
+ //------------------------------------------------------------------
+ /// Sometimes processes know how to retrieve and load shared libraries.
+ /// This is normally done by DynamicLoader plug-ins, but sometimes the
+ /// connection to the process allows retrieving this information. The
+ /// dynamic loader plug-ins can use this function if they can't
+ /// determine the current shared library load state.
+ ///
+ /// @return
+ /// The number of shared libraries that were loaded
+ //------------------------------------------------------------------
+ virtual size_t LoadModules() { return 0; }
+
+ virtual size_t LoadModules(LoadedModuleInfoList &) { return 0; }
- //------------------------------------------------------------------
- /// Print a user-visible warning about a module being built with optimization
- ///
- /// Prints a async warning message to the user one time per Module
- /// where a function is found that was compiled with optimization, per
- /// Process.
- ///
- /// @param [in] sc
- /// A SymbolContext with eSymbolContextFunction and eSymbolContextModule
- /// pre-computed.
- //------------------------------------------------------------------
- void
- PrintWarningOptimization (const SymbolContext &sc);
-
- virtual bool
- GetProcessInfo(ProcessInstanceInfo &info);
+protected:
+ virtual JITLoaderList &GetJITLoaders();
public:
- //------------------------------------------------------------------
- /// Get the exit status for a process.
- ///
- /// @return
- /// The process's return code, or -1 if the current process
- /// state is not eStateExited.
- //------------------------------------------------------------------
- int
- GetExitStatus ();
-
- //------------------------------------------------------------------
- /// Get a textual description of what the process exited.
- ///
- /// @return
- /// The textual description of why the process exited, or nullptr
- /// if there is no description available.
- //------------------------------------------------------------------
- const char *
- GetExitDescription ();
-
- virtual void
- DidExit ()
- {
- }
-
- //------------------------------------------------------------------
- /// Get the Modification ID of the process.
- ///
- /// @return
- /// The modification ID of the process.
- //------------------------------------------------------------------
- ProcessModID
- GetModID () const
- {
- return m_mod_id;
- }
-
- const ProcessModID &
- GetModIDRef () const
- {
- return m_mod_id;
- }
-
- uint32_t
- GetStopID () const
- {
- return m_mod_id.GetStopID();
- }
-
- uint32_t
- GetResumeID () const
- {
- return m_mod_id.GetResumeID();
- }
-
- uint32_t
- GetLastUserExpressionResumeID () const
- {
- return m_mod_id.GetLastUserExpressionResumeID();
- }
-
- uint32_t
- GetLastNaturalStopID() const
- {
- return m_mod_id.GetLastNaturalStopID();
- }
+ //------------------------------------------------------------------
+ /// Get the system runtime plug-in for this process.
+ ///
+ /// @return
+ /// Returns a pointer to the SystemRuntime plugin for this Process
+ /// if one is available. Else returns nullptr.
+ //------------------------------------------------------------------
+ virtual SystemRuntime *GetSystemRuntime();
+
+ //------------------------------------------------------------------
+ /// Attach to an existing process using the process attach info.
+ ///
+ /// This function is not meant to be overridden by Process
+ /// subclasses. It will first call WillAttach (lldb::pid_t)
+ /// or WillAttach (const char *), and if that returns \b
+ /// true, DoAttach (lldb::pid_t) or DoAttach (const char *) will
+ /// be called to actually do the attach. If DoAttach returns \b
+ /// true, then Process::DidAttach() will be called.
+ ///
+ /// @param[in] pid
+ /// The process ID that we should attempt to attach to.
+ ///
+ /// @return
+ /// Returns \a pid if attaching was successful, or
+ /// LLDB_INVALID_PROCESS_ID if attaching fails.
+ //------------------------------------------------------------------
+ virtual Error Attach(ProcessAttachInfo &attach_info);
+
+ //------------------------------------------------------------------
+ /// Attach to a remote system via a URL
+ ///
+ /// @param[in] strm
+ /// A stream where output intended for the user
+ /// (if the driver has a way to display that) generated during
+ /// the connection. This may be nullptr if no output is needed.A
+ ///
+ /// @param[in] remote_url
+ /// The URL format that we are connecting to.
+ ///
+ /// @return
+ /// Returns an error object.
+ //------------------------------------------------------------------
+ virtual Error ConnectRemote(Stream *strm, llvm::StringRef remote_url);
+
+ bool GetShouldDetach() const { return m_should_detach; }
+
+ void SetShouldDetach(bool b) { m_should_detach = b; }
+
+ //------------------------------------------------------------------
+ /// Get the image information address for the current process.
+ ///
+ /// Some runtimes have system functions that can help dynamic
+ /// loaders locate the dynamic loader information needed to observe
+ /// shared libraries being loaded or unloaded. This function is
+ /// in the Process interface (as opposed to the DynamicLoader
+ /// interface) to ensure that remote debugging can take advantage of
+ /// this functionality.
+ ///
+ /// @return
+ /// The address of the dynamic loader information, or
+ /// LLDB_INVALID_ADDRESS if this is not supported by this
+ /// interface.
+ //------------------------------------------------------------------
+ virtual lldb::addr_t GetImageInfoAddress();
+
+ //------------------------------------------------------------------
+ /// Called when the process is about to broadcast a public stop.
+ ///
+ /// There are public and private stops. Private stops are when the
+ /// process is doing things like stepping and the client doesn't
+ /// need to know about starts and stop that implement a thread plan.
+ /// Single stepping over a source line in code might end up being
+ /// implemented by one or more process starts and stops. Public stops
+ /// are when clients will be notified that the process is stopped.
+ /// These events typically trigger UI updates (thread stack frames to
+ /// be displayed, variables to be displayed, and more). This function
+ /// can be overriden and allows process subclasses to do something
+ /// before the eBroadcastBitStateChanged event is sent to public
+ /// clients.
+ //------------------------------------------------------------------
+ virtual void WillPublicStop() {}
+
+//------------------------------------------------------------------
+/// Register for process and thread notifications.
+///
+/// Clients can register notification callbacks by filling out a
+/// Process::Notifications structure and calling this function.
+///
+/// @param[in] callbacks
+/// A structure that contains the notification baton and
+/// callback functions.
+///
+/// @see Process::Notifications
+//------------------------------------------------------------------
+#ifndef SWIG
+ void RegisterNotificationCallbacks(const Process::Notifications &callbacks);
+#endif
- lldb::EventSP
- GetStopEventForStopID (uint32_t stop_id) const
- {
- return m_mod_id.GetStopEventForStopID(stop_id);
- }
+//------------------------------------------------------------------
+/// Unregister for process and thread notifications.
+///
+/// Clients can unregister notification callbacks by passing a copy of
+/// the original baton and callbacks in \a callbacks.
+///
+/// @param[in] callbacks
+/// A structure that contains the notification baton and
+/// callback functions.
+///
+/// @return
+/// Returns \b true if the notification callbacks were
+/// successfully removed from the process, \b false otherwise.
+///
+/// @see Process::Notifications
+//------------------------------------------------------------------
+#ifndef SWIG
+ bool UnregisterNotificationCallbacks(const Process::Notifications &callbacks);
+#endif
- //------------------------------------------------------------------
- /// Set accessor for the process exit status (return code).
- ///
- /// Sometimes a child exits and the exit can be detected by global
- /// functions (signal handler for SIGCHLD for example). This
- /// accessor allows the exit status to be set from an external
- /// source.
- ///
- /// Setting this will cause a eStateExited event to be posted to
- /// the process event queue.
- ///
- /// @param[in] exit_status
- /// The value for the process's return code.
- ///
- /// @see lldb::StateType
- //------------------------------------------------------------------
- virtual bool
- SetExitStatus (int exit_status, const char *cstr);
-
- //------------------------------------------------------------------
- /// Check if a process is still alive.
- ///
- /// @return
- /// Returns \b true if the process is still valid, \b false
- /// otherwise.
- //------------------------------------------------------------------
- virtual bool
- IsAlive ();
-
- //------------------------------------------------------------------
- /// Before lldb detaches from a process, it warns the user that they are about to lose their debug session.
- /// In some cases, this warning doesn't need to be emitted -- for instance, with core file debugging where
- /// the user can reconstruct the "state" by simply re-running the debugger on the core file.
- ///
- /// @return
- // true if the user should be warned about detaching from this process.
- //------------------------------------------------------------------
- virtual bool
- WarnBeforeDetach () const
- {
- return true;
- }
+ //==================================================================
+ // Built in Process Control functions
+ //==================================================================
+ //------------------------------------------------------------------
+ /// Resumes all of a process's threads as configured using the
+ /// Thread run control functions.
+ ///
+ /// Threads for a process should be updated with one of the run
+ /// control actions (resume, step, or suspend) that they should take
+ /// when the process is resumed. If no run control action is given
+ /// to a thread it will be resumed by default.
+ ///
+ /// This function is not meant to be overridden by Process
+ /// subclasses. This function will take care of disabling any
+ /// breakpoints that threads may be stopped at, single stepping, and
+ /// re-enabling breakpoints, and enabling the basic flow control
+ /// that the plug-in instances need not worry about.
+ ///
+ /// N.B. This function also sets the Write side of the Run Lock,
+ /// which is unset when the corresponding stop event is pulled off
+ /// the Public Event Queue. If you need to resume the process without
+ /// setting the Run Lock, use PrivateResume (though you should only do
+ /// that from inside the Process class.
+ ///
+ /// @return
+ /// Returns an error object.
+ ///
+ /// @see Thread:Resume()
+ /// @see Thread:Step()
+ /// @see Thread:Suspend()
+ //------------------------------------------------------------------
+ Error Resume();
+
+ Error ResumeSynchronous(Stream *stream);
+
+ //------------------------------------------------------------------
+ /// Halts a running process.
+ ///
+ /// This function is not meant to be overridden by Process
+ /// subclasses.
+ /// If the process is successfully halted, a eStateStopped
+ /// process event with GetInterrupted will be broadcast. If false, we will
+ /// halt the process with no events generated by the halt.
+ ///
+ /// @param[in] clear_thread_plans
+ /// If true, when the process stops, clear all thread plans.
+ ///
+ /// @param[in] use_run_lock
+ /// Whether to release the run lock after the stop.
+ ///
+ /// @return
+ /// Returns an error object. If the error is empty, the process is
+ /// halted.
+ /// otherwise the halt has failed.
+ //------------------------------------------------------------------
+ Error Halt(bool clear_thread_plans = false, bool use_run_lock = true);
+
+ //------------------------------------------------------------------
+ /// Detaches from a running or stopped process.
+ ///
+ /// This function is not meant to be overridden by Process
+ /// subclasses.
+ ///
+ /// @param[in] keep_stopped
+ /// If true, don't resume the process on detach.
+ ///
+ /// @return
+ /// Returns an error object.
+ //------------------------------------------------------------------
+ Error Detach(bool keep_stopped);
+
+ //------------------------------------------------------------------
+ /// Kills the process and shuts down all threads that were spawned
+ /// to track and monitor the process.
+ ///
+ /// This function is not meant to be overridden by Process
+ /// subclasses.
+ ///
+ /// @param[in] force_kill
+ /// Whether lldb should force a kill (instead of a detach) from
+ /// the inferior process. Normally if lldb launched a binary and
+ /// Destory is called, lldb kills it. If lldb attached to a
+ /// running process and Destory is called, lldb detaches. If
+ /// this behavior needs to be over-ridden, this is the bool that
+ /// can be used.
+ ///
+ /// @return
+ /// Returns an error object.
+ //------------------------------------------------------------------
+ Error Destroy(bool force_kill);
+
+ //------------------------------------------------------------------
+ /// Sends a process a UNIX signal \a signal.
+ ///
+ /// This function is not meant to be overridden by Process
+ /// subclasses.
+ ///
+ /// @return
+ /// Returns an error object.
+ //------------------------------------------------------------------
+ Error Signal(int signal);
+
+ void SetUnixSignals(lldb::UnixSignalsSP &&signals_sp);
+
+ const lldb::UnixSignalsSP &GetUnixSignals();
+
+ //==================================================================
+ // Plug-in Process Control Overrides
+ //==================================================================
+
+ //------------------------------------------------------------------
+ /// Called before attaching to a process.
+ ///
+ /// Allow Process plug-ins to execute some code before attaching a
+ /// process.
+ ///
+ /// @return
+ /// Returns an error object.
+ //------------------------------------------------------------------
+ virtual Error WillAttachToProcessWithID(lldb::pid_t pid) { return Error(); }
+
+ //------------------------------------------------------------------
+ /// Called before attaching to a process.
+ ///
+ /// Allow Process plug-ins to execute some code before attaching a
+ /// process.
+ ///
+ /// @return
+ /// Returns an error object.
+ //------------------------------------------------------------------
+ virtual Error WillAttachToProcessWithName(const char *process_name,
+ bool wait_for_launch) {
+ return Error();
+ }
+
+ //------------------------------------------------------------------
+ /// Attach to a remote system via a URL
+ ///
+ /// @param[in] strm
+ /// A stream where output intended for the user
+ /// (if the driver has a way to display that) generated during
+ /// the connection. This may be nullptr if no output is needed.A
+ ///
+ /// @param[in] remote_url
+ /// The URL format that we are connecting to.
+ ///
+ /// @return
+ /// Returns an error object.
+ //------------------------------------------------------------------
+ virtual Error DoConnectRemote(Stream *strm, llvm::StringRef remote_url) {
+ Error error;
+ error.SetErrorString("remote connections are not supported");
+ return error;
+ }
+
+ //------------------------------------------------------------------
+ /// Attach to an existing process using a process ID.
+ ///
+ /// @param[in] pid
+ /// The process ID that we should attempt to attach to.
+ ///
+ /// @param[in] attach_info
+ /// Information on how to do the attach. For example, GetUserID()
+ /// will return the uid to attach as.
+ ///
+ /// @return
+ /// Returns a successful Error attaching was successful, or
+ /// an appropriate (possibly platform-specific) error code if
+ /// attaching fails.
+ /// hanming : need flag
+ //------------------------------------------------------------------
+ virtual Error DoAttachToProcessWithID(lldb::pid_t pid,
+ const ProcessAttachInfo &attach_info) {
+ Error error;
+ error.SetErrorStringWithFormat(
+ "error: %s does not support attaching to a process by pid",
+ GetPluginName().GetCString());
+ return error;
+ }
+
+ //------------------------------------------------------------------
+ /// Attach to an existing process using a partial process name.
+ ///
+ /// @param[in] process_name
+ /// The name of the process to attach to.
+ ///
+ /// @param[in] attach_info
+ /// Information on how to do the attach. For example, GetUserID()
+ /// will return the uid to attach as.
+ ///
+ /// @return
+ /// Returns a successful Error attaching was successful, or
+ /// an appropriate (possibly platform-specific) error code if
+ /// attaching fails.
+ //------------------------------------------------------------------
+ virtual Error
+ DoAttachToProcessWithName(const char *process_name,
+ const ProcessAttachInfo &attach_info) {
+ Error error;
+ error.SetErrorString("attach by name is not supported");
+ return error;
+ }
+
+ //------------------------------------------------------------------
+ /// Called after attaching a process.
+ ///
+ /// @param[in] process_arch
+ /// If you can figure out the process architecture after attach, fill it
+ /// in here.
+ ///
+ /// Allow Process plug-ins to execute some code after attaching to
+ /// a process.
+ //------------------------------------------------------------------
+ virtual void DidAttach(ArchSpec &process_arch) { process_arch.Clear(); }
+
+ //------------------------------------------------------------------
+ /// Called after a process re-execs itself.
+ ///
+ /// Allow Process plug-ins to execute some code after a process has
+ /// exec'ed itself. Subclasses typically should override DoDidExec()
+ /// as the lldb_private::Process class needs to remove its dynamic
+ /// loader, runtime, ABI and other plug-ins, as well as unload all
+ /// shared libraries.
+ //------------------------------------------------------------------
+ virtual void DidExec();
+
+ //------------------------------------------------------------------
+ /// Subclasses of Process should implement this function if they
+ /// need to do anything after a process exec's itself.
+ //------------------------------------------------------------------
+ virtual void DoDidExec() {}
+
+ //------------------------------------------------------------------
+ /// Called before launching to a process.
+ ///
+ /// Allow Process plug-ins to execute some code before launching a
+ /// process.
+ ///
+ /// @return
+ /// Returns an error object.
+ //------------------------------------------------------------------
+ virtual Error WillLaunch(Module *module) { return Error(); }
+
+ //------------------------------------------------------------------
+ /// Launch a new process.
+ ///
+ /// Launch a new process by spawning a new process using
+ /// \a exe_module's file as the file to launch. Launch details are
+ /// provided in \a launch_info.
+ ///
+ /// @param[in] exe_module
+ /// The module from which to extract the file specification and
+ /// launch.
+ ///
+ /// @param[in] launch_info
+ /// Details (e.g. arguments, stdio redirection, etc.) for the
+ /// requested launch.
+ ///
+ /// @return
+ /// An Error instance indicating success or failure of the
+ /// operation.
+ //------------------------------------------------------------------
+ virtual Error DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) {
+ Error error;
+ error.SetErrorStringWithFormat(
+ "error: %s does not support launching processes",
+ GetPluginName().GetCString());
+ return error;
+ }
+
+ //------------------------------------------------------------------
+ /// Called after launching a process.
+ ///
+ /// Allow Process plug-ins to execute some code after launching
+ /// a process.
+ //------------------------------------------------------------------
+ virtual void DidLaunch() {}
+
+ //------------------------------------------------------------------
+ /// Called before resuming to a process.
+ ///
+ /// Allow Process plug-ins to execute some code before resuming a
+ /// process.
+ ///
+ /// @return
+ /// Returns an error object.
+ //------------------------------------------------------------------
+ virtual Error WillResume() { return Error(); }
+
+ //------------------------------------------------------------------
+ /// Resumes all of a process's threads as configured using the
+ /// Thread run control functions.
+ ///
+ /// Threads for a process should be updated with one of the run
+ /// control actions (resume, step, or suspend) that they should take
+ /// when the process is resumed. If no run control action is given
+ /// to a thread it will be resumed by default.
+ ///
+ /// @return
+ /// Returns \b true if the process successfully resumes using
+ /// the thread run control actions, \b false otherwise.
+ ///
+ /// @see Thread:Resume()
+ /// @see Thread:Step()
+ /// @see Thread:Suspend()
+ //------------------------------------------------------------------
+ virtual Error DoResume() {
+ Error error;
+ error.SetErrorStringWithFormat(
+ "error: %s does not support resuming processes",
+ GetPluginName().GetCString());
+ return error;
+ }
+
+ //------------------------------------------------------------------
+ /// Called after resuming a process.
+ ///
+ /// Allow Process plug-ins to execute some code after resuming
+ /// a process.
+ //------------------------------------------------------------------
+ virtual void DidResume() {}
+
+ //------------------------------------------------------------------
+ /// Called before halting to a process.
+ ///
+ /// Allow Process plug-ins to execute some code before halting a
+ /// process.
+ ///
+ /// @return
+ /// Returns an error object.
+ //------------------------------------------------------------------
+ virtual Error WillHalt() { return Error(); }
+
+ //------------------------------------------------------------------
+ /// Halts a running process.
+ ///
+ /// DoHalt must produce one and only one stop StateChanged event if it
+ /// actually
+ /// stops the process. If the stop happens through some natural event (for
+ /// instance a SIGSTOP), then forwarding that event will do. Otherwise, you
+ /// must
+ /// generate the event manually. This function is called from the context of
+ /// the
+ /// private state thread.
+ ///
+ /// @param[out] caused_stop
+ /// If true, then this Halt caused the stop, otherwise, the
+ /// process was already stopped.
+ ///
+ /// @return
+ /// Returns \b true if the process successfully halts, \b false
+ /// otherwise.
+ //------------------------------------------------------------------
+ virtual Error DoHalt(bool &caused_stop) {
+ Error error;
+ error.SetErrorStringWithFormat(
+ "error: %s does not support halting processes",
+ GetPluginName().GetCString());
+ return error;
+ }
+
+ //------------------------------------------------------------------
+ /// Called after halting a process.
+ ///
+ /// Allow Process plug-ins to execute some code after halting
+ /// a process.
+ //------------------------------------------------------------------
+ virtual void DidHalt() {}
+
+ //------------------------------------------------------------------
+ /// Called before detaching from a process.
+ ///
+ /// Allow Process plug-ins to execute some code before detaching
+ /// from a process.
+ ///
+ /// @return
+ /// Returns an error object.
+ //------------------------------------------------------------------
+ virtual Error WillDetach() { return Error(); }
+
+ //------------------------------------------------------------------
+ /// Detaches from a running or stopped process.
+ ///
+ /// @return
+ /// Returns \b true if the process successfully detaches, \b
+ /// false otherwise.
+ //------------------------------------------------------------------
+ virtual Error DoDetach(bool keep_stopped) {
+ Error error;
+ error.SetErrorStringWithFormat(
+ "error: %s does not support detaching from processes",
+ GetPluginName().GetCString());
+ return error;
+ }
+
+ //------------------------------------------------------------------
+ /// Called after detaching from a process.
+ ///
+ /// Allow Process plug-ins to execute some code after detaching
+ /// from a process.
+ //------------------------------------------------------------------
+ virtual void DidDetach() {}
+
+ virtual bool DetachRequiresHalt() { return false; }
+
+ //------------------------------------------------------------------
+ /// Called before sending a signal to a process.
+ ///
+ /// Allow Process plug-ins to execute some code before sending a
+ /// signal to a process.
+ ///
+ /// @return
+ /// Returns no error if it is safe to proceed with a call to
+ /// Process::DoSignal(int), otherwise an error describing what
+ /// prevents the signal from being sent.
+ //------------------------------------------------------------------
+ virtual Error WillSignal() { return Error(); }
+
+ //------------------------------------------------------------------
+ /// Sends a process a UNIX signal \a signal.
+ ///
+ /// @return
+ /// Returns an error object.
+ //------------------------------------------------------------------
+ virtual Error DoSignal(int signal) {
+ Error error;
+ error.SetErrorStringWithFormat(
+ "error: %s does not support sending signals to processes",
+ GetPluginName().GetCString());
+ return error;
+ }
+
+ virtual Error WillDestroy() { return Error(); }
+
+ virtual Error DoDestroy() = 0;
+
+ virtual void DidDestroy() {}
+
+ virtual bool DestroyRequiresHalt() { return true; }
+
+ //------------------------------------------------------------------
+ /// Called after sending a signal to a process.
+ ///
+ /// Allow Process plug-ins to execute some code after sending a
+ /// signal to a process.
+ //------------------------------------------------------------------
+ virtual void DidSignal() {}
+
+ //------------------------------------------------------------------
+ /// Currently called as part of ShouldStop.
+ /// FIXME: Should really happen when the target stops before the
+ /// event is taken from the queue...
+ ///
+ /// This callback is called as the event
+ /// is about to be queued up to allow Process plug-ins to execute
+ /// some code prior to clients being notified that a process was
+ /// stopped. Common operations include updating the thread list,
+ /// invalidating any thread state (registers, stack, etc) prior to
+ /// letting the notification go out.
+ ///
+ //------------------------------------------------------------------
+ virtual void RefreshStateAfterStop() = 0;
+
+ //------------------------------------------------------------------
+ /// Sometimes the connection to a process can detect the host OS
+ /// version that the process is running on. The current platform
+ /// should be checked first in case the platform is connected, but
+ /// clients can fall back onto this function if the platform fails
+ /// to identify the host OS version. The platform should be checked
+ /// first in case you are running a simulator platform that might
+ /// itself be running natively, but have different heuristics for
+ /// figuring out which OS is is emulating.
+ ///
+ /// @param[out] major
+ /// The major OS version, or UINT32_MAX if it can't be determined
+ ///
+ /// @param[out] minor
+ /// The minor OS version, or UINT32_MAX if it can't be determined
+ ///
+ /// @param[out] update
+ /// The update OS version, or UINT32_MAX if it can't be determined
+ ///
+ /// @return
+ /// Returns \b true if the host OS version info was filled in
+ /// and \b false otherwise.
+ //------------------------------------------------------------------
+ virtual bool GetHostOSVersion(uint32_t &major, uint32_t &minor,
+ uint32_t &update) {
+ major = UINT32_MAX;
+ minor = UINT32_MAX;
+ update = UINT32_MAX;
+ return false;
+ }
+
+ //------------------------------------------------------------------
+ /// Get the target object pointer for this module.
+ ///
+ /// @return
+ /// A Target object pointer to the target that owns this
+ /// module.
+ //------------------------------------------------------------------
+ Target &GetTarget() { return *m_target_sp.lock(); }
+
+ //------------------------------------------------------------------
+ /// Get the const target object pointer for this module.
+ ///
+ /// @return
+ /// A const Target object pointer to the target that owns this
+ /// module.
+ //------------------------------------------------------------------
+ const Target &GetTarget() const { return *m_target_sp.lock(); }
+
+ //------------------------------------------------------------------
+ /// Flush all data in the process.
+ ///
+ /// Flush the memory caches, all threads, and any other cached data
+ /// in the process.
+ ///
+ /// This function can be called after a world changing event like
+ /// adding a new symbol file, or after the process makes a large
+ /// context switch (from boot ROM to booted into an OS).
+ //------------------------------------------------------------------
+ void Flush();
+
+ //------------------------------------------------------------------
+ /// Get accessor for the current process state.
+ ///
+ /// @return
+ /// The current state of the process.
+ ///
+ /// @see lldb::StateType
+ //------------------------------------------------------------------
+ lldb::StateType GetState();
+
+ lldb::ExpressionResults
+ RunThreadPlan(ExecutionContext &exe_ctx, lldb::ThreadPlanSP &thread_plan_sp,
+ const EvaluateExpressionOptions &options,
+ DiagnosticManager &diagnostic_manager);
+
+ static const char *ExecutionResultAsCString(lldb::ExpressionResults result);
+
+ void GetStatus(Stream &ostrm);
+
+ size_t GetThreadStatus(Stream &ostrm, bool only_threads_with_stop_reason,
+ uint32_t start_frame, uint32_t num_frames,
+ uint32_t num_frames_with_source,
+ bool stop_format);
+
+ void SendAsyncInterrupt();
+
+ //------------------------------------------------------------------
+ // Notify this process class that modules got loaded.
+ //
+ // If subclasses override this method, they must call this version
+ // before doing anything in the subclass version of the function.
+ //------------------------------------------------------------------
+ virtual void ModulesDidLoad(ModuleList &module_list);
+
+ //------------------------------------------------------------------
+ /// Retrieve the list of shared libraries that are loaded for this process
+ /// This method is used on pre-macOS 10.12, pre-iOS 10, pre-tvOS 10,
+ /// pre-watchOS 3 systems. The following two methods are for newer versions
+ /// of those OSes.
+ ///
+ /// For certain platforms, the time it takes for the DynamicLoader plugin to
+ /// read all of the shared libraries out of memory over a slow communication
+ /// channel may be too long. In that instance, the gdb-remote stub may be
+ /// able to retrieve the necessary information about the solibs out of memory
+ /// and return a concise summary sufficient for the DynamicLoader plugin.
+ ///
+ /// @param [in] image_list_address
+ /// The address where the table of shared libraries is stored in memory,
+ /// if that is appropriate for this platform. Else this may be
+ /// passed as LLDB_INVALID_ADDRESS.
+ ///
+ /// @param [in] image_count
+ /// The number of shared libraries that are present in this process, if
+ /// that is appropriate for this platofrm Else this may be passed as
+ /// LLDB_INVALID_ADDRESS.
+ ///
+ /// @return
+ /// A StructureDataSP object which, if non-empty, will contain the
+ /// information the DynamicLoader needs to get the initial scan of
+ /// solibs resolved.
+ //------------------------------------------------------------------
+ virtual lldb_private::StructuredData::ObjectSP
+ GetLoadedDynamicLibrariesInfos(lldb::addr_t image_list_address,
+ lldb::addr_t image_count) {
+ return StructuredData::ObjectSP();
+ }
+
+ // On macOS 10.12, tvOS 10, iOS 10, watchOS 3 and newer, debugserver can
+ // return
+ // the full list of loaded shared libraries without needing any input.
+ virtual lldb_private::StructuredData::ObjectSP
+ GetLoadedDynamicLibrariesInfos() {
+ return StructuredData::ObjectSP();
+ }
+
+ // On macOS 10.12, tvOS 10, iOS 10, watchOS 3 and newer, debugserver can
+ // return
+ // information about binaries given their load addresses.
+ virtual lldb_private::StructuredData::ObjectSP GetLoadedDynamicLibrariesInfos(
+ const std::vector<lldb::addr_t> &load_addresses) {
+ return StructuredData::ObjectSP();
+ }
+
+ //------------------------------------------------------------------
+ // Get information about the library shared cache, if that exists
+ //
+ // On macOS 10.12, tvOS 10, iOS 10, watchOS 3 and newer, debugserver can
+ // return
+ // information about the library shared cache (a set of standard libraries
+ // that are
+ // loaded at the same location for all processes on a system) in use.
+ //------------------------------------------------------------------
+ virtual lldb_private::StructuredData::ObjectSP GetSharedCacheInfo() {
+ return StructuredData::ObjectSP();
+ }
+
+ //------------------------------------------------------------------
+ /// Print a user-visible warning about a module being built with optimization
+ ///
+ /// Prints a async warning message to the user one time per Module
+ /// where a function is found that was compiled with optimization, per
+ /// Process.
+ ///
+ /// @param [in] sc
+ /// A SymbolContext with eSymbolContextFunction and eSymbolContextModule
+ /// pre-computed.
+ //------------------------------------------------------------------
+ void PrintWarningOptimization(const SymbolContext &sc);
+
+ virtual bool GetProcessInfo(ProcessInstanceInfo &info);
- //------------------------------------------------------------------
- /// Actually do the reading of memory from a process.
- ///
- /// Subclasses must override this function and can return fewer
- /// bytes than requested when memory requests are too large. This
- /// class will break up the memory requests and keep advancing the
- /// arguments along as needed.
- ///
- /// @param[in] vm_addr
- /// A virtual load address that indicates where to start reading
- /// memory from.
- ///
- /// @param[in] size
- /// The number of bytes to read.
- ///
- /// @param[out] buf
- /// A byte buffer that is at least \a size bytes long that
- /// will receive the memory bytes.
- ///
- /// @return
- /// The number of bytes that were actually read into \a buf.
- //------------------------------------------------------------------
- virtual size_t
- DoReadMemory (lldb::addr_t vm_addr,
- void *buf,
- size_t size,
- Error &error) = 0;
-
- //------------------------------------------------------------------
- /// Read of memory from a process.
- ///
- /// This function will read memory from the current process's
- /// address space and remove any traps that may have been inserted
- /// into the memory.
- ///
- /// This function is not meant to be overridden by Process
- /// subclasses, the subclasses should implement
- /// Process::DoReadMemory (lldb::addr_t, size_t, void *).
- ///
- /// @param[in] vm_addr
- /// A virtual load address that indicates where to start reading
- /// memory from.
- ///
- /// @param[out] buf
- /// A byte buffer that is at least \a size bytes long that
- /// will receive the memory bytes.
- ///
- /// @param[in] size
- /// The number of bytes to read.
- ///
- /// @return
- /// The number of bytes that were actually read into \a buf. If
- /// the returned number is greater than zero, yet less than \a
- /// size, then this function will get called again with \a
- /// vm_addr, \a buf, and \a size updated appropriately. Zero is
- /// returned to indicate an error.
- //------------------------------------------------------------------
- virtual size_t
- ReadMemory (lldb::addr_t vm_addr,
- void *buf,
- size_t size,
- Error &error);
-
- //------------------------------------------------------------------
- /// Read a NULL terminated string from memory
- ///
- /// This function will read a cache page at a time until a NULL
- /// string terminator is found. It will stop reading if an aligned
- /// sequence of NULL termination \a type_width bytes is not found
- /// before reading \a cstr_max_len bytes. The results are always
- /// guaranteed to be NULL terminated, and that no more than
- /// (max_bytes - type_width) bytes will be read.
- ///
- /// @param[in] vm_addr
- /// The virtual load address to start the memory read.
- ///
- /// @param[in] str
- /// A character buffer containing at least max_bytes.
- ///
- /// @param[in] max_bytes
- /// The maximum number of bytes to read.
- ///
- /// @param[in] error
- /// The error status of the read operation.
- ///
- /// @param[in] type_width
- /// The size of the null terminator (1 to 4 bytes per
- /// character). Defaults to 1.
- ///
- /// @return
- /// The error status or the number of bytes prior to the null terminator.
- //------------------------------------------------------------------
- size_t
- ReadStringFromMemory (lldb::addr_t vm_addr,
- char *str,
- size_t max_bytes,
- Error &error,
- size_t type_width = 1);
-
- //------------------------------------------------------------------
- /// Read a NULL terminated C string from memory
- ///
- /// This function will read a cache page at a time until the NULL
- /// C string terminator is found. It will stop reading if the NULL
- /// termination byte isn't found before reading \a cstr_max_len
- /// bytes, and the results are always guaranteed to be NULL
- /// terminated (at most cstr_max_len - 1 bytes will be read).
- //------------------------------------------------------------------
- size_t
- ReadCStringFromMemory (lldb::addr_t vm_addr,
- char *cstr,
- size_t cstr_max_len,
- Error &error);
-
- size_t
- ReadCStringFromMemory (lldb::addr_t vm_addr,
- std::string &out_str,
- Error &error);
-
- size_t
- ReadMemoryFromInferior (lldb::addr_t vm_addr,
- void *buf,
- size_t size,
+public:
+ //------------------------------------------------------------------
+ /// Get the exit status for a process.
+ ///
+ /// @return
+ /// The process's return code, or -1 if the current process
+ /// state is not eStateExited.
+ //------------------------------------------------------------------
+ int GetExitStatus();
+
+ //------------------------------------------------------------------
+ /// Get a textual description of what the process exited.
+ ///
+ /// @return
+ /// The textual description of why the process exited, or nullptr
+ /// if there is no description available.
+ //------------------------------------------------------------------
+ const char *GetExitDescription();
+
+ virtual void DidExit() {}
+
+ //------------------------------------------------------------------
+ /// Get the Modification ID of the process.
+ ///
+ /// @return
+ /// The modification ID of the process.
+ //------------------------------------------------------------------
+ ProcessModID GetModID() const { return m_mod_id; }
+
+ const ProcessModID &GetModIDRef() const { return m_mod_id; }
+
+ uint32_t GetStopID() const { return m_mod_id.GetStopID(); }
+
+ uint32_t GetResumeID() const { return m_mod_id.GetResumeID(); }
+
+ uint32_t GetLastUserExpressionResumeID() const {
+ return m_mod_id.GetLastUserExpressionResumeID();
+ }
+
+ uint32_t GetLastNaturalStopID() const {
+ return m_mod_id.GetLastNaturalStopID();
+ }
+
+ lldb::EventSP GetStopEventForStopID(uint32_t stop_id) const {
+ return m_mod_id.GetStopEventForStopID(stop_id);
+ }
+
+ //------------------------------------------------------------------
+ /// Set accessor for the process exit status (return code).
+ ///
+ /// Sometimes a child exits and the exit can be detected by global
+ /// functions (signal handler for SIGCHLD for example). This
+ /// accessor allows the exit status to be set from an external
+ /// source.
+ ///
+ /// Setting this will cause a eStateExited event to be posted to
+ /// the process event queue.
+ ///
+ /// @param[in] exit_status
+ /// The value for the process's return code.
+ ///
+ /// @see lldb::StateType
+ //------------------------------------------------------------------
+ virtual bool SetExitStatus(int exit_status, const char *cstr);
+
+ //------------------------------------------------------------------
+ /// Check if a process is still alive.
+ ///
+ /// @return
+ /// Returns \b true if the process is still valid, \b false
+ /// otherwise.
+ //------------------------------------------------------------------
+ virtual bool IsAlive();
+
+ //------------------------------------------------------------------
+ /// Before lldb detaches from a process, it warns the user that they are about
+ /// to lose their debug session.
+ /// In some cases, this warning doesn't need to be emitted -- for instance,
+ /// with core file debugging where
+ /// the user can reconstruct the "state" by simply re-running the debugger on
+ /// the core file.
+ ///
+ /// @return
+ // true if the user should be warned about detaching from this process.
+ //------------------------------------------------------------------
+ virtual bool WarnBeforeDetach() const { return true; }
+
+ //------------------------------------------------------------------
+ /// Actually do the reading of memory from a process.
+ ///
+ /// Subclasses must override this function and can return fewer
+ /// bytes than requested when memory requests are too large. This
+ /// class will break up the memory requests and keep advancing the
+ /// arguments along as needed.
+ ///
+ /// @param[in] vm_addr
+ /// A virtual load address that indicates where to start reading
+ /// memory from.
+ ///
+ /// @param[in] size
+ /// The number of bytes to read.
+ ///
+ /// @param[out] buf
+ /// A byte buffer that is at least \a size bytes long that
+ /// will receive the memory bytes.
+ ///
+ /// @return
+ /// The number of bytes that were actually read into \a buf.
+ //------------------------------------------------------------------
+ virtual size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
+ Error &error) = 0;
+
+ //------------------------------------------------------------------
+ /// Read of memory from a process.
+ ///
+ /// This function will read memory from the current process's
+ /// address space and remove any traps that may have been inserted
+ /// into the memory.
+ ///
+ /// This function is not meant to be overridden by Process
+ /// subclasses, the subclasses should implement
+ /// Process::DoReadMemory (lldb::addr_t, size_t, void *).
+ ///
+ /// @param[in] vm_addr
+ /// A virtual load address that indicates where to start reading
+ /// memory from.
+ ///
+ /// @param[out] buf
+ /// A byte buffer that is at least \a size bytes long that
+ /// will receive the memory bytes.
+ ///
+ /// @param[in] size
+ /// The number of bytes to read.
+ ///
+ /// @return
+ /// The number of bytes that were actually read into \a buf. If
+ /// the returned number is greater than zero, yet less than \a
+ /// size, then this function will get called again with \a
+ /// vm_addr, \a buf, and \a size updated appropriately. Zero is
+ /// returned to indicate an error.
+ //------------------------------------------------------------------
+ virtual size_t ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
Error &error);
-
- //------------------------------------------------------------------
- /// Reads an unsigned integer of the specified byte size from
- /// process memory.
- ///
- /// @param[in] load_addr
- /// A load address of the integer to read.
- ///
- /// @param[in] byte_size
- /// The size in byte of the integer to read.
- ///
- /// @param[in] fail_value
- /// The value to return if we fail to read an integer.
- ///
- /// @param[out] error
- /// An error that indicates the success or failure of this
- /// operation. If error indicates success (error.Success()),
- /// then the value returned can be trusted, otherwise zero
- /// will be returned.
- ///
- /// @return
- /// The unsigned integer that was read from the process memory
- /// space. If the integer was smaller than a uint64_t, any
- /// unused upper bytes will be zero filled. If the process
- /// byte order differs from the host byte order, the integer
- /// value will be appropriately byte swapped into host byte
- /// order.
- //------------------------------------------------------------------
- uint64_t
- ReadUnsignedIntegerFromMemory(lldb::addr_t load_addr, size_t byte_size, uint64_t fail_value, Error &error);
-
- int64_t
- ReadSignedIntegerFromMemory(lldb::addr_t load_addr, size_t byte_size, int64_t fail_value, Error &error);
-
- lldb::addr_t
- ReadPointerFromMemory (lldb::addr_t vm_addr,
- Error &error);
-
- bool
- WritePointerToMemory (lldb::addr_t vm_addr,
- lldb::addr_t ptr_value,
- Error &error);
-
- //------------------------------------------------------------------
- /// Actually do the writing of memory to a process.
- ///
- /// @param[in] vm_addr
- /// A virtual load address that indicates where to start writing
- /// memory to.
- ///
- /// @param[in] buf
- /// A byte buffer that is at least \a size bytes long that
- /// contains the data to write.
- ///
- /// @param[in] size
- /// The number of bytes to write.
- ///
- /// @param[out] error
- /// An error value in case the memory write fails.
- ///
- /// @return
- /// The number of bytes that were actually written.
- //------------------------------------------------------------------
- virtual size_t
- DoWriteMemory (lldb::addr_t vm_addr, const void *buf, size_t size, Error &error)
- {
- error.SetErrorStringWithFormat("error: %s does not support writing to processes", GetPluginName().GetCString());
- return 0;
- }
-
- //------------------------------------------------------------------
- /// Write all or part of a scalar value to memory.
- ///
- /// The value contained in \a scalar will be swapped to match the
- /// byte order of the process that is being debugged. If \a size is
- /// less than the size of scalar, the least significant \a size bytes
- /// from scalar will be written. If \a size is larger than the byte
- /// size of scalar, then the extra space will be padded with zeros
- /// and the scalar value will be placed in the least significant
- /// bytes in memory.
- ///
- /// @param[in] vm_addr
- /// A virtual load address that indicates where to start writing
- /// memory to.
- ///
- /// @param[in] scalar
- /// The scalar to write to the debugged process.
- ///
- /// @param[in] size
- /// This value can be smaller or larger than the scalar value
- /// itself. If \a size is smaller than the size of \a scalar,
- /// the least significant bytes in \a scalar will be used. If
- /// \a size is larger than the byte size of \a scalar, then
- /// the extra space will be padded with zeros. If \a size is
- /// set to UINT32_MAX, then the size of \a scalar will be used.
- ///
- /// @param[out] error
- /// An error value in case the memory write fails.
- ///
- /// @return
- /// The number of bytes that were actually written.
- //------------------------------------------------------------------
- size_t
- WriteScalarToMemory (lldb::addr_t vm_addr,
- const Scalar &scalar,
- size_t size,
- Error &error);
-
- size_t
- ReadScalarIntegerFromMemory (lldb::addr_t addr,
- uint32_t byte_size,
- bool is_signed,
- Scalar &scalar,
- Error &error);
-
- //------------------------------------------------------------------
- /// Write memory to a process.
- ///
- /// This function will write memory to the current process's
- /// address space and maintain any traps that might be present due
- /// to software breakpoints.
- ///
- /// This function is not meant to be overridden by Process
- /// subclasses, the subclasses should implement
- /// Process::DoWriteMemory (lldb::addr_t, size_t, void *).
- ///
- /// @param[in] vm_addr
- /// A virtual load address that indicates where to start writing
- /// memory to.
- ///
- /// @param[in] buf
- /// A byte buffer that is at least \a size bytes long that
- /// contains the data to write.
- ///
- /// @param[in] size
- /// The number of bytes to write.
- ///
- /// @return
- /// The number of bytes that were actually written.
- //------------------------------------------------------------------
- size_t
- WriteMemory (lldb::addr_t vm_addr, const void *buf, size_t size, Error &error);
-
- //------------------------------------------------------------------
- /// Actually allocate memory in the process.
- ///
- /// This function will allocate memory in the process's address
- /// space. This can't rely on the generic function calling mechanism,
- /// since that requires this function.
- ///
- /// @param[in] size
- /// The size of the allocation requested.
- ///
- /// @return
- /// The address of the allocated buffer in the process, or
- /// LLDB_INVALID_ADDRESS if the allocation failed.
- //------------------------------------------------------------------
-
- virtual lldb::addr_t
- DoAllocateMemory (size_t size, uint32_t permissions, Error &error)
- {
- error.SetErrorStringWithFormat("error: %s does not support allocating in the debug process", GetPluginName().GetCString());
- return LLDB_INVALID_ADDRESS;
- }
-
- //------------------------------------------------------------------
- /// The public interface to allocating memory in the process.
- ///
- /// This function will allocate memory in the process's address
- /// space. This can't rely on the generic function calling mechanism,
- /// since that requires this function.
- ///
- /// @param[in] size
- /// The size of the allocation requested.
- ///
- /// @param[in] permissions
- /// Or together any of the lldb::Permissions bits. The permissions on
- /// a given memory allocation can't be changed after allocation. Note
- /// that a block that isn't set writable can still be written on from lldb,
- /// just not by the process itself.
- ///
- /// @param[in,out] error
- /// An error object to fill in if things go wrong.
- /// @return
- /// The address of the allocated buffer in the process, or
- /// LLDB_INVALID_ADDRESS if the allocation failed.
- //------------------------------------------------------------------
- lldb::addr_t
- AllocateMemory (size_t size, uint32_t permissions, Error &error);
-
- //------------------------------------------------------------------
- /// The public interface to allocating memory in the process, this also
- /// clears the allocated memory.
- ///
- /// This function will allocate memory in the process's address
- /// space. This can't rely on the generic function calling mechanism,
- /// since that requires this function.
- ///
- /// @param[in] size
- /// The size of the allocation requested.
- ///
- /// @param[in] permissions
- /// Or together any of the lldb::Permissions bits. The permissions on
- /// a given memory allocation can't be changed after allocation. Note
- /// that a block that isn't set writable can still be written on from lldb,
- /// just not by the process itself.
- ///
- /// @param[in/out] error
- /// An error object to fill in if things go wrong.
- /// @return
- /// The address of the allocated buffer in the process, or
- /// LLDB_INVALID_ADDRESS if the allocation failed.
- //------------------------------------------------------------------
-
- lldb::addr_t
- CallocateMemory (size_t size, uint32_t permissions, Error &error);
-
- //------------------------------------------------------------------
- /// Resolve dynamically loaded indirect functions.
- ///
- /// @param[in] address
- /// The load address of the indirect function to resolve.
- ///
- /// @param[out] error
- /// An error value in case the resolve fails.
- ///
- /// @return
- /// The address of the resolved function.
- /// LLDB_INVALID_ADDRESS if the resolution failed.
- //------------------------------------------------------------------
- virtual lldb::addr_t
- ResolveIndirectFunction(const Address *address, Error &error);
-
- //------------------------------------------------------------------
- /// Locate the memory region that contains load_addr.
- ///
- /// If load_addr is within the address space the process has mapped
- /// range_info will be filled in with the start and end of that range
- /// as well as the permissions for that range and range_info.GetMapped
- /// will return true.
- ///
- /// If load_addr is outside any mapped region then range_info will
- /// have its start address set to load_addr and the end of the
- /// range will indicate the start of the next mapped range or be
- /// set to LLDB_INVALID_ADDRESS if there are no valid mapped ranges
- /// between load_addr and the end of the process address space.
- ///
- /// GetMemoryRegionInfo will only return an error if it is
- /// unimplemented for the current process.
- ///
- /// @param[in] load_addr
- /// The load address to query the range_info for.
- ///
- /// @param[out] range_info
- /// An range_info value containing the details of the range.
- ///
- /// @return
- /// An error value.
- //------------------------------------------------------------------
- virtual Error
- GetMemoryRegionInfo (lldb::addr_t load_addr,
- MemoryRegionInfo &range_info)
- {
- Error error;
- error.SetErrorString ("Process::GetMemoryRegionInfo() not supported");
- return error;
- }
-
- //------------------------------------------------------------------
- /// Obtain all the mapped memory regions within this process.
- ///
- /// @param[out] region_list
- /// A vector to contain MemoryRegionInfo objects for all mapped
- /// ranges.
- ///
- /// @return
- /// An error value.
- //------------------------------------------------------------------
- virtual Error
- GetMemoryRegions (std::vector<lldb::MemoryRegionInfoSP>& region_list);
-
- virtual Error
- GetWatchpointSupportInfo (uint32_t &num)
- {
- Error error;
- num = 0;
- error.SetErrorString ("Process::GetWatchpointSupportInfo() not supported");
- return error;
- }
- virtual Error
- GetWatchpointSupportInfo (uint32_t &num, bool& after)
- {
- Error error;
- num = 0;
- after = true;
- error.SetErrorString ("Process::GetWatchpointSupportInfo() not supported");
- return error;
- }
-
- lldb::ModuleSP
- ReadModuleFromMemory (const FileSpec& file_spec,
- lldb::addr_t header_addr,
- size_t size_to_read = 512);
-
- //------------------------------------------------------------------
- /// Attempt to get the attributes for a region of memory in the process.
- ///
- /// It may be possible for the remote debug server to inspect attributes
- /// for a region of memory in the process, such as whether there is a
- /// valid page of memory at a given address or whether that page is
- /// readable/writable/executable by the process.
- ///
- /// @param[in] load_addr
- /// The address of interest in the process.
- ///
- /// @param[out] permissions
- /// If this call returns successfully, this bitmask will have
- /// its Permissions bits set to indicate whether the region is
- /// readable/writable/executable. If this call fails, the
- /// bitmask values are undefined.
- ///
- /// @return
- /// Returns true if it was able to determine the attributes of the
- /// memory region. False if not.
- //------------------------------------------------------------------
- virtual bool
- GetLoadAddressPermissions (lldb::addr_t load_addr, uint32_t &permissions);
-
- //------------------------------------------------------------------
- /// Determines whether executing JIT-compiled code in this process
- /// is possible.
- ///
- /// @return
- /// True if execution of JIT code is possible; false otherwise.
- //------------------------------------------------------------------
- bool CanJIT ();
-
- //------------------------------------------------------------------
- /// Sets whether executing JIT-compiled code in this process
- /// is possible.
- ///
- /// @param[in] can_jit
- /// True if execution of JIT code is possible; false otherwise.
- //------------------------------------------------------------------
- void SetCanJIT (bool can_jit);
-
- //------------------------------------------------------------------
- /// Determines whether executing function calls using the interpreter
- /// is possible for this process.
- ///
- /// @return
- /// True if possible; false otherwise.
- //------------------------------------------------------------------
- bool CanInterpretFunctionCalls ()
- {
- return m_can_interpret_function_calls;
- }
-
- //------------------------------------------------------------------
- /// Sets whether executing function calls using the interpreter
- /// is possible for this process.
- ///
- /// @param[in] can_interpret_function_calls
- /// True if possible; false otherwise.
- //------------------------------------------------------------------
- void SetCanInterpretFunctionCalls (bool can_interpret_function_calls)
- {
- m_can_interpret_function_calls = can_interpret_function_calls;
- }
-
- //------------------------------------------------------------------
- /// Sets whether executing code in this process is possible.
- /// This could be either through JIT or interpreting.
- ///
- /// @param[in] can_run_code
- /// True if execution of code is possible; false otherwise.
- //------------------------------------------------------------------
- void SetCanRunCode (bool can_run_code);
-
- //------------------------------------------------------------------
- /// Actually deallocate memory in the process.
- ///
- /// This function will deallocate memory in the process's address
- /// space that was allocated with AllocateMemory.
- ///
- /// @param[in] ptr
- /// A return value from AllocateMemory, pointing to the memory you
- /// want to deallocate.
- ///
- /// @return
- /// \btrue if the memory was deallocated, \bfalse otherwise.
- //------------------------------------------------------------------
- virtual Error
- DoDeallocateMemory (lldb::addr_t ptr)
- {
- Error error;
- error.SetErrorStringWithFormat("error: %s does not support deallocating in the debug process", GetPluginName().GetCString());
- return error;
- }
+ //------------------------------------------------------------------
+ /// Read a NULL terminated string from memory
+ ///
+ /// This function will read a cache page at a time until a NULL
+ /// string terminator is found. It will stop reading if an aligned
+ /// sequence of NULL termination \a type_width bytes is not found
+ /// before reading \a cstr_max_len bytes. The results are always
+ /// guaranteed to be NULL terminated, and that no more than
+ /// (max_bytes - type_width) bytes will be read.
+ ///
+ /// @param[in] vm_addr
+ /// The virtual load address to start the memory read.
+ ///
+ /// @param[in] str
+ /// A character buffer containing at least max_bytes.
+ ///
+ /// @param[in] max_bytes
+ /// The maximum number of bytes to read.
+ ///
+ /// @param[in] error
+ /// The error status of the read operation.
+ ///
+ /// @param[in] type_width
+ /// The size of the null terminator (1 to 4 bytes per
+ /// character). Defaults to 1.
+ ///
+ /// @return
+ /// The error status or the number of bytes prior to the null terminator.
+ //------------------------------------------------------------------
+ size_t ReadStringFromMemory(lldb::addr_t vm_addr, char *str, size_t max_bytes,
+ Error &error, size_t type_width = 1);
+
+ //------------------------------------------------------------------
+ /// Read a NULL terminated C string from memory
+ ///
+ /// This function will read a cache page at a time until the NULL
+ /// C string terminator is found. It will stop reading if the NULL
+ /// termination byte isn't found before reading \a cstr_max_len
+ /// bytes, and the results are always guaranteed to be NULL
+ /// terminated (at most cstr_max_len - 1 bytes will be read).
+ //------------------------------------------------------------------
+ size_t ReadCStringFromMemory(lldb::addr_t vm_addr, char *cstr,
+ size_t cstr_max_len, Error &error);
+
+ size_t ReadCStringFromMemory(lldb::addr_t vm_addr, std::string &out_str,
+ Error &error);
+
+ size_t ReadMemoryFromInferior(lldb::addr_t vm_addr, void *buf, size_t size,
+ Error &error);
+
+ //------------------------------------------------------------------
+ /// Reads an unsigned integer of the specified byte size from
+ /// process memory.
+ ///
+ /// @param[in] load_addr
+ /// A load address of the integer to read.
+ ///
+ /// @param[in] byte_size
+ /// The size in byte of the integer to read.
+ ///
+ /// @param[in] fail_value
+ /// The value to return if we fail to read an integer.
+ ///
+ /// @param[out] error
+ /// An error that indicates the success or failure of this
+ /// operation. If error indicates success (error.Success()),
+ /// then the value returned can be trusted, otherwise zero
+ /// will be returned.
+ ///
+ /// @return
+ /// The unsigned integer that was read from the process memory
+ /// space. If the integer was smaller than a uint64_t, any
+ /// unused upper bytes will be zero filled. If the process
+ /// byte order differs from the host byte order, the integer
+ /// value will be appropriately byte swapped into host byte
+ /// order.
+ //------------------------------------------------------------------
+ uint64_t ReadUnsignedIntegerFromMemory(lldb::addr_t load_addr,
+ size_t byte_size, uint64_t fail_value,
+ Error &error);
+
+ int64_t ReadSignedIntegerFromMemory(lldb::addr_t load_addr, size_t byte_size,
+ int64_t fail_value, Error &error);
+
+ lldb::addr_t ReadPointerFromMemory(lldb::addr_t vm_addr, Error &error);
+
+ bool WritePointerToMemory(lldb::addr_t vm_addr, lldb::addr_t ptr_value,
+ Error &error);
- //------------------------------------------------------------------
- /// The public interface to deallocating memory in the process.
- ///
- /// This function will deallocate memory in the process's address
- /// space that was allocated with AllocateMemory.
- ///
- /// @param[in] ptr
- /// A return value from AllocateMemory, pointing to the memory you
- /// want to deallocate.
- ///
- /// @return
- /// \btrue if the memory was deallocated, \bfalse otherwise.
- //------------------------------------------------------------------
- Error
- DeallocateMemory (lldb::addr_t ptr);
-
- //------------------------------------------------------------------
- /// Get any available STDOUT.
- ///
- /// Calling this method is a valid operation only if all of the
- /// following conditions are true:
- /// 1) The process was launched, and not attached to.
- /// 2) The process was not launched with eLaunchFlagDisableSTDIO.
- /// 3) The process was launched without supplying a valid file path
- /// for STDOUT.
- ///
- /// Note that the implementation will probably need to start a read
- /// thread in the background to make sure that the pipe is drained
- /// and the STDOUT buffered appropriately, to prevent the process
- /// from deadlocking trying to write to a full buffer.
- ///
- /// Events will be queued indicating that there is STDOUT available
- /// that can be retrieved using this function.
- ///
- /// @param[out] buf
- /// A buffer that will receive any STDOUT bytes that are
- /// currently available.
- ///
- /// @param[in] buf_size
- /// The size in bytes for the buffer \a buf.
- ///
- /// @return
- /// The number of bytes written into \a buf. If this value is
- /// equal to \a buf_size, another call to this function should
- /// be made to retrieve more STDOUT data.
- //------------------------------------------------------------------
- virtual size_t
- GetSTDOUT (char *buf, size_t buf_size, Error &error);
-
- //------------------------------------------------------------------
- /// Get any available STDERR.
- ///
- /// Calling this method is a valid operation only if all of the
- /// following conditions are true:
- /// 1) The process was launched, and not attached to.
- /// 2) The process was not launched with eLaunchFlagDisableSTDIO.
- /// 3) The process was launched without supplying a valid file path
- /// for STDERR.
- ///
- /// Note that the implementation will probably need to start a read
- /// thread in the background to make sure that the pipe is drained
- /// and the STDERR buffered appropriately, to prevent the process
- /// from deadlocking trying to write to a full buffer.
- ///
- /// Events will be queued indicating that there is STDERR available
- /// that can be retrieved using this function.
- ///
- /// @param[in] buf
- /// A buffer that will receive any STDERR bytes that are
- /// currently available.
- ///
- /// @param[out] buf_size
- /// The size in bytes for the buffer \a buf.
- ///
- /// @return
- /// The number of bytes written into \a buf. If this value is
- /// equal to \a buf_size, another call to this function should
- /// be made to retrieve more STDERR data.
- //------------------------------------------------------------------
- virtual size_t
- GetSTDERR (char *buf, size_t buf_size, Error &error);
-
- //------------------------------------------------------------------
- /// Puts data into this process's STDIN.
- ///
- /// Calling this method is a valid operation only if all of the
- /// following conditions are true:
- /// 1) The process was launched, and not attached to.
- /// 2) The process was not launched with eLaunchFlagDisableSTDIO.
- /// 3) The process was launched without supplying a valid file path
- /// for STDIN.
- ///
- /// @param[in] buf
- /// A buffer that contains the data to write to the process's STDIN.
- ///
- /// @param[in] buf_size
- /// The size in bytes for the buffer \a buf.
- ///
- /// @return
- /// The number of bytes written into \a buf. If this value is
- /// less than \a buf_size, another call to this function should
- /// be made to write the rest of the data.
- //------------------------------------------------------------------
- virtual size_t
- PutSTDIN (const char *buf, size_t buf_size, Error &error)
- {
- error.SetErrorString("stdin unsupported");
- return 0;
- }
+ //------------------------------------------------------------------
+ /// Actually do the writing of memory to a process.
+ ///
+ /// @param[in] vm_addr
+ /// A virtual load address that indicates where to start writing
+ /// memory to.
+ ///
+ /// @param[in] buf
+ /// A byte buffer that is at least \a size bytes long that
+ /// contains the data to write.
+ ///
+ /// @param[in] size
+ /// The number of bytes to write.
+ ///
+ /// @param[out] error
+ /// An error value in case the memory write fails.
+ ///
+ /// @return
+ /// The number of bytes that were actually written.
+ //------------------------------------------------------------------
+ virtual size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf,
+ size_t size, Error &error) {
+ error.SetErrorStringWithFormat(
+ "error: %s does not support writing to processes",
+ GetPluginName().GetCString());
+ return 0;
+ }
+
+ //------------------------------------------------------------------
+ /// Write all or part of a scalar value to memory.
+ ///
+ /// The value contained in \a scalar will be swapped to match the
+ /// byte order of the process that is being debugged. If \a size is
+ /// less than the size of scalar, the least significant \a size bytes
+ /// from scalar will be written. If \a size is larger than the byte
+ /// size of scalar, then the extra space will be padded with zeros
+ /// and the scalar value will be placed in the least significant
+ /// bytes in memory.
+ ///
+ /// @param[in] vm_addr
+ /// A virtual load address that indicates where to start writing
+ /// memory to.
+ ///
+ /// @param[in] scalar
+ /// The scalar to write to the debugged process.
+ ///
+ /// @param[in] size
+ /// This value can be smaller or larger than the scalar value
+ /// itself. If \a size is smaller than the size of \a scalar,
+ /// the least significant bytes in \a scalar will be used. If
+ /// \a size is larger than the byte size of \a scalar, then
+ /// the extra space will be padded with zeros. If \a size is
+ /// set to UINT32_MAX, then the size of \a scalar will be used.
+ ///
+ /// @param[out] error
+ /// An error value in case the memory write fails.
+ ///
+ /// @return
+ /// The number of bytes that were actually written.
+ //------------------------------------------------------------------
+ size_t WriteScalarToMemory(lldb::addr_t vm_addr, const Scalar &scalar,
+ size_t size, Error &error);
+
+ size_t ReadScalarIntegerFromMemory(lldb::addr_t addr, uint32_t byte_size,
+ bool is_signed, Scalar &scalar,
+ Error &error);
+
+ //------------------------------------------------------------------
+ /// Write memory to a process.
+ ///
+ /// This function will write memory to the current process's
+ /// address space and maintain any traps that might be present due
+ /// to software breakpoints.
+ ///
+ /// This function is not meant to be overridden by Process
+ /// subclasses, the subclasses should implement
+ /// Process::DoWriteMemory (lldb::addr_t, size_t, void *).
+ ///
+ /// @param[in] vm_addr
+ /// A virtual load address that indicates where to start writing
+ /// memory to.
+ ///
+ /// @param[in] buf
+ /// A byte buffer that is at least \a size bytes long that
+ /// contains the data to write.
+ ///
+ /// @param[in] size
+ /// The number of bytes to write.
+ ///
+ /// @return
+ /// The number of bytes that were actually written.
+ //------------------------------------------------------------------
+ // TODO: change this to take an ArrayRef<uint8_t>
+ size_t WriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
+ Error &error);
+
+ //------------------------------------------------------------------
+ /// Actually allocate memory in the process.
+ ///
+ /// This function will allocate memory in the process's address
+ /// space. This can't rely on the generic function calling mechanism,
+ /// since that requires this function.
+ ///
+ /// @param[in] size
+ /// The size of the allocation requested.
+ ///
+ /// @return
+ /// The address of the allocated buffer in the process, or
+ /// LLDB_INVALID_ADDRESS if the allocation failed.
+ //------------------------------------------------------------------
+
+ virtual lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions,
+ Error &error) {
+ error.SetErrorStringWithFormat(
+ "error: %s does not support allocating in the debug process",
+ GetPluginName().GetCString());
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ //------------------------------------------------------------------
+ /// The public interface to allocating memory in the process.
+ ///
+ /// This function will allocate memory in the process's address
+ /// space. This can't rely on the generic function calling mechanism,
+ /// since that requires this function.
+ ///
+ /// @param[in] size
+ /// The size of the allocation requested.
+ ///
+ /// @param[in] permissions
+ /// Or together any of the lldb::Permissions bits. The permissions on
+ /// a given memory allocation can't be changed after allocation. Note
+ /// that a block that isn't set writable can still be written on from
+ /// lldb,
+ /// just not by the process itself.
+ ///
+ /// @param[in,out] error
+ /// An error object to fill in if things go wrong.
+ /// @return
+ /// The address of the allocated buffer in the process, or
+ /// LLDB_INVALID_ADDRESS if the allocation failed.
+ //------------------------------------------------------------------
+ lldb::addr_t AllocateMemory(size_t size, uint32_t permissions, Error &error);
+
+ //------------------------------------------------------------------
+ /// The public interface to allocating memory in the process, this also
+ /// clears the allocated memory.
+ ///
+ /// This function will allocate memory in the process's address
+ /// space. This can't rely on the generic function calling mechanism,
+ /// since that requires this function.
+ ///
+ /// @param[in] size
+ /// The size of the allocation requested.
+ ///
+ /// @param[in] permissions
+ /// Or together any of the lldb::Permissions bits. The permissions on
+ /// a given memory allocation can't be changed after allocation. Note
+ /// that a block that isn't set writable can still be written on from
+ /// lldb,
+ /// just not by the process itself.
+ ///
+ /// @param[in/out] error
+ /// An error object to fill in if things go wrong.
+ /// @return
+ /// The address of the allocated buffer in the process, or
+ /// LLDB_INVALID_ADDRESS if the allocation failed.
+ //------------------------------------------------------------------
+
+ lldb::addr_t CallocateMemory(size_t size, uint32_t permissions, Error &error);
+
+ //------------------------------------------------------------------
+ /// Resolve dynamically loaded indirect functions.
+ ///
+ /// @param[in] address
+ /// The load address of the indirect function to resolve.
+ ///
+ /// @param[out] error
+ /// An error value in case the resolve fails.
+ ///
+ /// @return
+ /// The address of the resolved function.
+ /// LLDB_INVALID_ADDRESS if the resolution failed.
+ //------------------------------------------------------------------
+ virtual lldb::addr_t ResolveIndirectFunction(const Address *address,
+ Error &error);
+
+ //------------------------------------------------------------------
+ /// Locate the memory region that contains load_addr.
+ ///
+ /// If load_addr is within the address space the process has mapped
+ /// range_info will be filled in with the start and end of that range
+ /// as well as the permissions for that range and range_info.GetMapped
+ /// will return true.
+ ///
+ /// If load_addr is outside any mapped region then range_info will
+ /// have its start address set to load_addr and the end of the
+ /// range will indicate the start of the next mapped range or be
+ /// set to LLDB_INVALID_ADDRESS if there are no valid mapped ranges
+ /// between load_addr and the end of the process address space.
+ ///
+ /// GetMemoryRegionInfo will only return an error if it is
+ /// unimplemented for the current process.
+ ///
+ /// @param[in] load_addr
+ /// The load address to query the range_info for.
+ ///
+ /// @param[out] range_info
+ /// An range_info value containing the details of the range.
+ ///
+ /// @return
+ /// An error value.
+ //------------------------------------------------------------------
+ virtual Error GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &range_info) {
+ Error error;
+ error.SetErrorString("Process::GetMemoryRegionInfo() not supported");
+ return error;
+ }
+
+ //------------------------------------------------------------------
+ /// Obtain all the mapped memory regions within this process.
+ ///
+ /// @param[out] region_list
+ /// A vector to contain MemoryRegionInfo objects for all mapped
+ /// ranges.
+ ///
+ /// @return
+ /// An error value.
+ //------------------------------------------------------------------
+ virtual Error
+ GetMemoryRegions(std::vector<lldb::MemoryRegionInfoSP> &region_list);
+
+ virtual Error GetWatchpointSupportInfo(uint32_t &num) {
+ Error error;
+ num = 0;
+ error.SetErrorString("Process::GetWatchpointSupportInfo() not supported");
+ return error;
+ }
+
+ virtual Error GetWatchpointSupportInfo(uint32_t &num, bool &after) {
+ Error error;
+ num = 0;
+ after = true;
+ error.SetErrorString("Process::GetWatchpointSupportInfo() not supported");
+ return error;
+ }
+
+ lldb::ModuleSP ReadModuleFromMemory(const FileSpec &file_spec,
+ lldb::addr_t header_addr,
+ size_t size_to_read = 512);
+
+ //------------------------------------------------------------------
+ /// Attempt to get the attributes for a region of memory in the process.
+ ///
+ /// It may be possible for the remote debug server to inspect attributes
+ /// for a region of memory in the process, such as whether there is a
+ /// valid page of memory at a given address or whether that page is
+ /// readable/writable/executable by the process.
+ ///
+ /// @param[in] load_addr
+ /// The address of interest in the process.
+ ///
+ /// @param[out] permissions
+ /// If this call returns successfully, this bitmask will have
+ /// its Permissions bits set to indicate whether the region is
+ /// readable/writable/executable. If this call fails, the
+ /// bitmask values are undefined.
+ ///
+ /// @return
+ /// Returns true if it was able to determine the attributes of the
+ /// memory region. False if not.
+ //------------------------------------------------------------------
+ virtual bool GetLoadAddressPermissions(lldb::addr_t load_addr,
+ uint32_t &permissions);
+
+ //------------------------------------------------------------------
+ /// Determines whether executing JIT-compiled code in this process
+ /// is possible.
+ ///
+ /// @return
+ /// True if execution of JIT code is possible; false otherwise.
+ //------------------------------------------------------------------
+ bool CanJIT();
+
+ //------------------------------------------------------------------
+ /// Sets whether executing JIT-compiled code in this process
+ /// is possible.
+ ///
+ /// @param[in] can_jit
+ /// True if execution of JIT code is possible; false otherwise.
+ //------------------------------------------------------------------
+ void SetCanJIT(bool can_jit);
+
+ //------------------------------------------------------------------
+ /// Determines whether executing function calls using the interpreter
+ /// is possible for this process.
+ ///
+ /// @return
+ /// True if possible; false otherwise.
+ //------------------------------------------------------------------
+ bool CanInterpretFunctionCalls() { return m_can_interpret_function_calls; }
+
+ //------------------------------------------------------------------
+ /// Sets whether executing function calls using the interpreter
+ /// is possible for this process.
+ ///
+ /// @param[in] can_interpret_function_calls
+ /// True if possible; false otherwise.
+ //------------------------------------------------------------------
+ void SetCanInterpretFunctionCalls(bool can_interpret_function_calls) {
+ m_can_interpret_function_calls = can_interpret_function_calls;
+ }
+
+ //------------------------------------------------------------------
+ /// Sets whether executing code in this process is possible.
+ /// This could be either through JIT or interpreting.
+ ///
+ /// @param[in] can_run_code
+ /// True if execution of code is possible; false otherwise.
+ //------------------------------------------------------------------
+ void SetCanRunCode(bool can_run_code);
+
+ //------------------------------------------------------------------
+ /// Actually deallocate memory in the process.
+ ///
+ /// This function will deallocate memory in the process's address
+ /// space that was allocated with AllocateMemory.
+ ///
+ /// @param[in] ptr
+ /// A return value from AllocateMemory, pointing to the memory you
+ /// want to deallocate.
+ ///
+ /// @return
+ /// \btrue if the memory was deallocated, \bfalse otherwise.
+ //------------------------------------------------------------------
+ virtual Error DoDeallocateMemory(lldb::addr_t ptr) {
+ Error error;
+ error.SetErrorStringWithFormat(
+ "error: %s does not support deallocating in the debug process",
+ GetPluginName().GetCString());
+ return error;
+ }
+
+ //------------------------------------------------------------------
+ /// The public interface to deallocating memory in the process.
+ ///
+ /// This function will deallocate memory in the process's address
+ /// space that was allocated with AllocateMemory.
+ ///
+ /// @param[in] ptr
+ /// A return value from AllocateMemory, pointing to the memory you
+ /// want to deallocate.
+ ///
+ /// @return
+ /// \btrue if the memory was deallocated, \bfalse otherwise.
+ //------------------------------------------------------------------
+ Error DeallocateMemory(lldb::addr_t ptr);
+
+ //------------------------------------------------------------------
+ /// Get any available STDOUT.
+ ///
+ /// Calling this method is a valid operation only if all of the
+ /// following conditions are true:
+ /// 1) The process was launched, and not attached to.
+ /// 2) The process was not launched with eLaunchFlagDisableSTDIO.
+ /// 3) The process was launched without supplying a valid file path
+ /// for STDOUT.
+ ///
+ /// Note that the implementation will probably need to start a read
+ /// thread in the background to make sure that the pipe is drained
+ /// and the STDOUT buffered appropriately, to prevent the process
+ /// from deadlocking trying to write to a full buffer.
+ ///
+ /// Events will be queued indicating that there is STDOUT available
+ /// that can be retrieved using this function.
+ ///
+ /// @param[out] buf
+ /// A buffer that will receive any STDOUT bytes that are
+ /// currently available.
+ ///
+ /// @param[in] buf_size
+ /// The size in bytes for the buffer \a buf.
+ ///
+ /// @return
+ /// The number of bytes written into \a buf. If this value is
+ /// equal to \a buf_size, another call to this function should
+ /// be made to retrieve more STDOUT data.
+ //------------------------------------------------------------------
+ virtual size_t GetSTDOUT(char *buf, size_t buf_size, Error &error);
+
+ //------------------------------------------------------------------
+ /// Get any available STDERR.
+ ///
+ /// Calling this method is a valid operation only if all of the
+ /// following conditions are true:
+ /// 1) The process was launched, and not attached to.
+ /// 2) The process was not launched with eLaunchFlagDisableSTDIO.
+ /// 3) The process was launched without supplying a valid file path
+ /// for STDERR.
+ ///
+ /// Note that the implementation will probably need to start a read
+ /// thread in the background to make sure that the pipe is drained
+ /// and the STDERR buffered appropriately, to prevent the process
+ /// from deadlocking trying to write to a full buffer.
+ ///
+ /// Events will be queued indicating that there is STDERR available
+ /// that can be retrieved using this function.
+ ///
+ /// @param[in] buf
+ /// A buffer that will receive any STDERR bytes that are
+ /// currently available.
+ ///
+ /// @param[out] buf_size
+ /// The size in bytes for the buffer \a buf.
+ ///
+ /// @return
+ /// The number of bytes written into \a buf. If this value is
+ /// equal to \a buf_size, another call to this function should
+ /// be made to retrieve more STDERR data.
+ //------------------------------------------------------------------
+ virtual size_t GetSTDERR(char *buf, size_t buf_size, Error &error);
+
+ //------------------------------------------------------------------
+ /// Puts data into this process's STDIN.
+ ///
+ /// Calling this method is a valid operation only if all of the
+ /// following conditions are true:
+ /// 1) The process was launched, and not attached to.
+ /// 2) The process was not launched with eLaunchFlagDisableSTDIO.
+ /// 3) The process was launched without supplying a valid file path
+ /// for STDIN.
+ ///
+ /// @param[in] buf
+ /// A buffer that contains the data to write to the process's STDIN.
+ ///
+ /// @param[in] buf_size
+ /// The size in bytes for the buffer \a buf.
+ ///
+ /// @return
+ /// The number of bytes written into \a buf. If this value is
+ /// less than \a buf_size, another call to this function should
+ /// be made to write the rest of the data.
+ //------------------------------------------------------------------
+ virtual size_t PutSTDIN(const char *buf, size_t buf_size, Error &error) {
+ error.SetErrorString("stdin unsupported");
+ return 0;
+ }
+
+ //------------------------------------------------------------------
+ /// Get any available profile data.
+ ///
+ /// @param[out] buf
+ /// A buffer that will receive any profile data bytes that are
+ /// currently available.
+ ///
+ /// @param[out] buf_size
+ /// The size in bytes for the buffer \a buf.
+ ///
+ /// @return
+ /// The number of bytes written into \a buf. If this value is
+ /// equal to \a buf_size, another call to this function should
+ /// be made to retrieve more profile data.
+ //------------------------------------------------------------------
+ virtual size_t GetAsyncProfileData(char *buf, size_t buf_size, Error &error);
+
+ //----------------------------------------------------------------------
+ // Process Breakpoints
+ //----------------------------------------------------------------------
+ size_t GetSoftwareBreakpointTrapOpcode(BreakpointSite *bp_site);
+
+ virtual Error EnableBreakpointSite(BreakpointSite *bp_site) {
+ Error error;
+ error.SetErrorStringWithFormat(
+ "error: %s does not support enabling breakpoints",
+ GetPluginName().GetCString());
+ return error;
+ }
+
+ virtual Error DisableBreakpointSite(BreakpointSite *bp_site) {
+ Error error;
+ error.SetErrorStringWithFormat(
+ "error: %s does not support disabling breakpoints",
+ GetPluginName().GetCString());
+ return error;
+ }
+
+ // This is implemented completely using the lldb::Process API. Subclasses
+ // don't need to implement this function unless the standard flow of
+ // read existing opcode, write breakpoint opcode, verify breakpoint opcode
+ // doesn't work for a specific process plug-in.
+ virtual Error EnableSoftwareBreakpoint(BreakpointSite *bp_site);
+
+ // This is implemented completely using the lldb::Process API. Subclasses
+ // don't need to implement this function unless the standard flow of
+ // restoring original opcode in memory and verifying the restored opcode
+ // doesn't work for a specific process plug-in.
+ virtual Error DisableSoftwareBreakpoint(BreakpointSite *bp_site);
+
+ BreakpointSiteList &GetBreakpointSiteList();
+
+ const BreakpointSiteList &GetBreakpointSiteList() const;
+
+ void DisableAllBreakpointSites();
+
+ Error ClearBreakpointSiteByID(lldb::user_id_t break_id);
+
+ lldb::break_id_t CreateBreakpointSite(const lldb::BreakpointLocationSP &owner,
+ bool use_hardware);
+
+ Error DisableBreakpointSiteByID(lldb::user_id_t break_id);
+
+ Error EnableBreakpointSiteByID(lldb::user_id_t break_id);
+
+ // BreakpointLocations use RemoveOwnerFromBreakpointSite to remove
+ // themselves from the owner's list of this breakpoint sites.
+ void RemoveOwnerFromBreakpointSite(lldb::user_id_t owner_id,
+ lldb::user_id_t owner_loc_id,
+ lldb::BreakpointSiteSP &bp_site_sp);
+
+ //----------------------------------------------------------------------
+ // Process Watchpoints (optional)
+ //----------------------------------------------------------------------
+ virtual Error EnableWatchpoint(Watchpoint *wp, bool notify = true);
+
+ virtual Error DisableWatchpoint(Watchpoint *wp, bool notify = true);
+
+ //------------------------------------------------------------------
+ // Thread Queries
+ //------------------------------------------------------------------
+ virtual bool UpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) = 0;
+
+ void UpdateThreadListIfNeeded();
+
+ ThreadList &GetThreadList() { return m_thread_list; }
+
+ // When ExtendedBacktraces are requested, the HistoryThreads that are
+ // created need an owner -- they're saved here in the Process. The
+ // threads in this list are not iterated over - driver programs need to
+ // request the extended backtrace calls starting from a root concrete
+ // thread one by one.
+ ThreadList &GetExtendedThreadList() { return m_extended_thread_list; }
+
+ ThreadList::ThreadIterable Threads() { return m_thread_list.Threads(); }
+
+ uint32_t GetNextThreadIndexID(uint64_t thread_id);
+
+ lldb::ThreadSP CreateOSPluginThread(lldb::tid_t tid, lldb::addr_t context);
+
+ // Returns true if an index id has been assigned to a thread.
+ bool HasAssignedIndexIDToThread(uint64_t sb_thread_id);
+
+ // Given a thread_id, it will assign a more reasonable index id for display to
+ // the user.
+ // If the thread_id has previously been assigned, the same index id will be
+ // used.
+ uint32_t AssignIndexIDToThread(uint64_t thread_id);
+
+ //------------------------------------------------------------------
+ // Queue Queries
+ //------------------------------------------------------------------
+
+ void UpdateQueueListIfNeeded();
+
+ QueueList &GetQueueList() {
+ UpdateQueueListIfNeeded();
+ return m_queue_list;
+ }
+
+ QueueList::QueueIterable Queues() {
+ UpdateQueueListIfNeeded();
+ return m_queue_list.Queues();
+ }
+
+ //------------------------------------------------------------------
+ // Event Handling
+ //------------------------------------------------------------------
+ lldb::StateType GetNextEvent(lldb::EventSP &event_sp);
+
+ // Returns the process state when it is stopped. If specified, event_sp_ptr
+ // is set to the event which triggered the stop. If wait_always = false,
+ // and the process is already stopped, this function returns immediately.
+ // If the process is hijacked and use_run_lock is true (the default), then
+ // this
+ // function releases the run lock after the stop. Setting use_run_lock to
+ // false
+ // will avoid this behavior.
+ lldb::StateType
+ WaitForProcessToStop(const Timeout<std::micro> &timeout,
+ lldb::EventSP *event_sp_ptr = nullptr,
+ bool wait_always = true,
+ lldb::ListenerSP hijack_listener = lldb::ListenerSP(),
+ Stream *stream = nullptr, bool use_run_lock = true);
+
+ uint32_t GetIOHandlerID() const { return m_iohandler_sync.GetValue(); }
+
+ //--------------------------------------------------------------------------------------
+ /// Waits for the process state to be running within a given msec timeout.
+ ///
+ /// The main purpose of this is to implement an interlock waiting for
+ /// HandlePrivateEvent
+ /// to push an IOHandler.
+ ///
+ /// @param[in] timeout_msec
+ /// The maximum time length to wait for the process to transition to the
+ /// eStateRunning state, specified in milliseconds.
+ //--------------------------------------------------------------------------------------
+ void SyncIOHandler(uint32_t iohandler_id, uint64_t timeout_msec);
+
+ lldb::StateType GetStateChangedEvents(
+ lldb::EventSP &event_sp, const Timeout<std::micro> &timeout,
+ lldb::ListenerSP
+ hijack_listener); // Pass an empty ListenerSP to use builtin listener
+
+ //--------------------------------------------------------------------------------------
+ /// Centralize the code that handles and prints descriptions for process state
+ /// changes.
+ ///
+ /// @param[in] event_sp
+ /// The process state changed event
+ ///
+ /// @param[in] stream
+ /// The output stream to get the state change description
+ ///
+ /// @param[in,out] pop_process_io_handler
+ /// If this value comes in set to \b true, then pop the Process IOHandler
+ /// if needed.
+ /// Else this variable will be set to \b true or \b false to indicate if
+ /// the process
+ /// needs to have its process IOHandler popped.
+ ///
+ /// @return
+ /// \b true if the event describes a process state changed event, \b false
+ /// otherwise.
+ //--------------------------------------------------------------------------------------
+ static bool HandleProcessStateChangedEvent(const lldb::EventSP &event_sp,
+ Stream *stream,
+ bool &pop_process_io_handler);
+
+ Event *PeekAtStateChangedEvents();
+
+ class ProcessEventHijacker {
+ public:
+ ProcessEventHijacker(Process &process, lldb::ListenerSP listener_sp)
+ : m_process(process) {
+ m_process.HijackProcessEvents(listener_sp);
+ }
+
+ ~ProcessEventHijacker() { m_process.RestoreProcessEvents(); }
+
+ private:
+ Process &m_process;
+ };
+
+ friend class ProcessEventHijacker;
+ friend class ProcessProperties;
+ //------------------------------------------------------------------
+ /// If you need to ensure that you and only you will hear about some public
+ /// event, then make a new listener, set to listen to process events, and
+ /// then call this with that listener. Then you will have to wait on that
+ /// listener explicitly for events (rather than using the GetNextEvent &
+ /// WaitFor*
+ /// calls above. Be sure to call RestoreProcessEvents when you are done.
+ ///
+ /// @param[in] listener
+ /// This is the new listener to whom all process events will be delivered.
+ ///
+ /// @return
+ /// Returns \b true if the new listener could be installed,
+ /// \b false otherwise.
+ //------------------------------------------------------------------
+ bool HijackProcessEvents(lldb::ListenerSP listener_sp);
+
+ //------------------------------------------------------------------
+ /// Restores the process event broadcasting to its normal state.
+ ///
+ //------------------------------------------------------------------
+ void RestoreProcessEvents();
+
+ const lldb::ABISP &GetABI();
+
+ OperatingSystem *GetOperatingSystem() { return m_os_ap.get(); }
+
+ ArchSpec::StopInfoOverrideCallbackType GetStopInfoOverrideCallback() const {
+ return m_stop_info_override_callback;
+ }
+
+ virtual LanguageRuntime *GetLanguageRuntime(lldb::LanguageType language,
+ bool retry_if_null = true);
+
+ virtual CPPLanguageRuntime *GetCPPLanguageRuntime(bool retry_if_null = true);
+
+ virtual ObjCLanguageRuntime *
+ GetObjCLanguageRuntime(bool retry_if_null = true);
+
+ bool IsPossibleDynamicValue(ValueObject &in_value);
+
+ bool IsRunning() const;
+
+ DynamicCheckerFunctions *GetDynamicCheckers() {
+ return m_dynamic_checkers_ap.get();
+ }
+
+ void SetDynamicCheckers(DynamicCheckerFunctions *dynamic_checkers);
+
+ //------------------------------------------------------------------
+ /// Call this to set the lldb in the mode where it breaks on new thread
+ /// creations, and then auto-restarts. This is useful when you are trying
+ /// to run only one thread, but either that thread or the kernel is creating
+ /// new threads in the process. If you stop when the thread is created, you
+ /// can immediately suspend it, and keep executing only the one thread you
+ /// intend.
+ ///
+ /// @return
+ /// Returns \b true if we were able to start up the notification
+ /// \b false otherwise.
+ //------------------------------------------------------------------
+ virtual bool StartNoticingNewThreads() { return true; }
+
+ //------------------------------------------------------------------
+ /// Call this to turn off the stop & notice new threads mode.
+ ///
+ /// @return
+ /// Returns \b true if we were able to start up the notification
+ /// \b false otherwise.
+ //------------------------------------------------------------------
+ virtual bool StopNoticingNewThreads() { return true; }
+
+ void SetRunningUserExpression(bool on);
+
+ //------------------------------------------------------------------
+ // lldb::ExecutionContextScope pure virtual functions
+ //------------------------------------------------------------------
+ lldb::TargetSP CalculateTarget() override;
+
+ lldb::ProcessSP CalculateProcess() override { return shared_from_this(); }
+
+ lldb::ThreadSP CalculateThread() override { return lldb::ThreadSP(); }
+
+ lldb::StackFrameSP CalculateStackFrame() override {
+ return lldb::StackFrameSP();
+ }
+
+ void CalculateExecutionContext(ExecutionContext &exe_ctx) override;
+
+ void SetSTDIOFileDescriptor(int file_descriptor);
+
+ //------------------------------------------------------------------
+ // Add a permanent region of memory that should never be read or
+ // written to. This can be used to ensure that memory reads or writes
+ // to certain areas of memory never end up being sent to the
+ // DoReadMemory or DoWriteMemory functions which can improve
+ // performance.
+ //------------------------------------------------------------------
+ void AddInvalidMemoryRegion(const LoadRange &region);
+
+ //------------------------------------------------------------------
+ // Remove a permanent region of memory that should never be read or
+ // written to that was previously added with AddInvalidMemoryRegion.
+ //------------------------------------------------------------------
+ bool RemoveInvalidMemoryRange(const LoadRange &region);
+
+ //------------------------------------------------------------------
+ // If the setup code of a thread plan needs to do work that might involve
+ // calling a function in the target, it should not do that work directly
+ // in one of the thread plan functions (DidPush/WillResume) because
+ // such work needs to be handled carefully. Instead, put that work in
+ // a PreResumeAction callback, and register it with the process. It will
+ // get done before the actual "DoResume" gets called.
+ //------------------------------------------------------------------
+
+ typedef bool(PreResumeActionCallback)(void *);
+
+ void AddPreResumeAction(PreResumeActionCallback callback, void *baton);
+
+ bool RunPreResumeActions();
+
+ void ClearPreResumeActions();
+
+ void ClearPreResumeAction(PreResumeActionCallback callback, void *baton);
+
+ ProcessRunLock &GetRunLock();
+
+ virtual Error SendEventData(const char *data) {
+ Error return_error("Sending an event is not supported for this process.");
+ return return_error;
+ }
+
+ lldb::ThreadCollectionSP GetHistoryThreads(lldb::addr_t addr);
+
+ lldb::InstrumentationRuntimeSP
+ GetInstrumentationRuntime(lldb::InstrumentationRuntimeType type);
+
+ //------------------------------------------------------------------
+ /// Try to fetch the module specification for a module with the
+ /// given file name and architecture. Process sub-classes have to
+ /// override this method if they support platforms where the
+ /// Platform object can't get the module spec for all module.
+ ///
+ /// @param[in] module_file_spec
+ /// The file name of the module to get specification for.
+ ///
+ /// @param[in] arch
+ /// The architecture of the module to get specification for.
+ ///
+ /// @param[out] module_spec
+ /// The fetched module specification if the return value is
+ /// \b true, unchanged otherwise.
+ ///
+ /// @return
+ /// Returns \b true if the module spec fetched successfully,
+ /// \b false otherwise.
+ //------------------------------------------------------------------
+ virtual bool GetModuleSpec(const FileSpec &module_file_spec,
+ const ArchSpec &arch, ModuleSpec &module_spec);
+
+ virtual void PrefetchModuleSpecs(llvm::ArrayRef<FileSpec> module_file_specs,
+ const llvm::Triple &triple) {}
+
+ //------------------------------------------------------------------
+ /// Try to find the load address of a file.
+ /// The load address is defined as the address of the first memory
+ /// region what contains data mapped from the specified file.
+ ///
+ /// @param[in] file
+ /// The name of the file whose load address we are looking for
+ ///
+ /// @param[out] is_loaded
+ /// \b True if the file is loaded into the memory and false
+ /// otherwise.
+ ///
+ /// @param[out] load_addr
+ /// The load address of the file if it is loaded into the
+ /// processes address space, LLDB_INVALID_ADDRESS otherwise.
+ //------------------------------------------------------------------
+ virtual Error GetFileLoadAddress(const FileSpec &file, bool &is_loaded,
+ lldb::addr_t &load_addr) {
+ return Error("Not supported");
+ }
+
+ size_t AddImageToken(lldb::addr_t image_ptr);
+
+ lldb::addr_t GetImagePtrFromToken(size_t token) const;
+
+ void ResetImageToken(size_t token);
+
+ //------------------------------------------------------------------
+ /// Find the next branch instruction to set a breakpoint on
+ ///
+ /// When instruction stepping through a source line, instead of
+ /// stepping through each instruction, we can put a breakpoint on
+ /// the next branch instruction (within the range of instructions
+ /// we are stepping through) and continue the process to there,
+ /// yielding significant performance benefits over instruction
+ /// stepping.
+ ///
+ /// @param[in] default_stop_addr
+ /// The address of the instruction where lldb would put a
+ /// breakpoint normally.
+ ///
+ /// @param[in] range_bounds
+ /// The range which the breakpoint must be contained within.
+ /// Typically a source line.
+ ///
+ /// @return
+ /// The address of the next branch instruction, or the end of
+ /// the range provided in range_bounds. If there are any
+ /// problems with the disassembly or getting the instructions,
+ /// the original default_stop_addr will be returned.
+ //------------------------------------------------------------------
+ Address AdvanceAddressToNextBranchInstruction(Address default_stop_addr,
+ AddressRange range_bounds);
+
+ //------------------------------------------------------------------
+ /// Configure asynchronous structured data feature.
+ ///
+ /// Each Process type that supports using an asynchronous StructuredData
+ /// feature should implement this to enable/disable/configure the feature.
+ /// The default implementation here will always return an error indiciating
+ /// the feature is unsupported.
+ ///
+ /// StructuredDataPlugin implementations will call this to configure
+ /// a feature that has been reported as being supported.
+ ///
+ /// @param[in] type_name
+ /// The StructuredData type name as previously discovered by
+ /// the Process-derived instance.
+ ///
+ /// @param[in] config
+ /// Configuration data for the feature being enabled. This config
+ /// data, which may be null, will be passed along to the feature
+ /// to process. The feature will dictate whether this is a dictionary,
+ /// an array or some other object. If the feature needs to be
+ /// set up properly before it can be enabled, then the config should
+ /// also take an enable/disable flag.
+ ///
+ /// @return
+ /// Returns the result of attempting to configure the feature.
+ //------------------------------------------------------------------
+ virtual Error
+ ConfigureStructuredData(const ConstString &type_name,
+ const StructuredData::ObjectSP &config_sp);
+
+ //------------------------------------------------------------------
+ /// Broadcasts the given structured data object from the given
+ /// plugin.
+ ///
+ /// StructuredDataPlugin instances can use this to optionally
+ /// broadcast any of their data if they want to make it available
+ /// for clients. The data will come in on the structured data
+ /// event bit (eBroadcastBitStructuredData).
+ ///
+ /// @param[in] object_sp
+ /// The structured data object to broadcast.
+ ///
+ /// @param[in] plugin_sp
+ /// The plugin that will be reported in the event's plugin
+ /// parameter.
+ //------------------------------------------------------------------
+ void BroadcastStructuredData(const StructuredData::ObjectSP &object_sp,
+ const lldb::StructuredDataPluginSP &plugin_sp);
+
+ //------------------------------------------------------------------
+ /// Returns the StructuredDataPlugin associated with a given type
+ /// name, if there is one.
+ ///
+ /// There will only be a plugin for a given StructuredDataType if the
+ /// debugged process monitor claims that the feature is supported.
+ /// This is one way to tell whether a feature is available.
+ ///
+ /// @return
+ /// The plugin if one is available for the specified feature;
+ /// otherwise, returns an empty shared pointer.
+ //------------------------------------------------------------------
+ lldb::StructuredDataPluginSP
+ GetStructuredDataPlugin(const ConstString &type_name) const;
- //------------------------------------------------------------------
- /// Get any available profile data.
- ///
- /// @param[out] buf
- /// A buffer that will receive any profile data bytes that are
- /// currently available.
- ///
- /// @param[out] buf_size
- /// The size in bytes for the buffer \a buf.
- ///
- /// @return
- /// The number of bytes written into \a buf. If this value is
- /// equal to \a buf_size, another call to this function should
- /// be made to retrieve more profile data.
- //------------------------------------------------------------------
- virtual size_t
- GetAsyncProfileData (char *buf, size_t buf_size, Error &error);
-
- //----------------------------------------------------------------------
- // Process Breakpoints
- //----------------------------------------------------------------------
- size_t
- GetSoftwareBreakpointTrapOpcode (BreakpointSite* bp_site);
-
- virtual Error
- EnableBreakpointSite (BreakpointSite *bp_site)
- {
- Error error;
- error.SetErrorStringWithFormat("error: %s does not support enabling breakpoints", GetPluginName().GetCString());
- return error;
- }
+protected:
+ void SetState(lldb::EventSP &event_sp);
+
+ lldb::StateType GetPrivateState();
+
+ //------------------------------------------------------------------
+ /// The "private" side of resuming a process. This doesn't alter the
+ /// state of m_run_lock, but just causes the process to resume.
+ ///
+ /// @return
+ /// An Error object describing the success or failure of the resume.
+ //------------------------------------------------------------------
+ Error PrivateResume();
+
+ //------------------------------------------------------------------
+ // Called internally
+ //------------------------------------------------------------------
+ void CompleteAttach();
+
+ //------------------------------------------------------------------
+ /// Print a user-visible warning one time per Process
+ ///
+ /// A facility for printing a warning to the user once per repeat_key.
+ ///
+ /// warning_type is from the Process::Warnings enums.
+ /// repeat_key is a pointer value that will be used to ensure that the
+ /// warning message is not printed multiple times. For instance, with a
+ /// warning about a function being optimized, you can pass the CompileUnit
+ /// pointer to have the warning issued for only the first function in a
+ /// CU, or the Function pointer to have it issued once for every function,
+ /// or a Module pointer to have it issued once per Module.
+ ///
+ /// Classes outside Process should call a specific PrintWarning method
+ /// so that the warning strings are all centralized in Process, instead of
+ /// calling PrintWarning() directly.
+ ///
+ /// @param [in] warning_type
+ /// One of the types defined in Process::Warnings.
+ ///
+ /// @param [in] repeat_key
+ /// A pointer value used to ensure that the warning is only printed once.
+ /// May be nullptr, indicating that the warning is printed unconditionally
+ /// every time.
+ ///
+ /// @param [in] fmt
+ /// printf style format string
+ //------------------------------------------------------------------
+ void PrintWarning(uint64_t warning_type, const void *repeat_key,
+ const char *fmt, ...) __attribute__((format(printf, 4, 5)));
+
+ //------------------------------------------------------------------
+ // NextEventAction provides a way to register an action on the next
+ // event that is delivered to this process. There is currently only
+ // one next event action allowed in the process at one time. If a
+ // new "NextEventAction" is added while one is already present, the
+ // old action will be discarded (with HandleBeingUnshipped called
+ // after it is discarded.)
+ //
+ // If you want to resume the process as a result of a resume action,
+ // call RequestResume, don't call Resume directly.
+ //------------------------------------------------------------------
+ class NextEventAction {
+ public:
+ typedef enum EventActionResult {
+ eEventActionSuccess,
+ eEventActionRetry,
+ eEventActionExit
+ } EventActionResult;
+
+ NextEventAction(Process *process) : m_process(process) {}
+
+ virtual ~NextEventAction() = default;
+
+ virtual EventActionResult PerformAction(lldb::EventSP &event_sp) = 0;
+ virtual void HandleBeingUnshipped() {}
+ virtual EventActionResult HandleBeingInterrupted() = 0;
+ virtual const char *GetExitString() = 0;
+ void RequestResume() { m_process->m_resume_requested = true; }
+
+ protected:
+ Process *m_process;
+ };
+
+ void SetNextEventAction(Process::NextEventAction *next_event_action) {
+ if (m_next_event_action_ap.get())
+ m_next_event_action_ap->HandleBeingUnshipped();
+
+ m_next_event_action_ap.reset(next_event_action);
+ }
+
+ // This is the completer for Attaching:
+ class AttachCompletionHandler : public NextEventAction {
+ public:
+ AttachCompletionHandler(Process *process, uint32_t exec_count);
+
+ ~AttachCompletionHandler() override = default;
+
+ EventActionResult PerformAction(lldb::EventSP &event_sp) override;
+ EventActionResult HandleBeingInterrupted() override;
+ const char *GetExitString() override;
+
+ private:
+ uint32_t m_exec_count;
+ std::string m_exit_string;
+ };
+
+ bool PrivateStateThreadIsValid() const {
+ lldb::StateType state = m_private_state.GetValue();
+ return state != lldb::eStateInvalid && state != lldb::eStateDetached &&
+ state != lldb::eStateExited && m_private_state_thread.IsJoinable();
+ }
+
+ void ForceNextEventDelivery() { m_force_next_event_delivery = true; }
+
+ //------------------------------------------------------------------
+ /// Loads any plugins associated with asynchronous structured data
+ /// and maps the relevant supported type name to the plugin.
+ ///
+ /// Processes can receive asynchronous structured data from the
+ /// process monitor. This method will load and map any structured
+ /// data plugins that support the given set of supported type names.
+ /// Later, if any of these features are enabled, the process monitor
+ /// is free to generate asynchronous structured data. The data must
+ /// come in as a single \b StructuredData::Dictionary. That dictionary
+ /// must have a string field named 'type', with a value that equals
+ /// the relevant type name string (one of the values in
+ /// \b supported_type_names).
+ ///
+ /// @param[in] supported_type_names
+ /// An array of zero or more type names. Each must be unique.
+ /// For each entry in the list, a StructuredDataPlugin will be
+ /// searched for that supports the structured data type name.
+ //------------------------------------------------------------------
+ void MapSupportedStructuredDataPlugins(
+ const StructuredData::Array &supported_type_names);
+
+ //------------------------------------------------------------------
+ /// Route the incoming structured data dictionary to the right plugin.
+ ///
+ /// The incoming structured data must be a dictionary, and it must
+ /// have a key named 'type' that stores a string value. The string
+ /// value must be the name of the structured data feature that
+ /// knows how to handle it.
+ ///
+ /// @param[in] object_sp
+ /// When non-null and pointing to a dictionary, the 'type'
+ /// key's string value is used to look up the plugin that
+ /// was registered for that structured data type. It then
+ /// calls the following method on the StructuredDataPlugin
+ /// instance:
+ ///
+ /// virtual void
+ /// HandleArrivalOfStructuredData(Process &process,
+ /// const ConstString &type_name,
+ /// const StructuredData::ObjectSP
+ /// &object_sp)
+ ///
+ /// @return
+ /// True if the structured data was routed to a plugin; otherwise,
+ /// false.
+ //------------------------------------------------------------------
+ bool RouteAsyncStructuredData(const StructuredData::ObjectSP object_sp);
+
+ //------------------------------------------------------------------
+ // Type definitions
+ //------------------------------------------------------------------
+ typedef std::map<lldb::LanguageType, lldb::LanguageRuntimeSP>
+ LanguageRuntimeCollection;
+ typedef std::unordered_set<const void *> WarningsPointerSet;
+ typedef std::map<uint64_t, WarningsPointerSet> WarningsCollection;
+
+ struct PreResumeCallbackAndBaton {
+ bool (*callback)(void *);
+ void *baton;
+ PreResumeCallbackAndBaton(PreResumeActionCallback in_callback,
+ void *in_baton)
+ : callback(in_callback), baton(in_baton) {}
+ bool operator== (const PreResumeCallbackAndBaton &rhs) {
+ return callback == rhs.callback && baton == rhs.baton;
+ }
+ };
+
+ using StructuredDataPluginMap =
+ std::map<ConstString, lldb::StructuredDataPluginSP>;
+
+ //------------------------------------------------------------------
+ // Member variables
+ //------------------------------------------------------------------
+ std::weak_ptr<Target> m_target_sp; ///< The target that owns this process.
+ ThreadSafeValue<lldb::StateType> m_public_state;
+ ThreadSafeValue<lldb::StateType>
+ m_private_state; // The actual state of our process
+ Broadcaster m_private_state_broadcaster; // This broadcaster feeds state
+ // changed events into the private
+ // state thread's listener.
+ Broadcaster m_private_state_control_broadcaster; // This is the control
+ // broadcaster, used to
+ // pause, resume & stop the
+ // private state thread.
+ lldb::ListenerSP m_private_state_listener_sp; // This is the listener for the
+ // private state thread.
+ HostThread m_private_state_thread; ///< Thread ID for the thread that watches
+ ///internal state events
+ ProcessModID m_mod_id; ///< Tracks the state of the process over stops and
+ ///other alterations.
+ uint32_t m_process_unique_id; ///< Each lldb_private::Process class that is
+ ///created gets a unique integer ID that
+ ///increments with each new instance
+ uint32_t m_thread_index_id; ///< Each thread is created with a 1 based index
+ ///that won't get re-used.
+ std::map<uint64_t, uint32_t> m_thread_id_to_index_id_map;
+ int m_exit_status; ///< The exit status of the process, or -1 if not set.
+ std::string m_exit_string; ///< A textual description of why a process exited.
+ std::mutex m_exit_status_mutex; ///< Mutex so m_exit_status m_exit_string can
+ ///be safely accessed from multiple threads
+ std::recursive_mutex m_thread_mutex;
+ ThreadList m_thread_list_real; ///< The threads for this process as are known
+ ///to the protocol we are debugging with
+ ThreadList m_thread_list; ///< The threads for this process as the user will
+ ///see them. This is usually the same as
+ ///< m_thread_list_real, but might be different if there is an OS plug-in
+ ///creating memory threads
+ ThreadList m_extended_thread_list; ///< Owner for extended threads that may be
+ ///generated, cleared on natural stops
+ uint32_t m_extended_thread_stop_id; ///< The natural stop id when
+ ///extended_thread_list was last updated
+ QueueList
+ m_queue_list; ///< The list of libdispatch queues at a given stop point
+ uint32_t m_queue_list_stop_id; ///< The natural stop id when queue list was
+ ///last fetched
+ std::vector<Notifications> m_notifications; ///< The list of notifications
+ ///that this process can deliver.
+ std::vector<lldb::addr_t> m_image_tokens;
+ lldb::ListenerSP m_listener_sp; ///< Shared pointer to the listener used for
+ ///public events. Can not be empty.
+ BreakpointSiteList m_breakpoint_site_list; ///< This is the list of breakpoint
+ ///locations we intend to insert in
+ ///the target.
+ lldb::DynamicLoaderUP m_dyld_ap;
+ lldb::JITLoaderListUP m_jit_loaders_ap;
+ lldb::DynamicCheckerFunctionsUP m_dynamic_checkers_ap; ///< The functions used
+ ///by the expression
+ ///parser to validate
+ ///data that
+ ///expressions use.
+ lldb::OperatingSystemUP m_os_ap;
+ lldb::SystemRuntimeUP m_system_runtime_ap;
+ lldb::UnixSignalsSP
+ m_unix_signals_sp; /// This is the current signal set for this process.
+ lldb::ABISP m_abi_sp;
+ lldb::IOHandlerSP m_process_input_reader;
+ Communication m_stdio_communication;
+ std::recursive_mutex m_stdio_communication_mutex;
+ bool m_stdin_forward; /// Remember if stdin must be forwarded to remote debug
+ /// server
+ std::string m_stdout_data;
+ std::string m_stderr_data;
+ std::recursive_mutex m_profile_data_comm_mutex;
+ std::vector<std::string> m_profile_data;
+ Predicate<uint32_t> m_iohandler_sync;
+ MemoryCache m_memory_cache;
+ AllocatedMemoryCache m_allocated_memory_cache;
+ bool m_should_detach; /// Should we detach if the process object goes away
+ /// with an explicit call to Kill or Detach?
+ LanguageRuntimeCollection m_language_runtimes;
+ InstrumentationRuntimeCollection m_instrumentation_runtimes;
+ std::unique_ptr<NextEventAction> m_next_event_action_ap;
+ std::vector<PreResumeCallbackAndBaton> m_pre_resume_actions;
+ ProcessRunLock m_public_run_lock;
+ ProcessRunLock m_private_run_lock;
+ ArchSpec::StopInfoOverrideCallbackType m_stop_info_override_callback;
+ bool m_currently_handling_do_on_removals;
+ bool m_resume_requested; // If m_currently_handling_event or
+ // m_currently_handling_do_on_removals are true,
+ // Resume will only request a resume, using this flag
+ // to check.
+ bool m_finalizing; // This is set at the beginning of Process::Finalize() to
+ // stop functions from looking up or creating things during
+ // a finalize call
+ bool m_finalize_called; // This is set at the end of Process::Finalize()
+ bool m_clear_thread_plans_on_stop;
+ bool m_force_next_event_delivery;
+ lldb::StateType m_last_broadcast_state; /// This helps with the Public event
+ /// coalescing in
+ /// ShouldBroadcastEvent.
+ std::map<lldb::addr_t, lldb::addr_t> m_resolved_indirect_addresses;
+ bool m_destroy_in_process;
+ bool m_can_interpret_function_calls; // Some targets, e.g the OSX kernel,
+ // don't support the ability to modify
+ // the stack.
+ WarningsCollection m_warnings_issued; // A set of object pointers which have
+ // already had warnings printed
+ std::mutex m_run_thread_plan_lock;
+ StructuredDataPluginMap m_structured_data_plugin_map;
+
+ enum { eCanJITDontKnow = 0, eCanJITYes, eCanJITNo } m_can_jit;
+
+ size_t RemoveBreakpointOpcodesFromBuffer(lldb::addr_t addr, size_t size,
+ uint8_t *buf) const;
+
+ void SynchronouslyNotifyStateChanged(lldb::StateType state);
+
+ void SetPublicState(lldb::StateType new_state, bool restarted);
+
+ void SetPrivateState(lldb::StateType state);
+
+ bool StartPrivateStateThread(bool is_secondary_thread = false);
+
+ void StopPrivateStateThread();
+
+ void PausePrivateStateThread();
+
+ void ResumePrivateStateThread();
- virtual Error
- DisableBreakpointSite (BreakpointSite *bp_site)
- {
- Error error;
- error.SetErrorStringWithFormat("error: %s does not support disabling breakpoints", GetPluginName().GetCString());
- return error;
- }
+private:
+ struct PrivateStateThreadArgs {
+ PrivateStateThreadArgs(Process *p, bool s)
+ : process(p), is_secondary_thread(s){};
+ Process *process;
+ bool is_secondary_thread;
+ };
+
+ // arg is a pointer to a new'ed PrivateStateThreadArgs structure.
+ // PrivateStateThread will free it for you.
+ static lldb::thread_result_t PrivateStateThread(void *arg);
+
+ // The starts up the private state thread that will watch for events from the
+ // debugee.
+ // Pass true for is_secondary_thread in the case where you have to temporarily
+ // spin up a
+ // secondary state thread to handle events from a hand-called function on the
+ // primary
+ // private state thread.
+
+ lldb::thread_result_t RunPrivateStateThread(bool is_secondary_thread);
- // This is implemented completely using the lldb::Process API. Subclasses
- // don't need to implement this function unless the standard flow of
- // read existing opcode, write breakpoint opcode, verify breakpoint opcode
- // doesn't work for a specific process plug-in.
- virtual Error
- EnableSoftwareBreakpoint (BreakpointSite *bp_site);
-
- // This is implemented completely using the lldb::Process API. Subclasses
- // don't need to implement this function unless the standard flow of
- // restoring original opcode in memory and verifying the restored opcode
- // doesn't work for a specific process plug-in.
- virtual Error
- DisableSoftwareBreakpoint (BreakpointSite *bp_site);
-
- BreakpointSiteList &
- GetBreakpointSiteList();
-
- const BreakpointSiteList &
- GetBreakpointSiteList() const;
-
- void
- DisableAllBreakpointSites ();
-
- Error
- ClearBreakpointSiteByID (lldb::user_id_t break_id);
-
- lldb::break_id_t
- CreateBreakpointSite (const lldb::BreakpointLocationSP &owner,
- bool use_hardware);
-
- Error
- DisableBreakpointSiteByID (lldb::user_id_t break_id);
-
- Error
- EnableBreakpointSiteByID (lldb::user_id_t break_id);
-
- // BreakpointLocations use RemoveOwnerFromBreakpointSite to remove
- // themselves from the owner's list of this breakpoint sites.
- void
- RemoveOwnerFromBreakpointSite (lldb::user_id_t owner_id,
- lldb::user_id_t owner_loc_id,
- lldb::BreakpointSiteSP &bp_site_sp);
-
- //----------------------------------------------------------------------
- // Process Watchpoints (optional)
- //----------------------------------------------------------------------
- virtual Error
- EnableWatchpoint (Watchpoint *wp, bool notify = true);
-
- virtual Error
- DisableWatchpoint (Watchpoint *wp, bool notify = true);
-
- //------------------------------------------------------------------
- // Thread Queries
- //------------------------------------------------------------------
- virtual bool
- UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list) = 0;
-
- void
- UpdateThreadListIfNeeded ();
-
- ThreadList &
- GetThreadList ()
- {
- return m_thread_list;
- }
+protected:
+ void HandlePrivateEvent(lldb::EventSP &event_sp);
- // When ExtendedBacktraces are requested, the HistoryThreads that are
- // created need an owner -- they're saved here in the Process. The
- // threads in this list are not iterated over - driver programs need to
- // request the extended backtrace calls starting from a root concrete
- // thread one by one.
- ThreadList &
- GetExtendedThreadList ()
- {
- return m_extended_thread_list;
- }
+ Error HaltPrivate();
- ThreadList::ThreadIterable
- Threads ()
- {
- return m_thread_list.Threads();
- }
+ lldb::StateType WaitForProcessStopPrivate(lldb::EventSP &event_sp,
+ const Timeout<std::micro> &timeout);
- uint32_t
- GetNextThreadIndexID (uint64_t thread_id);
-
- lldb::ThreadSP
- CreateOSPluginThread (lldb::tid_t tid, lldb::addr_t context);
-
- // Returns true if an index id has been assigned to a thread.
- bool
- HasAssignedIndexIDToThread(uint64_t sb_thread_id);
-
- // Given a thread_id, it will assign a more reasonable index id for display to the user.
- // If the thread_id has previously been assigned, the same index id will be used.
- uint32_t
- AssignIndexIDToThread(uint64_t thread_id);
-
- //------------------------------------------------------------------
- // Queue Queries
- //------------------------------------------------------------------
-
- void
- UpdateQueueListIfNeeded ();
-
- QueueList &
- GetQueueList ()
- {
- UpdateQueueListIfNeeded();
- return m_queue_list;
- }
+ // This waits for both the state change broadcaster, and the control
+ // broadcaster.
+ // If control_only, it only waits for the control broadcaster.
- QueueList::QueueIterable
- Queues ()
- {
- UpdateQueueListIfNeeded();
- return m_queue_list.Queues();
- }
+ bool GetEventsPrivate(lldb::EventSP &event_sp,
+ const Timeout<std::micro> &timeout, bool control_only);
- //------------------------------------------------------------------
- // Event Handling
- //------------------------------------------------------------------
- lldb::StateType
- GetNextEvent (lldb::EventSP &event_sp);
-
- // Returns the process state when it is stopped. If specified, event_sp_ptr
- // is set to the event which triggered the stop. If wait_always = false,
- // and the process is already stopped, this function returns immediately.
- // If the process is hijacked and use_run_lock is true (the default), then this
- // function releases the run lock after the stop. Setting use_run_lock to false
- // will avoid this behavior.
- lldb::StateType
- WaitForProcessToStop(const TimeValue *timeout,
- lldb::EventSP *event_sp_ptr = nullptr,
- bool wait_always = true,
- lldb::ListenerSP hijack_listener = lldb::ListenerSP(),
- Stream *stream = nullptr,
- bool use_run_lock = true);
-
- uint32_t
- GetIOHandlerID () const
- {
- return m_iohandler_sync.GetValue();
- }
+ lldb::StateType
+ GetStateChangedEventsPrivate(lldb::EventSP &event_sp,
+ const Timeout<std::micro> &timeout);
- //--------------------------------------------------------------------------------------
- /// Waits for the process state to be running within a given msec timeout.
- ///
- /// The main purpose of this is to implement an interlock waiting for HandlePrivateEvent
- /// to push an IOHandler.
- ///
- /// @param[in] timeout_msec
- /// The maximum time length to wait for the process to transition to the
- /// eStateRunning state, specified in milliseconds.
- //--------------------------------------------------------------------------------------
- void
- SyncIOHandler (uint32_t iohandler_id, uint64_t timeout_msec);
-
- lldb::StateType
- WaitForStateChangedEvents(const TimeValue *timeout,
- lldb::EventSP &event_sp,
- lldb::ListenerSP hijack_listener); // Pass an empty ListenerSP to use builtin listener
-
- //--------------------------------------------------------------------------------------
- /// Centralize the code that handles and prints descriptions for process state changes.
- ///
- /// @param[in] event_sp
- /// The process state changed event
- ///
- /// @param[in] stream
- /// The output stream to get the state change description
- ///
- /// @param[in,out] pop_process_io_handler
- /// If this value comes in set to \b true, then pop the Process IOHandler if needed.
- /// Else this variable will be set to \b true or \b false to indicate if the process
- /// needs to have its process IOHandler popped.
- ///
- /// @return
- /// \b true if the event describes a process state changed event, \b false otherwise.
- //--------------------------------------------------------------------------------------
- static bool
- HandleProcessStateChangedEvent (const lldb::EventSP &event_sp,
- Stream *stream,
- bool &pop_process_io_handler);
-
- Event *
- PeekAtStateChangedEvents ();
-
- class
- ProcessEventHijacker
- {
- public:
- ProcessEventHijacker (Process &process, lldb::ListenerSP listener_sp) :
- m_process (process)
- {
- m_process.HijackProcessEvents (listener_sp);
- }
-
- ~ProcessEventHijacker ()
- {
- m_process.RestoreProcessEvents();
- }
-
- private:
- Process &m_process;
- };
-
- friend class ProcessEventHijacker;
- friend class ProcessProperties;
- //------------------------------------------------------------------
- /// If you need to ensure that you and only you will hear about some public
- /// event, then make a new listener, set to listen to process events, and
- /// then call this with that listener. Then you will have to wait on that
- /// listener explicitly for events (rather than using the GetNextEvent & WaitFor*
- /// calls above. Be sure to call RestoreProcessEvents when you are done.
- ///
- /// @param[in] listener
- /// This is the new listener to whom all process events will be delivered.
- ///
- /// @return
- /// Returns \b true if the new listener could be installed,
- /// \b false otherwise.
- //------------------------------------------------------------------
- bool
- HijackProcessEvents (lldb::ListenerSP listener_sp);
-
- //------------------------------------------------------------------
- /// Restores the process event broadcasting to its normal state.
- ///
- //------------------------------------------------------------------
- void
- RestoreProcessEvents ();
-
- const lldb::ABISP &
- GetABI ();
-
- OperatingSystem *
- GetOperatingSystem ()
- {
- return m_os_ap.get();
- }
+ size_t WriteMemoryPrivate(lldb::addr_t addr, const void *buf, size_t size,
+ Error &error);
- ArchSpec::StopInfoOverrideCallbackType
- GetStopInfoOverrideCallback () const
- {
- return m_stop_info_override_callback;
- }
+ void AppendSTDOUT(const char *s, size_t len);
- virtual LanguageRuntime *
- GetLanguageRuntime (lldb::LanguageType language, bool retry_if_null = true);
-
- virtual CPPLanguageRuntime *
- GetCPPLanguageRuntime (bool retry_if_null = true);
-
- virtual ObjCLanguageRuntime *
- GetObjCLanguageRuntime (bool retry_if_null = true);
-
- bool
- IsPossibleDynamicValue (ValueObject& in_value);
-
- bool
- IsRunning () const;
-
- DynamicCheckerFunctions *GetDynamicCheckers()
- {
- return m_dynamic_checkers_ap.get();
- }
-
- void SetDynamicCheckers(DynamicCheckerFunctions *dynamic_checkers);
-
- //------------------------------------------------------------------
- /// Call this to set the lldb in the mode where it breaks on new thread
- /// creations, and then auto-restarts. This is useful when you are trying
- /// to run only one thread, but either that thread or the kernel is creating
- /// new threads in the process. If you stop when the thread is created, you
- /// can immediately suspend it, and keep executing only the one thread you intend.
- ///
- /// @return
- /// Returns \b true if we were able to start up the notification
- /// \b false otherwise.
- //------------------------------------------------------------------
- virtual bool
- StartNoticingNewThreads()
- {
- return true;
- }
-
- //------------------------------------------------------------------
- /// Call this to turn off the stop & notice new threads mode.
- ///
- /// @return
- /// Returns \b true if we were able to start up the notification
- /// \b false otherwise.
- //------------------------------------------------------------------
- virtual bool
- StopNoticingNewThreads()
- {
- return true;
- }
-
- void
- SetRunningUserExpression (bool on);
-
- //------------------------------------------------------------------
- // lldb::ExecutionContextScope pure virtual functions
- //------------------------------------------------------------------
- lldb::TargetSP
- CalculateTarget() override;
-
- lldb::ProcessSP
- CalculateProcess() override
- {
- return shared_from_this();
- }
-
- lldb::ThreadSP
- CalculateThread() override
- {
- return lldb::ThreadSP();
- }
-
- lldb::StackFrameSP
- CalculateStackFrame() override
- {
- return lldb::StackFrameSP();
- }
+ void AppendSTDERR(const char *s, size_t len);
- void
- CalculateExecutionContext(ExecutionContext &exe_ctx) override;
-
- void
- SetSTDIOFileDescriptor (int file_descriptor);
-
- //------------------------------------------------------------------
- // Add a permanent region of memory that should never be read or
- // written to. This can be used to ensure that memory reads or writes
- // to certain areas of memory never end up being sent to the
- // DoReadMemory or DoWriteMemory functions which can improve
- // performance.
- //------------------------------------------------------------------
- void
- AddInvalidMemoryRegion (const LoadRange &region);
-
- //------------------------------------------------------------------
- // Remove a permanent region of memory that should never be read or
- // written to that was previously added with AddInvalidMemoryRegion.
- //------------------------------------------------------------------
- bool
- RemoveInvalidMemoryRange (const LoadRange &region);
-
- //------------------------------------------------------------------
- // If the setup code of a thread plan needs to do work that might involve
- // calling a function in the target, it should not do that work directly
- // in one of the thread plan functions (DidPush/WillResume) because
- // such work needs to be handled carefully. Instead, put that work in
- // a PreResumeAction callback, and register it with the process. It will
- // get done before the actual "DoResume" gets called.
- //------------------------------------------------------------------
-
- typedef bool (PreResumeActionCallback)(void *);
-
- void
- AddPreResumeAction (PreResumeActionCallback callback, void *baton);
-
- bool
- RunPreResumeActions ();
-
- void
- ClearPreResumeActions ();
-
- ProcessRunLock &
- GetRunLock ();
-
- virtual Error
- SendEventData(const char *data)
- {
- Error return_error ("Sending an event is not supported for this process.");
- return return_error;
- }
-
- lldb::ThreadCollectionSP
- GetHistoryThreads(lldb::addr_t addr);
-
- lldb::InstrumentationRuntimeSP
- GetInstrumentationRuntime(lldb::InstrumentationRuntimeType type);
-
- //------------------------------------------------------------------
- /// Try to fetch the module specification for a module with the
- /// given file name and architecture. Process sub-classes have to
- /// override this method if they support platforms where the
- /// Platform object can't get the module spec for all module.
- ///
- /// @param[in] module_file_spec
- /// The file name of the module to get specification for.
- ///
- /// @param[in] arch
- /// The architecture of the module to get specification for.
- ///
- /// @param[out] module_spec
- /// The fetched module specification if the return value is
- /// \b true, unchanged otherwise.
- ///
- /// @return
- /// Returns \b true if the module spec fetched successfully,
- /// \b false otherwise.
- //------------------------------------------------------------------
- virtual bool
- GetModuleSpec(const FileSpec& module_file_spec, const ArchSpec& arch, ModuleSpec &module_spec);
-
- //------------------------------------------------------------------
- /// Try to find the load address of a file.
- /// The load address is defined as the address of the first memory
- /// region what contains data mapped from the specified file.
- ///
- /// @param[in] file
- /// The name of the file whose load address we are looking for
- ///
- /// @param[out] is_loaded
- /// \b True if the file is loaded into the memory and false
- /// otherwise.
- ///
- /// @param[out] load_addr
- /// The load address of the file if it is loaded into the
- /// processes address space, LLDB_INVALID_ADDRESS otherwise.
- //------------------------------------------------------------------
- virtual Error
- GetFileLoadAddress(const FileSpec& file, bool& is_loaded, lldb::addr_t& load_addr)
- {
- return Error("Not supported");
- }
+ void BroadcastAsyncProfileData(const std::string &one_profile_data);
- size_t
- AddImageToken(lldb::addr_t image_ptr);
-
- lldb::addr_t
- GetImagePtrFromToken(size_t token) const;
-
- void
- ResetImageToken(size_t token);
-
- //------------------------------------------------------------------
- /// Find the next branch instruction to set a breakpoint on
- ///
- /// When instruction stepping through a source line, instead of
- /// stepping through each instruction, we can put a breakpoint on
- /// the next branch instruction (within the range of instructions
- /// we are stepping through) and continue the process to there,
- /// yielding significant performance benefits over instruction
- /// stepping.
- ///
- /// @param[in] default_stop_addr
- /// The address of the instruction where lldb would put a
- /// breakpoint normally.
- ///
- /// @param[in] range_bounds
- /// The range which the breakpoint must be contained within.
- /// Typically a source line.
- ///
- /// @return
- /// The address of the next branch instruction, or the end of
- /// the range provided in range_bounds. If there are any
- /// problems with the disassembly or getting the instructions,
- /// the original default_stop_addr will be returned.
- //------------------------------------------------------------------
- Address
- AdvanceAddressToNextBranchInstruction (Address default_stop_addr,
- AddressRange range_bounds);
+ static void STDIOReadThreadBytesReceived(void *baton, const void *src,
+ size_t src_len);
-protected:
- void
- SetState (lldb::EventSP &event_sp);
-
- lldb::StateType
- GetPrivateState ();
-
- //------------------------------------------------------------------
- /// The "private" side of resuming a process. This doesn't alter the
- /// state of m_run_lock, but just causes the process to resume.
- ///
- /// @return
- /// An Error object describing the success or failure of the resume.
- //------------------------------------------------------------------
- Error
- PrivateResume ();
-
- //------------------------------------------------------------------
- // Called internally
- //------------------------------------------------------------------
- void
- CompleteAttach ();
-
- //------------------------------------------------------------------
- /// Print a user-visible warning one time per Process
- ///
- /// A facility for printing a warning to the user once per repeat_key.
- ///
- /// warning_type is from the Process::Warnings enums.
- /// repeat_key is a pointer value that will be used to ensure that the
- /// warning message is not printed multiple times. For instance, with a
- /// warning about a function being optimized, you can pass the CompileUnit
- /// pointer to have the warning issued for only the first function in a
- /// CU, or the Function pointer to have it issued once for every function,
- /// or a Module pointer to have it issued once per Module.
- ///
- /// Classes outside Process should call a specific PrintWarning method
- /// so that the warning strings are all centralized in Process, instead of
- /// calling PrintWarning() directly.
- ///
- /// @param [in] warning_type
- /// One of the types defined in Process::Warnings.
- ///
- /// @param [in] repeat_key
- /// A pointer value used to ensure that the warning is only printed once.
- /// May be nullptr, indicating that the warning is printed unconditionally
- /// every time.
- ///
- /// @param [in] fmt
- /// printf style format string
- //------------------------------------------------------------------
- void
- PrintWarning (uint64_t warning_type, const void *repeat_key, const char *fmt, ...) __attribute__((format(printf, 4, 5)));
-
- //------------------------------------------------------------------
- // NextEventAction provides a way to register an action on the next
- // event that is delivered to this process. There is currently only
- // one next event action allowed in the process at one time. If a
- // new "NextEventAction" is added while one is already present, the
- // old action will be discarded (with HandleBeingUnshipped called
- // after it is discarded.)
- //
- // If you want to resume the process as a result of a resume action,
- // call RequestResume, don't call Resume directly.
- //------------------------------------------------------------------
- class NextEventAction
- {
- public:
- typedef enum EventActionResult
- {
- eEventActionSuccess,
- eEventActionRetry,
- eEventActionExit
- } EventActionResult;
-
- NextEventAction (Process *process) :
- m_process(process)
- {
- }
-
- virtual
- ~NextEventAction() = default;
-
- virtual EventActionResult PerformAction (lldb::EventSP &event_sp) = 0;
- virtual void HandleBeingUnshipped () {}
- virtual EventActionResult HandleBeingInterrupted () = 0;
- virtual const char *GetExitString() = 0;
- void RequestResume()
- {
- m_process->m_resume_requested = true;
- }
-
- protected:
- Process *m_process;
- };
-
- void SetNextEventAction (Process::NextEventAction *next_event_action)
- {
- if (m_next_event_action_ap.get())
- m_next_event_action_ap->HandleBeingUnshipped();
-
- m_next_event_action_ap.reset(next_event_action);
- }
-
- // This is the completer for Attaching:
- class AttachCompletionHandler : public NextEventAction
- {
- public:
- AttachCompletionHandler (Process *process, uint32_t exec_count);
-
- ~AttachCompletionHandler() override = default;
-
- EventActionResult PerformAction(lldb::EventSP &event_sp) override;
- EventActionResult HandleBeingInterrupted() override;
- const char *GetExitString() override;
-
- private:
- uint32_t m_exec_count;
- std::string m_exit_string;
- };
-
- bool
- PrivateStateThreadIsValid () const
- {
- lldb::StateType state = m_private_state.GetValue();
- return state != lldb::eStateInvalid &&
- state != lldb::eStateDetached &&
- state != lldb::eStateExited &&
- m_private_state_thread.IsJoinable();
- }
+ bool PushProcessIOHandler();
- void
- ForceNextEventDelivery()
- {
- m_force_next_event_delivery = true;
- }
+ bool PopProcessIOHandler();
- //------------------------------------------------------------------
- // Type definitions
- //------------------------------------------------------------------
- typedef std::map<lldb::LanguageType, lldb::LanguageRuntimeSP> LanguageRuntimeCollection;
- typedef std::unordered_set<const void *> WarningsPointerSet;
- typedef std::map<uint64_t, WarningsPointerSet> WarningsCollection;
-
- struct PreResumeCallbackAndBaton
- {
- bool (*callback) (void *);
- void *baton;
- PreResumeCallbackAndBaton (PreResumeActionCallback in_callback, void *in_baton) :
- callback (in_callback),
- baton (in_baton)
- {
- }
- };
-
- //------------------------------------------------------------------
- // Member variables
- //------------------------------------------------------------------
- std::weak_ptr<Target> m_target_sp; ///< The target that owns this process.
- ThreadSafeValue<lldb::StateType> m_public_state;
- ThreadSafeValue<lldb::StateType> m_private_state; // The actual state of our process
- Broadcaster m_private_state_broadcaster; // This broadcaster feeds state changed events into the private state thread's listener.
- Broadcaster m_private_state_control_broadcaster; // This is the control broadcaster, used to pause, resume & stop the private state thread.
- lldb::ListenerSP m_private_state_listener_sp; // This is the listener for the private state thread.
- HostThread m_private_state_thread; ///< Thread ID for the thread that watches internal state events
- ProcessModID m_mod_id; ///< Tracks the state of the process over stops and other alterations.
- uint32_t m_process_unique_id; ///< Each lldb_private::Process class that is created gets a unique integer ID that increments with each new instance
- uint32_t m_thread_index_id; ///< Each thread is created with a 1 based index that won't get re-used.
- std::map<uint64_t, uint32_t> m_thread_id_to_index_id_map;
- int m_exit_status; ///< The exit status of the process, or -1 if not set.
- std::string m_exit_string; ///< A textual description of why a process exited.
- std::mutex
- m_exit_status_mutex; ///< Mutex so m_exit_status m_exit_string can be safely accessed from multiple threads
- std::recursive_mutex m_thread_mutex;
- ThreadList m_thread_list_real; ///< The threads for this process as are known to the protocol we are debugging with
- ThreadList m_thread_list; ///< The threads for this process as the user will see them. This is usually the same as
- ///< m_thread_list_real, but might be different if there is an OS plug-in creating memory threads
- ThreadList m_extended_thread_list; ///< Owner for extended threads that may be generated, cleared on natural stops
- uint32_t m_extended_thread_stop_id; ///< The natural stop id when extended_thread_list was last updated
- QueueList m_queue_list; ///< The list of libdispatch queues at a given stop point
- uint32_t m_queue_list_stop_id; ///< The natural stop id when queue list was last fetched
- std::vector<Notifications> m_notifications; ///< The list of notifications that this process can deliver.
- std::vector<lldb::addr_t> m_image_tokens;
- lldb::ListenerSP m_listener_sp; ///< Shared pointer to the listener used for public events. Can not be empty.
- BreakpointSiteList m_breakpoint_site_list; ///< This is the list of breakpoint locations we intend to insert in the target.
- lldb::DynamicLoaderUP m_dyld_ap;
- lldb::JITLoaderListUP m_jit_loaders_ap;
- lldb::DynamicCheckerFunctionsUP m_dynamic_checkers_ap; ///< The functions used by the expression parser to validate data that expressions use.
- lldb::OperatingSystemUP m_os_ap;
- lldb::SystemRuntimeUP m_system_runtime_ap;
- lldb::UnixSignalsSP m_unix_signals_sp; /// This is the current signal set for this process.
- lldb::ABISP m_abi_sp;
- lldb::IOHandlerSP m_process_input_reader;
- Communication m_stdio_communication;
- std::recursive_mutex m_stdio_communication_mutex;
- bool m_stdin_forward; /// Remember if stdin must be forwarded to remote debug server
- std::string m_stdout_data;
- std::string m_stderr_data;
- std::recursive_mutex m_profile_data_comm_mutex;
- std::vector<std::string> m_profile_data;
- Predicate<uint32_t> m_iohandler_sync;
- MemoryCache m_memory_cache;
- AllocatedMemoryCache m_allocated_memory_cache;
- bool m_should_detach; /// Should we detach if the process object goes away with an explicit call to Kill or Detach?
- LanguageRuntimeCollection m_language_runtimes;
- InstrumentationRuntimeCollection m_instrumentation_runtimes;
- std::unique_ptr<NextEventAction> m_next_event_action_ap;
- std::vector<PreResumeCallbackAndBaton> m_pre_resume_actions;
- ProcessRunLock m_public_run_lock;
- ProcessRunLock m_private_run_lock;
- ArchSpec::StopInfoOverrideCallbackType m_stop_info_override_callback;
- bool m_currently_handling_do_on_removals;
- bool m_resume_requested; // If m_currently_handling_event or m_currently_handling_do_on_removals are true, Resume will only request a resume, using this flag to check.
- bool m_finalizing; // This is set at the beginning of Process::Finalize() to stop functions from looking up or creating things during a finalize call
- bool m_finalize_called; // This is set at the end of Process::Finalize()
- bool m_clear_thread_plans_on_stop;
- bool m_force_next_event_delivery;
- lldb::StateType m_last_broadcast_state; /// This helps with the Public event coalescing in ShouldBroadcastEvent.
- std::map<lldb::addr_t,lldb::addr_t> m_resolved_indirect_addresses;
- bool m_destroy_in_process;
- bool m_can_interpret_function_calls; // Some targets, e.g the OSX kernel, don't support the ability to modify the stack.
- WarningsCollection m_warnings_issued; // A set of object pointers which have already had warnings printed
- std::mutex m_run_thread_plan_lock;
-
- enum {
- eCanJITDontKnow= 0,
- eCanJITYes,
- eCanJITNo
- } m_can_jit;
-
- size_t
- RemoveBreakpointOpcodesFromBuffer (lldb::addr_t addr, size_t size, uint8_t *buf) const;
-
- void
- SynchronouslyNotifyStateChanged (lldb::StateType state);
-
- void
- SetPublicState (lldb::StateType new_state, bool restarted);
-
- void
- SetPrivateState (lldb::StateType state);
-
- bool
- StartPrivateStateThread (bool is_secondary_thread = false);
-
- void
- StopPrivateStateThread ();
-
- void
- PausePrivateStateThread ();
-
- void
- ResumePrivateStateThread ();
+ bool ProcessIOHandlerIsActive();
-private:
- struct PrivateStateThreadArgs
- {
- PrivateStateThreadArgs(Process *p, bool s) : process(p), is_secondary_thread(s) {};
- Process *process;
- bool is_secondary_thread;
- };
-
- // arg is a pointer to a new'ed PrivateStateThreadArgs structure. PrivateStateThread will free it for you.
- static lldb::thread_result_t
- PrivateStateThread (void *arg);
-
- // The starts up the private state thread that will watch for events from the debugee.
- // Pass true for is_secondary_thread in the case where you have to temporarily spin up a
- // secondary state thread to handle events from a hand-called function on the primary
- // private state thread.
-
- lldb::thread_result_t
- RunPrivateStateThread (bool is_secondary_thread);
+ bool ProcessIOHandlerExists() const {
+ return static_cast<bool>(m_process_input_reader);
+ }
-protected:
- void
- HandlePrivateEvent (lldb::EventSP &event_sp);
-
- Error
- HaltPrivate();
-
- lldb::StateType
- WaitForProcessStopPrivate (const TimeValue *timeout, lldb::EventSP &event_sp);
-
- // This waits for both the state change broadcaster, and the control broadcaster.
- // If control_only, it only waits for the control broadcaster.
-
- bool
- WaitForEventsPrivate (const TimeValue *timeout, lldb::EventSP &event_sp, bool control_only);
-
- lldb::StateType
- WaitForStateChangedEventsPrivate (const TimeValue *timeout, lldb::EventSP &event_sp);
-
- lldb::StateType
- WaitForState (const TimeValue *timeout,
- const lldb::StateType *match_states,
- const uint32_t num_match_states);
-
- size_t
- WriteMemoryPrivate (lldb::addr_t addr, const void *buf, size_t size, Error &error);
-
- void
- AppendSTDOUT (const char *s, size_t len);
-
- void
- AppendSTDERR (const char *s, size_t len);
-
- void
- BroadcastAsyncProfileData(const std::string &one_profile_data);
-
- static void
- STDIOReadThreadBytesReceived (void *baton, const void *src, size_t src_len);
-
- bool
- PushProcessIOHandler ();
-
- bool
- PopProcessIOHandler ();
-
- bool
- ProcessIOHandlerIsActive ();
-
- bool
- ProcessIOHandlerExists () const
- {
- return static_cast<bool>(m_process_input_reader);
- }
-
- Error
- StopForDestroyOrDetach(lldb::EventSP &exit_event_sp);
+ Error StopForDestroyOrDetach(lldb::EventSP &exit_event_sp);
- bool
- StateChangedIsExternallyHijacked();
+ bool StateChangedIsExternallyHijacked();
- void
- LoadOperatingSystemPlugin(bool flush);
+ void LoadOperatingSystemPlugin(bool flush);
private:
- //------------------------------------------------------------------
- /// This is the part of the event handling that for a process event.
- /// It decides what to do with the event and returns true if the
- /// event needs to be propagated to the user, and false otherwise.
- /// If the event is not propagated, this call will most likely set
- /// the target to executing again.
- /// There is only one place where this call should be called, HandlePrivateEvent.
- /// Don't call it from anywhere else...
- ///
- /// @param[in] event_ptr
- /// This is the event we are handling.
- ///
- /// @return
- /// Returns \b true if the event should be reported to the
- /// user, \b false otherwise.
- //------------------------------------------------------------------
- bool
- ShouldBroadcastEvent (Event *event_ptr);
-
- void ControlPrivateStateThread (uint32_t signal);
-
- DISALLOW_COPY_AND_ASSIGN (Process);
+ //------------------------------------------------------------------
+ /// This is the part of the event handling that for a process event.
+ /// It decides what to do with the event and returns true if the
+ /// event needs to be propagated to the user, and false otherwise.
+ /// If the event is not propagated, this call will most likely set
+ /// the target to executing again.
+ /// There is only one place where this call should be called,
+ /// HandlePrivateEvent.
+ /// Don't call it from anywhere else...
+ ///
+ /// @param[in] event_ptr
+ /// This is the event we are handling.
+ ///
+ /// @return
+ /// Returns \b true if the event should be reported to the
+ /// user, \b false otherwise.
+ //------------------------------------------------------------------
+ bool ShouldBroadcastEvent(Event *event_ptr);
+
+ void ControlPrivateStateThread(uint32_t signal);
+
+ DISALLOW_COPY_AND_ASSIGN(Process);
};
} // namespace lldb_private
diff --git a/include/lldb/Target/ProcessInfo.h b/include/lldb/Target/ProcessInfo.h
index 1539e043d6fc..f8d37fa4ebb4 100644
--- a/include/lldb/Target/ProcessInfo.h
+++ b/include/lldb/Target/ProcessInfo.h
@@ -15,174 +15,89 @@
#include "lldb/Host/FileSpec.h"
#include "lldb/Interpreter/Args.h"
-namespace lldb_private
-{
- //----------------------------------------------------------------------
- // ProcessInfo
- //
- // A base class for information for a process. This can be used to fill
- // out information for a process prior to launching it, or it can be
- // used for an instance of a process and can be filled in with the
- // existing values for that process.
- //----------------------------------------------------------------------
- class ProcessInfo
- {
- public:
- ProcessInfo ();
-
- ProcessInfo (const char *name,
- const ArchSpec &arch,
- lldb::pid_t pid);
-
- void
- Clear ();
-
- const char *
- GetName() const;
-
- size_t
- GetNameLength() const;
-
- FileSpec &
- GetExecutableFile ()
- {
- return m_executable;
- }
-
- void
- SetExecutableFile (const FileSpec &exe_file, bool add_exe_file_as_first_arg);
-
- const FileSpec &
- GetExecutableFile () const
- {
- return m_executable;
- }
-
- uint32_t
- GetUserID() const
- {
- return m_uid;
- }
-
- uint32_t
- GetGroupID() const
- {
- return m_gid;
- }
-
- bool
- UserIDIsValid () const
- {
- return m_uid != UINT32_MAX;
- }
-
- bool
- GroupIDIsValid () const
- {
- return m_gid != UINT32_MAX;
- }
-
- void
- SetUserID (uint32_t uid)
- {
- m_uid = uid;
- }
-
- void
- SetGroupID (uint32_t gid)
- {
- m_gid = gid;
- }
-
- ArchSpec &
- GetArchitecture ()
- {
- return m_arch;
- }
-
- const ArchSpec &
- GetArchitecture () const
- {
- return m_arch;
- }
-
- void
- SetArchitecture (const ArchSpec& arch)
- {
- m_arch = arch;
- }
-
- lldb::pid_t
- GetProcessID () const
- {
- return m_pid;
- }
-
- void
- SetProcessID (lldb::pid_t pid)
- {
- m_pid = pid;
- }
-
- bool
- ProcessIDIsValid() const
- {
- return m_pid != LLDB_INVALID_PROCESS_ID;
- }
-
- void
- Dump (Stream &s, Platform *platform) const;
-
- Args &
- GetArguments ()
- {
- return m_arguments;
- }
-
- const Args &
- GetArguments () const
- {
- return m_arguments;
- }
-
- const char *
- GetArg0 () const;
-
- void
- SetArg0 (const char *arg);
-
- void
- SetArguments (const Args& args, bool first_arg_is_executable);
-
- void
- SetArguments (char const **argv, bool first_arg_is_executable);
-
- Args &
- GetEnvironmentEntries ()
- {
- return m_environment;
- }
-
- const Args &
- GetEnvironmentEntries () const
- {
- return m_environment;
- }
-
- protected:
- FileSpec m_executable;
- std::string m_arg0; // argv[0] if supported. If empty, then use m_executable.
- // Not all process plug-ins support specifying an argv[0]
- // that differs from the resolved platform executable
- // (which is in m_executable)
- Args m_arguments; // All program arguments except argv[0]
- Args m_environment;
- uint32_t m_uid;
- uint32_t m_gid;
- ArchSpec m_arch;
- lldb::pid_t m_pid;
- };
+namespace lldb_private {
+//----------------------------------------------------------------------
+// ProcessInfo
+//
+// A base class for information for a process. This can be used to fill
+// out information for a process prior to launching it, or it can be
+// used for an instance of a process and can be filled in with the
+// existing values for that process.
+//----------------------------------------------------------------------
+class ProcessInfo {
+public:
+ ProcessInfo();
+
+ ProcessInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid);
+
+ void Clear();
+
+ const char *GetName() const;
+
+ size_t GetNameLength() const;
+
+ FileSpec &GetExecutableFile() { return m_executable; }
+
+ void SetExecutableFile(const FileSpec &exe_file,
+ bool add_exe_file_as_first_arg);
+
+ const FileSpec &GetExecutableFile() const { return m_executable; }
+
+ uint32_t GetUserID() const { return m_uid; }
+
+ uint32_t GetGroupID() const { return m_gid; }
+
+ bool UserIDIsValid() const { return m_uid != UINT32_MAX; }
+
+ bool GroupIDIsValid() const { return m_gid != UINT32_MAX; }
+
+ void SetUserID(uint32_t uid) { m_uid = uid; }
+
+ void SetGroupID(uint32_t gid) { m_gid = gid; }
+
+ ArchSpec &GetArchitecture() { return m_arch; }
+
+ const ArchSpec &GetArchitecture() const { return m_arch; }
+
+ void SetArchitecture(const ArchSpec &arch) { m_arch = arch; }
+
+ lldb::pid_t GetProcessID() const { return m_pid; }
+
+ void SetProcessID(lldb::pid_t pid) { m_pid = pid; }
+
+ bool ProcessIDIsValid() const { return m_pid != LLDB_INVALID_PROCESS_ID; }
+
+ void Dump(Stream &s, Platform *platform) const;
+
+ Args &GetArguments() { return m_arguments; }
+
+ const Args &GetArguments() const { return m_arguments; }
+
+ llvm::StringRef GetArg0() const;
+
+ void SetArg0(llvm::StringRef arg);
+
+ void SetArguments(const Args &args, bool first_arg_is_executable);
+
+ void SetArguments(char const **argv, bool first_arg_is_executable);
+
+ Args &GetEnvironmentEntries() { return m_environment; }
+
+ const Args &GetEnvironmentEntries() const { return m_environment; }
+
+protected:
+ FileSpec m_executable;
+ std::string m_arg0; // argv[0] if supported. If empty, then use m_executable.
+ // Not all process plug-ins support specifying an argv[0]
+ // that differs from the resolved platform executable
+ // (which is in m_executable)
+ Args m_arguments; // All program arguments except argv[0]
+ Args m_environment;
+ uint32_t m_uid;
+ uint32_t m_gid;
+ ArchSpec m_arch;
+ lldb::pid_t m_pid;
+};
}
#endif // #ifndef liblldb_ProcessInfo_h_
-
diff --git a/include/lldb/Target/ProcessLaunchInfo.h b/include/lldb/Target/ProcessLaunchInfo.h
index d1a45794b551..2c192c24da87 100644
--- a/include/lldb/Target/ProcessLaunchInfo.h
+++ b/include/lldb/Target/ProcessLaunchInfo.h
@@ -21,224 +21,144 @@
#include "lldb/Target/ProcessInfo.h"
#include "lldb/Utility/PseudoTerminal.h"
-namespace lldb_private
-{
-
- //----------------------------------------------------------------------
- // ProcessLaunchInfo
- //
- // Describes any information that is required to launch a process.
- //----------------------------------------------------------------------
-
- class ProcessLaunchInfo : public ProcessInfo
- {
- public:
-
- ProcessLaunchInfo ();
-
- ProcessLaunchInfo(const FileSpec &stdin_file_spec,
- const FileSpec &stdout_file_spec,
- const FileSpec &stderr_file_spec,
- const FileSpec &working_dir,
- uint32_t launch_flags);
-
- void
- AppendFileAction (const FileAction &info)
- {
- m_file_actions.push_back(info);
- }
-
- bool
- AppendCloseFileAction (int fd);
-
- bool
- AppendDuplicateFileAction (int fd, int dup_fd);
-
- bool
- AppendOpenFileAction(int fd, const FileSpec &file_spec,
- bool read, bool write);
-
- bool
- AppendSuppressFileAction (int fd, bool read, bool write);
-
- void
- FinalizeFileActions (Target *target,
- bool default_to_use_pty);
-
- size_t
- GetNumFileActions () const
- {
- return m_file_actions.size();
- }
-
- const FileAction *
- GetFileActionAtIndex (size_t idx) const;
-
- const FileAction *
- GetFileActionForFD (int fd) const;
-
- Flags &
- GetFlags ()
- {
- return m_flags;
- }
-
- const Flags &
- GetFlags () const
- {
- return m_flags;
- }
-
- const FileSpec &
- GetWorkingDirectory() const;
-
- void
- SetWorkingDirectory(const FileSpec &working_dir);
-
- const char *
- GetProcessPluginName () const;
-
- void
- SetProcessPluginName (const char *plugin);
-
- const FileSpec &
- GetShell () const;
-
- void
- SetShell (const FileSpec &shell);
-
- uint32_t
- GetResumeCount () const
- {
- return m_resume_count;
- }
-
- void
- SetResumeCount (uint32_t c)
- {
- m_resume_count = c;
- }
-
- bool
- GetLaunchInSeparateProcessGroup() const
- {
- return m_flags.Test(lldb::eLaunchFlagLaunchInSeparateProcessGroup);
- }
-
- void
- SetLaunchInSeparateProcessGroup (bool separate);
-
- bool
- GetShellExpandArguments () const
- {
- return m_flags.Test(lldb::eLaunchFlagShellExpandArguments);
- }
-
- void
- SetShellExpandArguments (bool expand);
-
- void
- Clear ();
-
- bool
- ConvertArgumentsForLaunchingInShell (Error &error,
- bool localhost,
- bool will_debug,
- bool first_arg_is_full_shell_command,
- int32_t num_resumes);
-
- void
- SetMonitorProcessCallback(const Host::MonitorChildProcessCallback &callback, bool monitor_signals);
-
- Host::MonitorChildProcessCallback
- GetMonitorProcessCallback() const
- {
- return m_monitor_callback;
- }
-
- bool
- GetMonitorSignals() const
- {
- return m_monitor_signals;
- }
-
- // If the LaunchInfo has a monitor callback, then arrange to monitor the process.
- // Return true if the LaunchInfo has taken care of monitoring the process, and false if the
- // caller might want to monitor the process themselves.
-
- bool
- MonitorProcess () const;
-
- lldb_utility::PseudoTerminal &
- GetPTY ()
- {
- return *m_pty;
- }
-
- // Get and set the actual listener that will be used for the process events
- lldb::ListenerSP
- GetListener () const
- {
- return m_listener_sp;
- }
-
- void
- SetListener (const lldb::ListenerSP &listener_sp)
- {
- m_listener_sp = listener_sp;
- }
-
- lldb::ListenerSP
- GetListenerForProcess (Debugger &debugger);
-
- lldb::ListenerSP
- GetHijackListener () const
- {
- return m_hijack_listener_sp;
- }
-
- void
- SetHijackListener (const lldb::ListenerSP &listener_sp)
- {
- m_hijack_listener_sp = listener_sp;
- }
-
- void
- SetLaunchEventData (const char *data)
- {
- m_event_data.assign (data);
- }
-
- const char *
- GetLaunchEventData () const
- {
- return m_event_data.c_str();
- }
-
- void
- SetDetachOnError (bool enable);
-
- bool
- GetDetachOnError () const
- {
- return m_flags.Test(lldb::eLaunchFlagDetachOnError);
- }
-
- protected:
- FileSpec m_working_dir;
- std::string m_plugin_name;
- FileSpec m_shell;
- Flags m_flags; // Bitwise OR of bits from lldb::LaunchFlags
- std::vector<FileAction> m_file_actions; // File actions for any other files
- std::shared_ptr<lldb_utility::PseudoTerminal> m_pty;
- uint32_t m_resume_count; // How many times do we resume after launching
- Host::MonitorChildProcessCallback m_monitor_callback;
- void *m_monitor_callback_baton;
- bool m_monitor_signals;
- std::string m_event_data; // A string passed to the plugin launch, having no meaning to the upper levels of lldb.
- lldb::ListenerSP m_listener_sp;
- lldb::ListenerSP m_hijack_listener_sp;
- };
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+// ProcessLaunchInfo
+//
+// Describes any information that is required to launch a process.
+//----------------------------------------------------------------------
+
+class ProcessLaunchInfo : public ProcessInfo {
+public:
+ ProcessLaunchInfo();
+
+ ProcessLaunchInfo(const FileSpec &stdin_file_spec,
+ const FileSpec &stdout_file_spec,
+ const FileSpec &stderr_file_spec,
+ const FileSpec &working_dir, uint32_t launch_flags);
+
+ void AppendFileAction(const FileAction &info) {
+ m_file_actions.push_back(info);
+ }
+
+ bool AppendCloseFileAction(int fd);
+
+ bool AppendDuplicateFileAction(int fd, int dup_fd);
+
+ bool AppendOpenFileAction(int fd, const FileSpec &file_spec, bool read,
+ bool write);
+
+ bool AppendSuppressFileAction(int fd, bool read, bool write);
+
+ void FinalizeFileActions(Target *target, bool default_to_use_pty);
+
+ size_t GetNumFileActions() const { return m_file_actions.size(); }
+
+ const FileAction *GetFileActionAtIndex(size_t idx) const;
+
+ const FileAction *GetFileActionForFD(int fd) const;
+
+ Flags &GetFlags() { return m_flags; }
+
+ const Flags &GetFlags() const { return m_flags; }
+
+ const FileSpec &GetWorkingDirectory() const;
+
+ void SetWorkingDirectory(const FileSpec &working_dir);
+
+ const char *GetProcessPluginName() const;
+
+ void SetProcessPluginName(llvm::StringRef plugin);
+
+ const FileSpec &GetShell() const;
+
+ void SetShell(const FileSpec &shell);
+
+ uint32_t GetResumeCount() const { return m_resume_count; }
+
+ void SetResumeCount(uint32_t c) { m_resume_count = c; }
+
+ bool GetLaunchInSeparateProcessGroup() const {
+ return m_flags.Test(lldb::eLaunchFlagLaunchInSeparateProcessGroup);
+ }
+
+ void SetLaunchInSeparateProcessGroup(bool separate);
+
+ bool GetShellExpandArguments() const {
+ return m_flags.Test(lldb::eLaunchFlagShellExpandArguments);
+ }
+
+ void SetShellExpandArguments(bool expand);
+
+ void Clear();
+
+ bool ConvertArgumentsForLaunchingInShell(Error &error, bool localhost,
+ bool will_debug,
+ bool first_arg_is_full_shell_command,
+ int32_t num_resumes);
+
+ void
+ SetMonitorProcessCallback(const Host::MonitorChildProcessCallback &callback,
+ bool monitor_signals);
+
+ Host::MonitorChildProcessCallback GetMonitorProcessCallback() const {
+ return m_monitor_callback;
+ }
+
+ bool GetMonitorSignals() const { return m_monitor_signals; }
+
+ // If the LaunchInfo has a monitor callback, then arrange to monitor the
+ // process.
+ // Return true if the LaunchInfo has taken care of monitoring the process, and
+ // false if the
+ // caller might want to monitor the process themselves.
+
+ bool MonitorProcess() const;
+
+ lldb_utility::PseudoTerminal &GetPTY() { return *m_pty; }
+
+ // Get and set the actual listener that will be used for the process events
+ lldb::ListenerSP GetListener() const { return m_listener_sp; }
+
+ void SetListener(const lldb::ListenerSP &listener_sp) {
+ m_listener_sp = listener_sp;
+ }
+
+ lldb::ListenerSP GetListenerForProcess(Debugger &debugger);
+
+ lldb::ListenerSP GetHijackListener() const { return m_hijack_listener_sp; }
+
+ void SetHijackListener(const lldb::ListenerSP &listener_sp) {
+ m_hijack_listener_sp = listener_sp;
+ }
+
+ void SetLaunchEventData(const char *data) { m_event_data.assign(data); }
+
+ const char *GetLaunchEventData() const { return m_event_data.c_str(); }
+
+ void SetDetachOnError(bool enable);
+
+ bool GetDetachOnError() const {
+ return m_flags.Test(lldb::eLaunchFlagDetachOnError);
+ }
+
+protected:
+ FileSpec m_working_dir;
+ std::string m_plugin_name;
+ FileSpec m_shell;
+ Flags m_flags; // Bitwise OR of bits from lldb::LaunchFlags
+ std::vector<FileAction> m_file_actions; // File actions for any other files
+ std::shared_ptr<lldb_utility::PseudoTerminal> m_pty;
+ uint32_t m_resume_count; // How many times do we resume after launching
+ Host::MonitorChildProcessCallback m_monitor_callback;
+ void *m_monitor_callback_baton;
+ bool m_monitor_signals;
+ std::string m_event_data; // A string passed to the plugin launch, having no
+ // meaning to the upper levels of lldb.
+ lldb::ListenerSP m_listener_sp;
+ lldb::ListenerSP m_hijack_listener_sp;
+};
}
#endif // liblldb_ProcessLaunch_Info_h
diff --git a/include/lldb/Target/Queue.h b/include/lldb/Target/Queue.h
index 514481fe8c9d..2df4d54a89b6 100644
--- a/include/lldb/Target/Queue.h
+++ b/include/lldb/Target/Queue.h
@@ -10,21 +10,20 @@
#ifndef liblldb_Queue_h_
#define liblldb_Queue_h_
-#include <vector>
#include <string>
+#include <vector>
-#include "lldb/lldb-forward.h"
+#include "lldb/Target/QueueItem.h"
#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
#include "lldb/lldb-private.h"
-#include "lldb/Target/QueueItem.h"
-
namespace lldb_private {
//------------------------------------------------------------------
// Queue:
// This class represents a libdispatch aka Grand Central Dispatch
-// queue in the process.
+// queue in the process.
//
// A program using libdispatch will create queues, put work items
// (functions, blocks) on the queues. The system will create /
@@ -34,169 +33,147 @@ namespace lldb_private {
// be associated with multiple threads.
//------------------------------------------------------------------
-
-class Queue :
- public std::enable_shared_from_this<Queue>
-{
+class Queue : public std::enable_shared_from_this<Queue> {
public:
-
- Queue (lldb::ProcessSP process_sp, lldb::queue_id_t queue_id, const char *queue_name);
-
- ~Queue ();
-
- //------------------------------------------------------------------
- /// Get the QueueID for this Queue
- ///
- /// A 64-bit ID number that uniquely identifies a queue at this particular
- /// stop_id. Currently the libdispatch serialnum is used for the QueueID;
- /// it is a number that starts at 1 for each process and increments with
- /// each queue. A serialnum is not reused for a different queue in the
- /// lifetime of that process execution.
- ///
- /// @return
- /// The QueueID for this Queue.
- //------------------------------------------------------------------
- lldb::queue_id_t
- GetID ();
-
- //------------------------------------------------------------------
- /// Get the name of this Queue
- ///
- /// @return
- /// The name of the queue, if one is available.
- /// A NULL pointer is returned if none is available.
- //------------------------------------------------------------------
- const char *
- GetName ();
-
- //------------------------------------------------------------------
- /// Get the IndexID for this Queue
- ///
- /// This is currently the same as GetID(). If it changes in the future,
- /// it will be a small integer value (starting with 1) assigned to
- /// each queue that is seen during a Process lifetime.
- ///
- /// Both the GetID and GetIndexID are being retained for Queues to
- /// maintain similar API to the Thread class, and allow for the
- /// possibility of GetID changing to a different source in the future.
- ///
- /// @return
- /// The IndexID for this queue.
- //------------------------------------------------------------------
- uint32_t
- GetIndexID ();
-
- //------------------------------------------------------------------
- /// Return the threads currently associated with this queue
- ///
- /// Zero, one, or many threads may be executing code for a queue at
- /// a given point in time. This call returns the list of threads
- /// that are currently executing work for this queue.
- ///
- /// @return
- /// The threads currently performing work for this queue
- //------------------------------------------------------------------
- std::vector<lldb::ThreadSP>
- GetThreads ();
-
- //------------------------------------------------------------------
- /// Return the items that are currently enqueued
- ///
- /// "Enqueued" means that the item has been added to the queue to
- /// be done, but has not yet been done. When the item is going to
- /// be processed it is "dequeued".
- ///
- /// @return
- /// The vector of enqueued items for this queue
- //------------------------------------------------------------------
- const std::vector<lldb::QueueItemSP> &
- GetPendingItems();
-
- lldb::ProcessSP
- GetProcess() const
- {
- return m_process_wp.lock();
- }
-
- //------------------------------------------------------------------
- /// Get the number of work items that this queue is currently running
- ///
- /// @return
- /// The number of work items currently executing. For a serial
- /// queue, this will be 0 or 1. For a concurrent queue, this
- /// may be any number.
- //------------------------------------------------------------------
- uint32_t
- GetNumRunningWorkItems () const;
-
- //------------------------------------------------------------------
- /// Get the number of work items enqueued on this queue
- ///
- /// @return
- /// The number of work items currently enqueued, waiting to
- /// execute.
- //------------------------------------------------------------------
- uint32_t
- GetNumPendingWorkItems () const;
-
- //------------------------------------------------------------------
- /// Get the dispatch_queue_t structure address for this Queue
- ///
- /// Get the address in the inferior process' memory of this Queue's
- /// dispatch_queue_t structure.
- ///
- /// @return
- /// The address of the dispatch_queue_t structure, if known.
- /// LLDB_INVALID_ADDRESS will be returned if it is unavailable.
- //------------------------------------------------------------------
- lldb::addr_t
- GetLibdispatchQueueAddress () const;
-
-
- void
- SetNumRunningWorkItems (uint32_t count);
-
- void
- SetNumPendingWorkItems (uint32_t count);
-
- void
- SetLibdispatchQueueAddress (lldb::addr_t dispatch_queue_t_addr);
-
- void
- PushPendingQueueItem (lldb::QueueItemSP item)
- {
- m_pending_items.push_back (item);
- }
-
- //------------------------------------------------------------------
- /// Return the kind (serial, concurrent) of this queue
- ///
- /// @return
- // Whether this is a serial or a concurrent queue
- //------------------------------------------------------------------
- lldb::QueueKind
- GetKind ();
-
- void
- SetKind (lldb::QueueKind kind);
+ Queue(lldb::ProcessSP process_sp, lldb::queue_id_t queue_id,
+ const char *queue_name);
+
+ ~Queue();
+
+ //------------------------------------------------------------------
+ /// Get the QueueID for this Queue
+ ///
+ /// A 64-bit ID number that uniquely identifies a queue at this particular
+ /// stop_id. Currently the libdispatch serialnum is used for the QueueID;
+ /// it is a number that starts at 1 for each process and increments with
+ /// each queue. A serialnum is not reused for a different queue in the
+ /// lifetime of that process execution.
+ ///
+ /// @return
+ /// The QueueID for this Queue.
+ //------------------------------------------------------------------
+ lldb::queue_id_t GetID();
+
+ //------------------------------------------------------------------
+ /// Get the name of this Queue
+ ///
+ /// @return
+ /// The name of the queue, if one is available.
+ /// A NULL pointer is returned if none is available.
+ //------------------------------------------------------------------
+ const char *GetName();
+
+ //------------------------------------------------------------------
+ /// Get the IndexID for this Queue
+ ///
+ /// This is currently the same as GetID(). If it changes in the future,
+ /// it will be a small integer value (starting with 1) assigned to
+ /// each queue that is seen during a Process lifetime.
+ ///
+ /// Both the GetID and GetIndexID are being retained for Queues to
+ /// maintain similar API to the Thread class, and allow for the
+ /// possibility of GetID changing to a different source in the future.
+ ///
+ /// @return
+ /// The IndexID for this queue.
+ //------------------------------------------------------------------
+ uint32_t GetIndexID();
+
+ //------------------------------------------------------------------
+ /// Return the threads currently associated with this queue
+ ///
+ /// Zero, one, or many threads may be executing code for a queue at
+ /// a given point in time. This call returns the list of threads
+ /// that are currently executing work for this queue.
+ ///
+ /// @return
+ /// The threads currently performing work for this queue
+ //------------------------------------------------------------------
+ std::vector<lldb::ThreadSP> GetThreads();
+
+ //------------------------------------------------------------------
+ /// Return the items that are currently enqueued
+ ///
+ /// "Enqueued" means that the item has been added to the queue to
+ /// be done, but has not yet been done. When the item is going to
+ /// be processed it is "dequeued".
+ ///
+ /// @return
+ /// The vector of enqueued items for this queue
+ //------------------------------------------------------------------
+ const std::vector<lldb::QueueItemSP> &GetPendingItems();
+
+ lldb::ProcessSP GetProcess() const { return m_process_wp.lock(); }
+
+ //------------------------------------------------------------------
+ /// Get the number of work items that this queue is currently running
+ ///
+ /// @return
+ /// The number of work items currently executing. For a serial
+ /// queue, this will be 0 or 1. For a concurrent queue, this
+ /// may be any number.
+ //------------------------------------------------------------------
+ uint32_t GetNumRunningWorkItems() const;
+
+ //------------------------------------------------------------------
+ /// Get the number of work items enqueued on this queue
+ ///
+ /// @return
+ /// The number of work items currently enqueued, waiting to
+ /// execute.
+ //------------------------------------------------------------------
+ uint32_t GetNumPendingWorkItems() const;
+
+ //------------------------------------------------------------------
+ /// Get the dispatch_queue_t structure address for this Queue
+ ///
+ /// Get the address in the inferior process' memory of this Queue's
+ /// dispatch_queue_t structure.
+ ///
+ /// @return
+ /// The address of the dispatch_queue_t structure, if known.
+ /// LLDB_INVALID_ADDRESS will be returned if it is unavailable.
+ //------------------------------------------------------------------
+ lldb::addr_t GetLibdispatchQueueAddress() const;
+
+ void SetNumRunningWorkItems(uint32_t count);
+
+ void SetNumPendingWorkItems(uint32_t count);
+
+ void SetLibdispatchQueueAddress(lldb::addr_t dispatch_queue_t_addr);
+
+ void PushPendingQueueItem(lldb::QueueItemSP item) {
+ m_pending_items.push_back(item);
+ }
+
+ //------------------------------------------------------------------
+ /// Return the kind (serial, concurrent) of this queue
+ ///
+ /// @return
+ // Whether this is a serial or a concurrent queue
+ //------------------------------------------------------------------
+ lldb::QueueKind GetKind();
+
+ void SetKind(lldb::QueueKind kind);
private:
- //------------------------------------------------------------------
- // For Queue only
- //------------------------------------------------------------------
-
- lldb::ProcessWP m_process_wp;
- lldb::queue_id_t m_queue_id;
- std::string m_queue_name;
- uint32_t m_running_work_items_count;
- uint32_t m_pending_work_items_count;
- std::vector<lldb::QueueItemSP> m_pending_items;
- lldb::addr_t m_dispatch_queue_t_addr; // address of libdispatch dispatch_queue_t for this Queue
- lldb::QueueKind m_kind;
-
- DISALLOW_COPY_AND_ASSIGN (Queue);
+ //------------------------------------------------------------------
+ // For Queue only
+ //------------------------------------------------------------------
+
+ lldb::ProcessWP m_process_wp;
+ lldb::queue_id_t m_queue_id;
+ std::string m_queue_name;
+ uint32_t m_running_work_items_count;
+ uint32_t m_pending_work_items_count;
+ std::vector<lldb::QueueItemSP> m_pending_items;
+ lldb::addr_t m_dispatch_queue_t_addr; // address of libdispatch
+ // dispatch_queue_t for this Queue
+ lldb::QueueKind m_kind;
+
+ DISALLOW_COPY_AND_ASSIGN(Queue);
};
} // namespace lldb_private
-#endif // liblldb_Queue_h_
+#endif // liblldb_Queue_h_
diff --git a/include/lldb/Target/QueueItem.h b/include/lldb/Target/QueueItem.h
index aea506644c37..f6378502c19c 100644
--- a/include/lldb/Target/QueueItem.h
+++ b/include/lldb/Target/QueueItem.h
@@ -18,9 +18,9 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/ConstString.h"
@@ -33,197 +33,153 @@ namespace lldb_private {
// Grand Central Dispatch (GCD) queue. Most often, this will be a
// function or block.
// "enqueued" here means that the work item has been added to a queue
-// but it has not yet started executing. When it is "dequeued",
+// but it has not yet started executing. When it is "dequeued",
// execution of the item begins.
//------------------------------------------------------------------
-class QueueItem :
- public std::enable_shared_from_this<QueueItem>
-{
+class QueueItem : public std::enable_shared_from_this<QueueItem> {
public:
- QueueItem (lldb::QueueSP queue_sp, lldb::ProcessSP process_sp, lldb::addr_t item_ref, lldb_private::Address address);
-
- ~QueueItem ();
-
- //------------------------------------------------------------------
- /// Get the kind of work item this is
- ///
- /// @return
- /// The type of work item that this QueueItem object
- /// represents. eQueueItemKindUnknown may be returned.
- //------------------------------------------------------------------
- lldb::QueueItemKind
- GetKind ();
-
- //------------------------------------------------------------------
- /// Set the type of work item this is
- ///
- /// @param [in] item_kind
- /// Set the kind of this work item object.
- //------------------------------------------------------------------
- void
- SetKind (lldb::QueueItemKind item_kind);
-
- //------------------------------------------------------------------
- /// Get the code address that will be executed when this work item
- /// is executed.
- ///
- /// @return
- /// The address that will be invoked when this work item is
- /// executed. Not all types of QueueItems will have an
- /// address associated with them; check that the returned
- /// Address is valid, or check that the WorkItemKind is a
- /// kind that involves an address, such as eQueueItemKindFunction
- /// or eQueueItemKindBlock.
- //------------------------------------------------------------------
- lldb_private::Address &
- GetAddress ();
-
- //------------------------------------------------------------------
- /// Set the work item address for this object
- ///
- /// @param [in] addr
- /// The address that will be invoked when this work item
- /// is executed.
- //------------------------------------------------------------------
- void
- SetAddress (lldb_private::Address addr);
-
- //------------------------------------------------------------------
- /// Check if this QueueItem object is valid
- ///
- /// If the weak pointer to the parent Queue cannot be revivified,
- /// it is invalid.
- ///
- /// @return
- /// True if this object is valid.
- //------------------------------------------------------------------
- bool
- IsValid ()
- {
- return m_queue_wp.lock() != nullptr;
- }
-
- //------------------------------------------------------------------
- /// Get an extended backtrace thread for this queue item, if available
- ///
- /// If the backtrace/thread information was collected when this item
- /// was enqueued, this call will provide it.
- ///
- /// @param [in] type
- /// The type of extended backtrace being requested, e.g. "libdispatch"
- /// or "pthread".
- ///
- /// @return
- /// A thread shared pointer which will have a reference to an extended
- /// thread if one was available.
- //------------------------------------------------------------------
- lldb::ThreadSP
- GetExtendedBacktraceThread (ConstString type);
-
- void
- SetItemThatEnqueuedThis (lldb::addr_t address_of_item)
- {
- m_item_that_enqueued_this_ref = address_of_item;
- }
-
- lldb::addr_t
- GetItemThatEnqueuedThis ();
-
- void
- SetEnqueueingThreadID (lldb::tid_t tid)
- {
- m_enqueueing_thread_id = tid;
- }
-
- lldb::tid_t
- GetEnqueueingThreadID ();
-
- void
- SetEnqueueingQueueID (lldb::queue_id_t qid)
- {
- m_enqueueing_queue_id = qid;
- }
-
- lldb::queue_id_t
- GetEnqueueingQueueID ();
-
- void
- SetTargetQueueID (lldb::queue_id_t qid)
- {
- m_target_queue_id = qid;
- }
-
- void
- SetStopID (uint32_t stop_id)
- {
- m_stop_id = stop_id;
- }
-
- uint32_t
- GetStopID ();
-
- void
- SetEnqueueingBacktrace (std::vector<lldb::addr_t> backtrace)
- {
- m_backtrace = backtrace;
- }
-
- std::vector<lldb::addr_t> &
- GetEnqueueingBacktrace ();
-
- void
- SetThreadLabel (std::string thread_name)
- {
- m_thread_label = thread_name;
- }
-
- std::string
- GetThreadLabel ();
-
- void
- SetQueueLabel (std::string queue_name)
- {
- m_queue_label = queue_name;
- }
-
- std::string
- GetQueueLabel ();
-
- void
- SetTargetQueueLabel (std::string queue_name)
- {
- m_target_queue_label = queue_name;
- }
-
- lldb::ProcessSP
- GetProcessSP ();
+ QueueItem(lldb::QueueSP queue_sp, lldb::ProcessSP process_sp,
+ lldb::addr_t item_ref, lldb_private::Address address);
+
+ ~QueueItem();
+
+ //------------------------------------------------------------------
+ /// Get the kind of work item this is
+ ///
+ /// @return
+ /// The type of work item that this QueueItem object
+ /// represents. eQueueItemKindUnknown may be returned.
+ //------------------------------------------------------------------
+ lldb::QueueItemKind GetKind();
+
+ //------------------------------------------------------------------
+ /// Set the type of work item this is
+ ///
+ /// @param [in] item_kind
+ /// Set the kind of this work item object.
+ //------------------------------------------------------------------
+ void SetKind(lldb::QueueItemKind item_kind);
+
+ //------------------------------------------------------------------
+ /// Get the code address that will be executed when this work item
+ /// is executed.
+ ///
+ /// @return
+ /// The address that will be invoked when this work item is
+ /// executed. Not all types of QueueItems will have an
+ /// address associated with them; check that the returned
+ /// Address is valid, or check that the WorkItemKind is a
+ /// kind that involves an address, such as eQueueItemKindFunction
+ /// or eQueueItemKindBlock.
+ //------------------------------------------------------------------
+ lldb_private::Address &GetAddress();
+
+ //------------------------------------------------------------------
+ /// Set the work item address for this object
+ ///
+ /// @param [in] addr
+ /// The address that will be invoked when this work item
+ /// is executed.
+ //------------------------------------------------------------------
+ void SetAddress(lldb_private::Address addr);
+
+ //------------------------------------------------------------------
+ /// Check if this QueueItem object is valid
+ ///
+ /// If the weak pointer to the parent Queue cannot be revivified,
+ /// it is invalid.
+ ///
+ /// @return
+ /// True if this object is valid.
+ //------------------------------------------------------------------
+ bool IsValid() { return m_queue_wp.lock() != nullptr; }
+
+ //------------------------------------------------------------------
+ /// Get an extended backtrace thread for this queue item, if available
+ ///
+ /// If the backtrace/thread information was collected when this item
+ /// was enqueued, this call will provide it.
+ ///
+ /// @param [in] type
+ /// The type of extended backtrace being requested, e.g. "libdispatch"
+ /// or "pthread".
+ ///
+ /// @return
+ /// A thread shared pointer which will have a reference to an extended
+ /// thread if one was available.
+ //------------------------------------------------------------------
+ lldb::ThreadSP GetExtendedBacktraceThread(ConstString type);
+
+ void SetItemThatEnqueuedThis(lldb::addr_t address_of_item) {
+ m_item_that_enqueued_this_ref = address_of_item;
+ }
+
+ lldb::addr_t GetItemThatEnqueuedThis();
+
+ void SetEnqueueingThreadID(lldb::tid_t tid) { m_enqueueing_thread_id = tid; }
+
+ lldb::tid_t GetEnqueueingThreadID();
+
+ void SetEnqueueingQueueID(lldb::queue_id_t qid) {
+ m_enqueueing_queue_id = qid;
+ }
+
+ lldb::queue_id_t GetEnqueueingQueueID();
+
+ void SetTargetQueueID(lldb::queue_id_t qid) { m_target_queue_id = qid; }
+
+ void SetStopID(uint32_t stop_id) { m_stop_id = stop_id; }
+
+ uint32_t GetStopID();
+
+ void SetEnqueueingBacktrace(std::vector<lldb::addr_t> backtrace) {
+ m_backtrace = backtrace;
+ }
+
+ std::vector<lldb::addr_t> &GetEnqueueingBacktrace();
+
+ void SetThreadLabel(std::string thread_name) { m_thread_label = thread_name; }
+
+ std::string GetThreadLabel();
+
+ void SetQueueLabel(std::string queue_name) { m_queue_label = queue_name; }
+
+ std::string GetQueueLabel();
+
+ void SetTargetQueueLabel(std::string queue_name) {
+ m_target_queue_label = queue_name;
+ }
+
+ lldb::ProcessSP GetProcessSP();
protected:
- void
- FetchEntireItem ();
-
- lldb::QueueWP m_queue_wp;
- lldb::ProcessWP m_process_wp;
-
- lldb::addr_t m_item_ref; // the token we can be used to fetch more information about this queue item
- lldb_private::Address m_address;
- bool m_have_fetched_entire_item;
-
- lldb::QueueItemKind m_kind;
- lldb::addr_t m_item_that_enqueued_this_ref; // a handle that we can pass into libBacktraceRecording
- // to get the QueueItem that enqueued this item
- lldb::tid_t m_enqueueing_thread_id; // thread that enqueued this item
- lldb::queue_id_t m_enqueueing_queue_id; // Queue that enqueued this item, if it was a queue
- lldb::queue_id_t m_target_queue_id;
- uint32_t m_stop_id; // indicates when this backtrace was recorded in time
- std::vector<lldb::addr_t> m_backtrace;
- std::string m_thread_label;
- std::string m_queue_label;
- std::string m_target_queue_label;
+ void FetchEntireItem();
+
+ lldb::QueueWP m_queue_wp;
+ lldb::ProcessWP m_process_wp;
+
+ lldb::addr_t m_item_ref; // the token we can be used to fetch more information
+ // about this queue item
+ lldb_private::Address m_address;
+ bool m_have_fetched_entire_item;
+
+ lldb::QueueItemKind m_kind;
+ lldb::addr_t m_item_that_enqueued_this_ref; // a handle that we can pass into
+ // libBacktraceRecording
+ // to get the QueueItem that enqueued this item
+ lldb::tid_t m_enqueueing_thread_id; // thread that enqueued this item
+ lldb::queue_id_t
+ m_enqueueing_queue_id; // Queue that enqueued this item, if it was a queue
+ lldb::queue_id_t m_target_queue_id;
+ uint32_t m_stop_id; // indicates when this backtrace was recorded in time
+ std::vector<lldb::addr_t> m_backtrace;
+ std::string m_thread_label;
+ std::string m_queue_label;
+ std::string m_target_queue_label;
private:
- DISALLOW_COPY_AND_ASSIGN (QueueItem);
+ DISALLOW_COPY_AND_ASSIGN(QueueItem);
};
} // namespace lldb_private
diff --git a/include/lldb/Target/QueueList.h b/include/lldb/Target/QueueList.h
index 265145db2696..038463d9ab02 100644
--- a/include/lldb/Target/QueueList.h
+++ b/include/lldb/Target/QueueList.h
@@ -13,130 +13,118 @@
#include <mutex>
#include <vector>
-#include "lldb/lldb-private.h"
#include "lldb/Core/UserID.h"
#include "lldb/Utility/Iterable.h"
-
+#include "lldb/lldb-private.h"
namespace lldb_private {
//------------------------------------------------------------------
// QueueList:
-// This is the container for libdispatch aka Grand Central Dispatch
+// This is the container for libdispatch aka Grand Central Dispatch
// Queue objects.
//
// Each Process will have a QueueList. When the process execution is
-// paused, the QueueList may be populated with Queues by the
+// paused, the QueueList may be populated with Queues by the
// SystemRuntime.
//------------------------------------------------------------------
-class QueueList
-{
-friend class Process;
+class QueueList {
+ friend class Process;
public:
-
- QueueList (Process *process);
-
- ~QueueList ();
-
- //------------------------------------------------------------------
- /// Get the number of libdispatch queues that are available
- ///
- /// @return
- /// The number of queues that are stored in the QueueList.
- //------------------------------------------------------------------
- uint32_t
- GetSize();
-
- //------------------------------------------------------------------
- /// Get the Queue at a given index number
- ///
- /// @param [in] idx
- /// The index number (0-based) of the queue.
- /// @return
- /// The Queue at that index number.
- //------------------------------------------------------------------
- lldb::QueueSP
- GetQueueAtIndex (uint32_t idx);
-
- typedef std::vector<lldb::QueueSP> collection;
- typedef LockingAdaptedIterable<collection, lldb::QueueSP, vector_adapter, std::mutex> QueueIterable;
-
- //------------------------------------------------------------------
- /// Iterate over the list of queues
- ///
- /// @return
- /// An Iterable object which can be used to loop over the queues
- /// that exist.
- //------------------------------------------------------------------
- QueueIterable
- Queues ()
- {
- return QueueIterable(m_queues, m_mutex);
- }
-
- //------------------------------------------------------------------
- /// Clear out the list of queues from the QueueList
- //------------------------------------------------------------------
- void
- Clear();
-
- //------------------------------------------------------------------
- /// Add a Queue to the QueueList
- ///
- /// @param [in] queue
- /// Used by the SystemRuntime to populate the QueueList
- //------------------------------------------------------------------
- void
- AddQueue (lldb::QueueSP queue);
-
- //------------------------------------------------------------------
- /// Find a queue in the QueueList by QueueID
- ///
- /// @param [in] qid
- /// The QueueID (same as returned by Thread::GetQueueID()) to find.
- ///
- /// @return
- /// A QueueSP to the queue requested, if it is present in the QueueList.
- /// An empty QueueSP will be returned if this queue was not found.
- //------------------------------------------------------------------
- lldb::QueueSP
- FindQueueByID (lldb::queue_id_t qid);
-
- //------------------------------------------------------------------
- /// Find a queue in the QueueList by IndexID
- ///
- /// @param [in] index_id
- /// Find a queue by IndexID. This is an integer associated with each
- /// unique queue seen during a debug session and will not be reused
- /// for a different queue. Unlike the QueueID, a 64-bit value, this
- /// will tend to be an integral value like 1 or 7.
- ///
- /// @return
- /// A QueueSP to the queue requested, if it is present in the QueueList.
- /// An empty QueueSP will be returned if this queue was not found.
- //------------------------------------------------------------------
- lldb::QueueSP
- FindQueueByIndexID (uint32_t index_id);
-
- std::mutex &
- GetMutex();
+ QueueList(Process *process);
+
+ ~QueueList();
+
+ //------------------------------------------------------------------
+ /// Get the number of libdispatch queues that are available
+ ///
+ /// @return
+ /// The number of queues that are stored in the QueueList.
+ //------------------------------------------------------------------
+ uint32_t GetSize();
+
+ //------------------------------------------------------------------
+ /// Get the Queue at a given index number
+ ///
+ /// @param [in] idx
+ /// The index number (0-based) of the queue.
+ /// @return
+ /// The Queue at that index number.
+ //------------------------------------------------------------------
+ lldb::QueueSP GetQueueAtIndex(uint32_t idx);
+
+ typedef std::vector<lldb::QueueSP> collection;
+ typedef LockingAdaptedIterable<collection, lldb::QueueSP, vector_adapter,
+ std::mutex>
+ QueueIterable;
+
+ //------------------------------------------------------------------
+ /// Iterate over the list of queues
+ ///
+ /// @return
+ /// An Iterable object which can be used to loop over the queues
+ /// that exist.
+ //------------------------------------------------------------------
+ QueueIterable Queues() { return QueueIterable(m_queues, m_mutex); }
+
+ //------------------------------------------------------------------
+ /// Clear out the list of queues from the QueueList
+ //------------------------------------------------------------------
+ void Clear();
+
+ //------------------------------------------------------------------
+ /// Add a Queue to the QueueList
+ ///
+ /// @param [in] queue
+ /// Used by the SystemRuntime to populate the QueueList
+ //------------------------------------------------------------------
+ void AddQueue(lldb::QueueSP queue);
+
+ //------------------------------------------------------------------
+ /// Find a queue in the QueueList by QueueID
+ ///
+ /// @param [in] qid
+ /// The QueueID (same as returned by Thread::GetQueueID()) to find.
+ ///
+ /// @return
+ /// A QueueSP to the queue requested, if it is present in the QueueList.
+ /// An empty QueueSP will be returned if this queue was not found.
+ //------------------------------------------------------------------
+ lldb::QueueSP FindQueueByID(lldb::queue_id_t qid);
+
+ //------------------------------------------------------------------
+ /// Find a queue in the QueueList by IndexID
+ ///
+ /// @param [in] index_id
+ /// Find a queue by IndexID. This is an integer associated with each
+ /// unique queue seen during a debug session and will not be reused
+ /// for a different queue. Unlike the QueueID, a 64-bit value, this
+ /// will tend to be an integral value like 1 or 7.
+ ///
+ /// @return
+ /// A QueueSP to the queue requested, if it is present in the QueueList.
+ /// An empty QueueSP will be returned if this queue was not found.
+ //------------------------------------------------------------------
+ lldb::QueueSP FindQueueByIndexID(uint32_t index_id);
+
+ std::mutex &GetMutex();
protected:
-
- //------------------------------------------------------------------
- // Classes that inherit from Process can see and modify these
- //------------------------------------------------------------------
- Process *m_process; ///< The process that manages this queue list.
- uint32_t m_stop_id; ///< The process stop ID that this queue list is valid for.
- collection m_queues; ///< The queues for this process.
- std::mutex m_mutex;
+ //------------------------------------------------------------------
+ // Classes that inherit from Process can see and modify these
+ //------------------------------------------------------------------
+ Process *m_process; ///< The process that manages this queue list.
+ uint32_t
+ m_stop_id; ///< The process stop ID that this queue list is valid for.
+ collection m_queues; ///< The queues for this process.
+ std::mutex m_mutex;
private:
- QueueList ();
+ QueueList();
};
} // namespace lldb_private
-#endif // liblldb_QueueList_h_
+#endif // liblldb_QueueList_h_
diff --git a/include/lldb/Target/RegisterCheckpoint.h b/include/lldb/Target/RegisterCheckpoint.h
index 3e61e1490d4b..8391cadcdf66 100644
--- a/include/lldb/Target/RegisterCheckpoint.h
+++ b/include/lldb/Target/RegisterCheckpoint.h
@@ -10,62 +10,46 @@
#ifndef liblldb_RegisterCheckpoint_h_
#define liblldb_RegisterCheckpoint_h_
-#include "lldb/lldb-private.h"
#include "lldb/Core/UserID.h"
#include "lldb/Target/StackID.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
- // Inherit from UserID in case pushing/popping all register values can be
- // done using a 64 bit integer that holds a baton/cookie instead of actually
- // having to read all register values into a buffer
- class RegisterCheckpoint : public UserID
- {
- public:
-
- enum class Reason {
- // An expression is about to be run on the thread if the protocol that
- // talks to the debuggee supports checkpointing the registers using a
- // push/pop then the UserID base class in the RegisterCheckpoint can
- // be used to store the baton/cookie that refers to the remote saved
- // state.
- eExpression,
- // The register checkpoint wants the raw register bytes, so they must
- // be read into m_data_sp, or the save/restore checkpoint should fail.
- eDataBackup
- };
-
- RegisterCheckpoint(Reason reason) :
- UserID(0),
- m_data_sp (),
- m_reason(reason)
- {
- }
-
- ~RegisterCheckpoint()
- {
- }
-
- lldb::DataBufferSP &
- GetData()
- {
- return m_data_sp;
- }
-
- const lldb::DataBufferSP &
- GetData() const
- {
- return m_data_sp;
- }
-
- protected:
- lldb::DataBufferSP m_data_sp;
- Reason m_reason;
-
- // Make RegisterCheckpointSP if you wish to share the data in this class.
- DISALLOW_COPY_AND_ASSIGN(RegisterCheckpoint);
- };
-
+// Inherit from UserID in case pushing/popping all register values can be
+// done using a 64 bit integer that holds a baton/cookie instead of actually
+// having to read all register values into a buffer
+class RegisterCheckpoint : public UserID {
+public:
+ enum class Reason {
+ // An expression is about to be run on the thread if the protocol that
+ // talks to the debuggee supports checkpointing the registers using a
+ // push/pop then the UserID base class in the RegisterCheckpoint can
+ // be used to store the baton/cookie that refers to the remote saved
+ // state.
+ eExpression,
+ // The register checkpoint wants the raw register bytes, so they must
+ // be read into m_data_sp, or the save/restore checkpoint should fail.
+ eDataBackup
+ };
+
+ RegisterCheckpoint(Reason reason)
+ : UserID(0), m_data_sp(), m_reason(reason) {}
+
+ ~RegisterCheckpoint() {}
+
+ lldb::DataBufferSP &GetData() { return m_data_sp; }
+
+ const lldb::DataBufferSP &GetData() const { return m_data_sp; }
+
+protected:
+ lldb::DataBufferSP m_data_sp;
+ Reason m_reason;
+
+ // Make RegisterCheckpointSP if you wish to share the data in this class.
+ DISALLOW_COPY_AND_ASSIGN(RegisterCheckpoint);
+};
+
} // namespace lldb_private
-#endif // liblldb_RegisterCheckpoint_h_
+#endif // liblldb_RegisterCheckpoint_h_
diff --git a/include/lldb/Target/RegisterContext.h b/include/lldb/Target/RegisterContext.h
index dfeb18348bf7..485645b2dc14 100644
--- a/include/lldb/Target/RegisterContext.h
+++ b/include/lldb/Target/RegisterContext.h
@@ -14,255 +14,217 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
-class RegisterContext :
- public std::enable_shared_from_this<RegisterContext>,
- public ExecutionContextScope
-{
+class RegisterContext : public std::enable_shared_from_this<RegisterContext>,
+ public ExecutionContextScope {
public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- RegisterContext (Thread &thread, uint32_t concrete_frame_idx);
-
- ~RegisterContext() override;
-
- void
- InvalidateIfNeeded (bool force);
-
- //------------------------------------------------------------------
- // Subclasses must override these functions
- //------------------------------------------------------------------
- virtual void
- InvalidateAllRegisters () = 0;
-
- virtual size_t
- GetRegisterCount () = 0;
-
- virtual const RegisterInfo *
- GetRegisterInfoAtIndex (size_t reg) = 0;
-
- // Detect the register size dynamically.
- uint32_t
- UpdateDynamicRegisterSize (const lldb_private::ArchSpec &arch,
- RegisterInfo* reg_info);
-
- virtual size_t
- GetRegisterSetCount () = 0;
-
- virtual const RegisterSet *
- GetRegisterSet (size_t reg_set) = 0;
-
- virtual bool
- ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value) = 0;
-
- virtual bool
- WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value) = 0;
-
- virtual bool
- ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
- {
- return false;
- }
-
- virtual bool
- WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
- {
- return false;
- }
-
- // These two functions are used to implement "push" and "pop" of register states. They are used primarily
- // for expression evaluation, where we need to push a new state (storing the old one in data_sp) and then
- // restoring the original state by passing the data_sp we got from ReadAllRegisters to WriteAllRegisterValues.
- // ReadAllRegisters will do what is necessary to return a coherent set of register values for this thread, which
- // may mean e.g. interrupting a thread that is sitting in a kernel trap. That is a somewhat disruptive operation,
- // so these API's should only be used when this behavior is needed.
-
- virtual bool
- ReadAllRegisterValues (lldb_private::RegisterCheckpoint &reg_checkpoint);
-
- virtual bool
- WriteAllRegisterValues (const lldb_private::RegisterCheckpoint &reg_checkpoint);
-
- bool
- CopyFromRegisterContext (lldb::RegisterContextSP context);
-
- //------------------------------------------------------------------
- /// Convert from a given register numbering scheme to the lldb register
- /// numbering scheme
- ///
- /// There may be multiple ways to enumerate the registers for a given
- /// architecture. ABI references will specify one to be used with
- /// DWARF, the register numberings from process plugin, there may
- /// be a variation used for eh_frame unwind instructions (e.g. on Darwin),
- /// and so on. Register 5 by itself is meaningless - RegisterKind
- /// enumeration tells you what context that number should be translated as.
- ///
- /// Inside lldb, register numbers are in the eRegisterKindLLDB scheme;
- /// arguments which take a register number should take one in that
- /// scheme.
- ///
- /// eRegisterKindGeneric is a special numbering scheme which gives us
- /// constant values for the pc, frame register, stack register, etc., for
- /// use within lldb. They may not be defined for all architectures but
- /// it allows generic code to translate these common registers into the
- /// lldb numbering scheme.
- ///
- /// This method translates a given register kind + register number into
- /// the eRegisterKindLLDB register numbering.
- ///
- /// @param [in] kind
- /// The register numbering scheme (RegisterKind) that the following
- /// register number is in.
- ///
- /// @param [in] num
- /// A register number in the 'kind' register numbering scheme.
- ///
- /// @return
- /// The equivalent register number in the eRegisterKindLLDB
- /// numbering scheme, if possible, else LLDB_INVALID_REGNUM.
- //------------------------------------------------------------------
- virtual uint32_t
- ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t num) = 0;
-
- //------------------------------------------------------------------
- // Subclasses can override these functions if desired
- //------------------------------------------------------------------
- virtual uint32_t
- NumSupportedHardwareBreakpoints ();
-
- virtual uint32_t
- SetHardwareBreakpoint (lldb::addr_t addr, size_t size);
-
- virtual bool
- ClearHardwareBreakpoint (uint32_t hw_idx);
-
- virtual uint32_t
- NumSupportedHardwareWatchpoints ();
-
- virtual uint32_t
- SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write);
-
- virtual bool
- ClearHardwareWatchpoint (uint32_t hw_index);
-
- virtual bool
- HardwareSingleStep (bool enable);
-
- virtual Error
- ReadRegisterValueFromMemory (const lldb_private::RegisterInfo *reg_info, lldb::addr_t src_addr, uint32_t src_len, RegisterValue &reg_value);
-
- virtual Error
- WriteRegisterValueToMemory (const lldb_private::RegisterInfo *reg_info, lldb::addr_t dst_addr, uint32_t dst_len, const RegisterValue &reg_value);
-
- //------------------------------------------------------------------
- // Subclasses should not override these
- //------------------------------------------------------------------
- virtual lldb::tid_t
- GetThreadID() const;
-
- virtual Thread &
- GetThread ()
- {
- return m_thread;
- }
-
- const RegisterInfo *
- GetRegisterInfoByName (const char *reg_name, uint32_t start_idx = 0);
-
- const RegisterInfo *
- GetRegisterInfo (lldb::RegisterKind reg_kind, uint32_t reg_num);
-
-