Update prebuilt Clang to r365631c1 from Android.
The version we had was segfaulting.
Bug: 132420445
Change-Id: Icb45a6fe0b4e2166f7895e669df1157cec9fb4e0
diff --git a/linux-x64/clang/include/lldb/Target/ABI.h b/linux-x64/clang/include/lldb/Target/ABI.h
new file mode 100644
index 0000000..f254839
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/ABI.h
@@ -0,0 +1,153 @@
+//===-- ABI.h ---------------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ABI_h_
+#define liblldb_ABI_h_
+
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/Utility/Status.h"
+#include "lldb/lldb-private.h"
+
+#include "llvm/ADT/ArrayRef.h"
+
+// forward define the llvm::Type class
+namespace llvm {
+class Type;
+}
+
+namespace lldb_private {
+
+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_up; /* 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 Status 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;
+
+ /// Request to get a Process shared pointer.
+ ///
+ /// This ABI object may not have been created with a Process object,
+ /// or the Process object may no longer be alive. Be sure to handle
+ /// the case where the shared pointer returned does not have an
+ /// object inside it.
+ lldb::ProcessSP GetProcessSP() const { return m_process_wp.lock(); }
+
+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(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(lldb::ProcessSP process_sp, const ArchSpec &arch);
+
+protected:
+ // Classes that inherit from ABI can see and modify these
+ ABI(lldb::ProcessSP process_sp) {
+ if (process_sp.get())
+ m_process_wp = process_sp;
+ }
+
+ lldb::ProcessWP m_process_wp;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(ABI);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ABI_h_
diff --git a/linux-x64/clang/include/lldb/Target/CPPLanguageRuntime.h b/linux-x64/clang/include/lldb/Target/CPPLanguageRuntime.h
new file mode 100644
index 0000000..2852636
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/CPPLanguageRuntime.h
@@ -0,0 +1,90 @@
+//===-- CPPLanguageRuntime.h
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_CPPLanguageRuntime_h_
+#define liblldb_CPPLanguageRuntime_h_
+
+#include <vector>
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Target/LanguageRuntime.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+class CPPLanguageRuntime : public LanguageRuntime {
+public:
+ enum class LibCppStdFunctionCallableCase {
+ Lambda = 0,
+ CallableObject,
+ FreeOrMemberFunction,
+ Invalid
+ };
+
+ struct LibCppStdFunctionCallableInfo {
+ Symbol callable_symbol;
+ Address callable_address;
+ LineEntry callable_line_entry;
+ lldb::addr_t member__f_pointer_value = 0u;
+ LibCppStdFunctionCallableCase callable_case =
+ LibCppStdFunctionCallableCase::Invalid;
+ };
+
+ LibCppStdFunctionCallableInfo
+ FindLibCppStdFunctionCallableInfo(lldb::ValueObjectSP &valobj_sp);
+
+ ~CPPLanguageRuntime() override;
+
+ static char ID;
+
+ bool isA(const void *ClassID) const override {
+ return ClassID == &ID || LanguageRuntime::isA(ClassID);
+ }
+
+ static bool classof(const LanguageRuntime *runtime) {
+ return runtime->isA(&ID);
+ }
+
+ lldb::LanguageType GetLanguageType() const override {
+ return lldb::eLanguageTypeC_plus_plus;
+ }
+
+ static CPPLanguageRuntime *Get(Process &process) {
+ return llvm::cast_or_null<CPPLanguageRuntime>(
+ process.GetLanguageRuntime(lldb::eLanguageTypeC_plus_plus));
+ }
+
+ bool GetObjectDescription(Stream &str, ValueObject &object) override;
+
+ bool GetObjectDescription(Stream &str, Value &value,
+ ExecutionContextScope *exe_scope) override;
+
+ /// Obtain a ThreadPlan to get us into C++ constructs such as std::function.
+ ///
+ /// \param[in] thread
+ /// Curent thrad of execution.
+ ///
+ /// \param[in] stop_others
+ /// True if other threads should pause during execution.
+ ///
+ /// \return
+ /// A ThreadPlan Shared pointer
+ lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread,
+ bool stop_others) override;
+
+ bool IsWhitelistedRuntimeValue(ConstString name) override;
+protected:
+ // Classes that inherit from CPPLanguageRuntime can see and modify these
+ CPPLanguageRuntime(Process *process);
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(CPPLanguageRuntime);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_CPPLanguageRuntime_h_
diff --git a/linux-x64/clang/include/lldb/Target/DynamicLoader.h b/linux-x64/clang/include/lldb/Target/DynamicLoader.h
new file mode 100644
index 0000000..2bf3f32
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/DynamicLoader.h
@@ -0,0 +1,322 @@
+//===-- DynamicLoader.h -----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DynamicLoader_h_
+#define liblldb_DynamicLoader_h_
+
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/Status.h"
+#include "lldb/Utility/UUID.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private-enumerations.h"
+#include "lldb/lldb-types.h"
+
+#include <stddef.h>
+#include <stdint.h>
+namespace lldb_private {
+class ModuleList;
+class Process;
+class SectionList;
+class Symbol;
+class SymbolContext;
+class SymbolContextList;
+class Thread;
+}
+
+namespace lldb_private {
+
+/// \class DynamicLoader DynamicLoader.h "lldb/Target/DynamicLoader.h"
+/// A plug-in interface definition class for dynamic loaders.
+///
+/// Dynamic loader plug-ins track image (shared library) loading and
+/// unloading. The class is initialized given a live process that is halted at
+/// its entry point or just after attaching.
+///
+/// Dynamic loader plug-ins can track the process by registering callbacks
+/// using the: Process::RegisterNotificationCallbacks (const Notifications&)
+/// function.
+///
+/// Breakpoints can also be set in the process which can register functions
+/// that get called using: 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 {
+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);
+
+ /// 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.
+ ~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 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;
+
+ /// 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;
+ }
+
+ /// 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 Status 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;
+ }
+
+ /// 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);
+
+ /// 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
+
+ /// 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);
+
+ // 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);
+
+ // 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;
+
+ // 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);
+
+ // Calls into the Process protected method LoadOperatingSystemPlugin:
+ void LoadOperatingSystemPlugin(bool flush);
+
+
+ // Member variables.
+ Process
+ *m_process; ///< The process that this dynamic loader plug-in is tracking.
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(DynamicLoader);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_DynamicLoader_h_
diff --git a/linux-x64/clang/include/lldb/Target/ExecutionContext.h b/linux-x64/clang/include/lldb/Target/ExecutionContext.h
new file mode 100644
index 0000000..0819357
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/ExecutionContext.h
@@ -0,0 +1,568 @@
+//===-- ExecutionContext.h --------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ExecutionContext_h_
+#define liblldb_ExecutionContext_h_
+
+#include <mutex>
+
+#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 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 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
+/// 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 ExecutionContext objects will be valid. If you want
+/// to refer strongly (ExecutionContext) or weakly (ExecutionContextRef) to a
+/// process, then only the process and target references will be valid. For
+/// threads, only the thread, process and target references will be filled in.
+/// For frames, all of the objects will be filled in.
+///
+/// These classes are designed to be used as baton objects that get passed to
+/// a wide variety of functions that require execution contexts.
+//===----------------------------------------------------------------------===//
+
+/// \class ExecutionContextRef ExecutionContext.h
+/// "lldb/Target/ExecutionContext.h"
+/// A class that holds a weak reference to an execution context.
+///
+/// ExecutionContextRef objects are designed to hold onto an execution context
+/// that might change over time. For example, if an object wants to refer to a
+/// stack frame, it should hold onto an ExecutionContextRef to a frame object.
+/// The backing object that represents the stack frame might change over time
+/// and instances of this object can track the logical object that refers to a
+/// frame even if it does change.
+///
+/// These objects also don't keep execution objects around longer than they
+/// should since they use weak pointers. For example if an object refers 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 references to
+/// the execution objects (target, process, thread and frame) 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 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 references to these objects.
+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(); }
+
+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
+};
+
+/// \class ExecutionContext ExecutionContext.h
+/// "lldb/Target/ExecutionContext.h"
+/// A class that contains an execution context.
+///
+/// This baton object can be passed into any function that requires 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 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 functions can guarantee that these objects won't go away in the
+/// middle of a function.
+///
+/// ExecutionContext objects should be used as short lived objects (typically
+/// on the stack) in order to lock down an execution context for local use and
+/// for passing down to other functions that also require specific contexts.
+/// They should NOT be used for long term storage, for long term storage use
+/// ExecutionContextRef objects.
+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;
+
+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.
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ExecutionContext_h_
diff --git a/linux-x64/clang/include/lldb/Target/ExecutionContextScope.h b/linux-x64/clang/include/lldb/Target/ExecutionContextScope.h
new file mode 100644
index 0000000..0121ce6
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/ExecutionContextScope.h
@@ -0,0 +1,58 @@
+//===-- ExecutionContextScope.h ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ExecutionContextScope_h_
+#define liblldb_ExecutionContextScope_h_
+
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+/// @class ExecutionContextScope ExecutionContextScope.h
+/// "lldb/Target/ExecutionContextScope.h" Inherit from this if your object can
+/// reconstruct its
+/// execution context.
+///
+/// Many objects that have pointers back to parent execution context objects
+/// can inherit from this pure virtual class can reconstruct their execution
+/// context without having to keep a complete ExecutionContext object in the
+/// object state. Examples of these objects include: Process, Thread,
+/// RegisterContext and StackFrame.
+///
+/// Objects can contain a valid pointer to an instance of this so they can
+/// reconstruct the execution context.
+///
+/// Objects that adhere to this protocol can reconstruct enough of a execution
+/// context to allow functions that take a execution contexts to be called.
+class ExecutionContextScope {
+public:
+ virtual ~ExecutionContextScope() {}
+
+ virtual lldb::TargetSP CalculateTarget() = 0;
+
+ virtual lldb::ProcessSP CalculateProcess() = 0;
+
+ virtual lldb::ThreadSP CalculateThread() = 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;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ExecutionContextScope_h_
diff --git a/linux-x64/clang/include/lldb/Target/InstrumentationRuntime.h b/linux-x64/clang/include/lldb/Target/InstrumentationRuntime.h
new file mode 100644
index 0000000..4cee76d
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/InstrumentationRuntime.h
@@ -0,0 +1,95 @@
+//===-- InstrumentationRuntime.h --------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_InstrumentationRuntime_h_
+#define liblldb_InstrumentationRuntime_h_
+
+#include <map>
+#include <vector>
+
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Utility/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 {
+ /// 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);
+
+ /// 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_
diff --git a/linux-x64/clang/include/lldb/Target/InstrumentationRuntimeStopInfo.h b/linux-x64/clang/include/lldb/Target/InstrumentationRuntimeStopInfo.h
new file mode 100644
index 0000000..6c2a8ad
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/InstrumentationRuntimeStopInfo.h
@@ -0,0 +1,42 @@
+//===-- InstrumentationRuntimeStopInfo.h ------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_InstrumentationRuntimeStopInfo_h_
+#define liblldb_InstrumentationRuntimeStopInfo_h_
+
+#include <string>
+
+#include "lldb/Target/StopInfo.h"
+#include "lldb/Utility/StructuredData.h"
+
+namespace lldb_private {
+
+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);
+
+private:
+ InstrumentationRuntimeStopInfo(Thread &thread, std::string description,
+ StructuredData::ObjectSP additional_data);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_InstrumentationRuntimeStopInfo_h_
diff --git a/linux-x64/clang/include/lldb/Target/JITLoader.h b/linux-x64/clang/include/lldb/Target/JITLoader.h
new file mode 100644
index 0000000..1bafd82
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/JITLoader.h
@@ -0,0 +1,68 @@
+//===-- JITLoader.h ---------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_JITLoader_h_
+#define liblldb_JITLoader_h_
+
+#include <vector>
+
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Target/JITLoaderList.h"
+
+namespace lldb_private {
+
+/// \class JITLoader JITLoader.h "lldb/Target/JITLoader.h"
+/// A plug-in interface definition class for JIT loaders.
+///
+/// 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.
+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);
+
+ /// Construct with a process.
+ JITLoader(Process *process);
+
+ ~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 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;
+
+protected:
+ // Member variables.
+ Process *m_process;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_JITLoader_h_
diff --git a/linux-x64/clang/include/lldb/Target/JITLoaderList.h b/linux-x64/clang/include/lldb/Target/JITLoaderList.h
new file mode 100644
index 0000000..4cc3a9e
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/JITLoaderList.h
@@ -0,0 +1,48 @@
+//===-- JITLoaderList.h -----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_JITLoaderList_h_
+#define liblldb_JITLoaderList_h_
+
+#include <mutex>
+#include <vector>
+
+#include "lldb/lldb-forward.h"
+
+namespace lldb_private {
+
+/// \class JITLoaderList JITLoaderList.h "lldb/Target/JITLoaderList.h"
+///
+/// Class used by the Process to hold a list of its JITLoaders.
+class JITLoaderList {
+public:
+ JITLoaderList();
+ ~JITLoaderList();
+
+ void Append(const lldb::JITLoaderSP &jit_loader_sp);
+
+ void Remove(const lldb::JITLoaderSP &jit_loader_sp);
+
+ size_t GetSize() const;
+
+ lldb::JITLoaderSP GetLoaderAtIndex(size_t idx);
+
+ void DidLaunch();
+
+ void DidAttach();
+
+ void ModulesDidLoad(ModuleList &module_list);
+
+private:
+ std::vector<lldb::JITLoaderSP> m_jit_loaders_vec;
+ std::recursive_mutex m_jit_loaders_mutex;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_JITLoaderList_h_
diff --git a/linux-x64/clang/include/lldb/Target/Language.h b/linux-x64/clang/include/lldb/Target/Language.h
new file mode 100644
index 0000000..6ea6029
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/Language.h
@@ -0,0 +1,287 @@
+//===-- Language.h ---------------------------------------------------*- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Language_h_
+#define liblldb_Language_h_
+
+#include <functional>
+#include <memory>
+#include <set>
+#include <vector>
+
+#include "lldb/Core/Highlighter.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 {
+public:
+ class TypeScavenger {
+ 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;
+ };
+
+ 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;
+ };
+
+ 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);
+
+ /// Returns the Language associated with the given file path or a nullptr
+ /// if there is no known language.
+ static Language *FindPlugin(llvm::StringRef file_path);
+
+ static Language *FindPlugin(lldb::LanguageType language,
+ llvm::StringRef file_path);
+
+ // 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 bool IsSourceFile(llvm::StringRef file_path) const = 0;
+
+ virtual const Highlighter *GetHighlighter() const { return nullptr; }
+
+ 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 a language can have more than one possible name for a method, this
+ // function can be used to enumerate them. This is useful when doing name
+ // lookups.
+ virtual std::vector<ConstString>
+ GetMethodNameVariants(ConstString method_name) const {
+ return std::vector<ConstString>();
+ };
+
+ // 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, Status &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);
+
+ /// Equivalent to \c LanguageIsC||LanguageIsObjC||LanguageIsCPlusPlus.
+ static bool LanguageIsCFamily(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 std::set<lldb::LanguageType> GetSupportedLanguages();
+
+ 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();
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(Language);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Language_h_
diff --git a/linux-x64/clang/include/lldb/Target/LanguageRuntime.h b/linux-x64/clang/include/lldb/Target/LanguageRuntime.h
new file mode 100644
index 0000000..3521f46
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/LanguageRuntime.h
@@ -0,0 +1,197 @@
+//===-- LanguageRuntime.h ---------------------------------------------------*-
+// C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_LanguageRuntime_h_
+#define liblldb_LanguageRuntime_h_
+
+#include "lldb/Breakpoint/BreakpointResolver.h"
+#include "lldb/Breakpoint/BreakpointResolverName.h"
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Expression/LLVMUserExpression.h"
+#include "lldb/Symbol/DeclVendor.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 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,
+ Status &error);
+
+ StructuredData::ObjectSP SerializeToStructuredData() override;
+
+protected:
+ 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;
+
+ 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 lldb::BreakpointPreconditionSP
+ GetExceptionPrecondition(lldb::LanguageType language, bool throw_bp);
+
+ virtual lldb::ValueObjectSP GetExceptionObjectForThread(
+ lldb::ThreadSP thread_sp) {
+ return lldb::ValueObjectSP();
+ }
+
+ virtual lldb::ThreadSP GetBacktraceThreadFromException(
+ lldb::ValueObjectSP thread_sp) {
+ return lldb::ThreadSP();
+ }
+
+ Process *GetProcess() { return m_process; }
+
+ Target &GetTargetRef() { return m_process->GetTarget(); }
+
+ virtual DeclVendor *GetDeclVendor() { return nullptr; }
+
+ virtual lldb::BreakpointResolverSP
+ CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp) = 0;
+
+ virtual lldb::SearchFilterSP CreateExceptionSearchFilter() {
+ return m_process->GetTarget().GetSearchFilterForModule(nullptr);
+ }
+
+ virtual bool GetTypeBitSize(const CompilerType &compiler_type,
+ uint64_t &size) {
+ return false;
+ }
+
+ virtual void SymbolsDidLoad(const ModuleList &module_list) { return; }
+
+ virtual lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread,
+ bool stop_others) = 0;
+
+ /// Identify whether a name is a runtime value that should not be hidden by
+ /// from the user interface.
+ virtual bool IsWhitelistedRuntimeValue(ConstString name) { 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;
+ }
+
+ // Given the name of a runtime symbol (e.g. in Objective-C, an 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(ConstString name) {
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ virtual bool isA(const void *ClassID) const { return ClassID == &ID; }
+ static char ID;
+
+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
+
+#endif // liblldb_LanguageRuntime_h_
diff --git a/linux-x64/clang/include/lldb/Target/Memory.h b/linux-x64/clang/include/lldb/Target/Memory.h
new file mode 100644
index 0000000..e62b8ef
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/Memory.h
@@ -0,0 +1,143 @@
+//===-- Memory.h ------------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Memory_h_
+#define liblldb_Memory_h_
+
+#include "lldb/Utility/RangeMap.h"
+#include "lldb/lldb-private.h"
+#include <map>
+#include <mutex>
+#include <vector>
+
+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, Status &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_range.GetRangeBase(); }
+
+ uint32_t GetByteSize() const { return m_range.GetByteSize(); }
+
+ uint32_t GetPermissions() const { return m_permissions; }
+
+ uint32_t GetChunkSize() const { return m_chunk_size; }
+
+ bool Contains(lldb::addr_t addr) const {
+ return m_range.Contains(addr);
+ }
+
+protected:
+ uint32_t TotalChunks() const { return GetByteSize() / GetChunkSize(); }
+
+ uint32_t CalculateChunksNeededForSize(uint32_t size) const {
+ return (size + m_chunk_size - 1) / m_chunk_size;
+ }
+ // Base address of this block of memory 4GB of chunk should be enough.
+ Range<lldb::addr_t, uint32_t> m_range;
+ // Permissions for this memory (logical OR of lldb::Permissions bits)
+ const uint32_t m_permissions;
+ // The size of chunks that the memory at m_addr is divied up into.
+ const uint32_t m_chunk_size;
+ // A sorted list of free address ranges.
+ RangeVector<lldb::addr_t, uint32_t> m_free_blocks;
+ // A sorted list of reserved address.
+ RangeVector<lldb::addr_t, uint32_t> m_reserved_blocks;
+};
+
+// 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,
+ Status &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, Status &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_
diff --git a/linux-x64/clang/include/lldb/Target/MemoryHistory.h b/linux-x64/clang/include/lldb/Target/MemoryHistory.h
new file mode 100644
index 0000000..501751c
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/MemoryHistory.h
@@ -0,0 +1,33 @@
+//===-- MemoryHistory.h ---------------------------------------------------*-
+//C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_MemoryHistory_h_
+#define liblldb_MemoryHistory_h_
+
+#include <vector>
+
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/lldb-private.h"
+#include "lldb/lldb-types.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);
+
+ virtual HistoryThreads GetHistoryThreads(lldb::addr_t address) = 0;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_MemoryHistory_h_
diff --git a/linux-x64/clang/include/lldb/Target/MemoryRegionInfo.h b/linux-x64/clang/include/lldb/Target/MemoryRegionInfo.h
new file mode 100644
index 0000000..5cab2ef
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/MemoryRegionInfo.h
@@ -0,0 +1,148 @@
+//===-- MemoryRegionInfo.h ---------------------------------------*- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_MemoryRegionInfo_h
+#define lldb_MemoryRegionInfo_h
+
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/RangeMap.h"
+#include "llvm/Support/FormatProviders.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), m_flash(eDontKnow), m_blocksize(0) {}
+
+ ~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; }
+
+ 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); }
+
+ OptionalBool GetFlash() const { return m_flash; }
+
+ void SetFlash(OptionalBool val) { m_flash = val; }
+
+ lldb::offset_t GetBlocksize() const { return m_blocksize; }
+
+ void SetBlocksize(lldb::offset_t blocksize) { m_blocksize = blocksize; }
+
+ // 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;
+ OptionalBool m_flash;
+ lldb::offset_t m_blocksize;
+};
+
+inline bool operator<(const MemoryRegionInfo &lhs,
+ const MemoryRegionInfo &rhs) {
+ return lhs.GetRange() < rhs.GetRange();
+}
+
+inline bool operator<(const MemoryRegionInfo &lhs, lldb::addr_t rhs) {
+ return lhs.GetRange().GetRangeBase() < rhs;
+}
+
+inline bool operator<(lldb::addr_t lhs, const MemoryRegionInfo &rhs) {
+ return lhs < rhs.GetRange().GetRangeBase();
+}
+
+// Forward-declarable wrapper.
+class MemoryRegionInfos : public std::vector<lldb_private::MemoryRegionInfo> {
+public:
+ using std::vector<lldb_private::MemoryRegionInfo>::vector;
+};
+
+}
+
+namespace llvm {
+template <>
+struct format_provider<lldb_private::MemoryRegionInfo::OptionalBool> {
+ static void format(const lldb_private::MemoryRegionInfo::OptionalBool &B,
+ raw_ostream &OS, StringRef Options) {
+ switch(B) {
+ case lldb_private::MemoryRegionInfo::eNo:
+ OS << "no";
+ return;
+ case lldb_private::MemoryRegionInfo::eYes:
+ OS << "yes";
+ return;
+ case lldb_private::MemoryRegionInfo::eDontKnow:
+ OS << "don't know";
+ return;
+ }
+ }
+};
+}
+
+#endif // #ifndef lldb_MemoryRegionInfo_h
diff --git a/linux-x64/clang/include/lldb/Target/ModuleCache.h b/linux-x64/clang/include/lldb/Target/ModuleCache.h
new file mode 100644
index 0000000..1196169
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/ModuleCache.h
@@ -0,0 +1,74 @@
+//===-- ModuleCache.h -------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_TARGET_MODULECACHE_H
+#define LLDB_TARGET_MODULECACHE_H
+
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-types.h"
+
+#include "lldb/Host/File.h"
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/Status.h"
+
+#include <functional>
+#include <string>
+#include <unordered_map>
+
+namespace lldb_private {
+
+class Module;
+class UUID;
+
+/// \class ModuleCache ModuleCache.h "lldb/Target/ModuleCache.h"
+/// A module cache class.
+///
+/// Caches locally modules that are downloaded from remote targets. Each
+/// cached module maintains 2 views:
+/// - UUID view:
+/// /${CACHE_ROOT}/${PLATFORM_NAME}/.cache/${UUID}/${MODULE_FILENAME}
+/// - Sysroot view:
+/// /${CACHE_ROOT}/${PLATFORM_NAME}/${HOSTNAME}/${MODULE_FULL_FILEPATH}
+///
+/// UUID views stores a real module file, whereas Sysroot view holds a symbolic
+/// link to UUID-view file.
+///
+/// Example:
+/// UUID view :
+/// /tmp/lldb/remote-
+/// linux/.cache/30C94DC6-6A1F-E951-80C3-D68D2B89E576-D5AE213C/libc.so.6
+/// Sysroot view: /tmp/lldb/remote-linux/ubuntu/lib/x86_64-linux-gnu/libc.so.6
+
+class ModuleCache {
+public:
+ using ModuleDownloader =
+ std::function<Status(const ModuleSpec &, const FileSpec &)>;
+ using SymfileDownloader =
+ std::function<Status(const lldb::ModuleSP &, const FileSpec &)>;
+
+ Status GetAndPut(const FileSpec &root_dir_spec, const char *hostname,
+ const ModuleSpec &module_spec,
+ const ModuleDownloader &module_downloader,
+ const SymfileDownloader &symfile_downloader,
+ lldb::ModuleSP &cached_module_sp, bool *did_create_ptr);
+
+private:
+ Status Put(const FileSpec &root_dir_spec, const char *hostname,
+ const ModuleSpec &module_spec, const FileSpec &tmp_file,
+ const FileSpec &target_file);
+
+ Status Get(const FileSpec &root_dir_spec, const char *hostname,
+ const ModuleSpec &module_spec, lldb::ModuleSP &cached_module_sp,
+ bool *did_create_ptr);
+
+ std::unordered_map<std::string, lldb::ModuleWP> m_loaded_modules;
+};
+
+} // namespace lldb_private
+
+#endif // utility_ModuleCache_h_
diff --git a/linux-x64/clang/include/lldb/Target/ObjCLanguageRuntime.h b/linux-x64/clang/include/lldb/Target/ObjCLanguageRuntime.h
new file mode 100644
index 0000000..1fc8744
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/ObjCLanguageRuntime.h
@@ -0,0 +1,427 @@
+//===-- ObjCLanguageRuntime.h -----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ObjCLanguageRuntime_h_
+#define liblldb_ObjCLanguageRuntime_h_
+
+#include <functional>
+#include <map>
+#include <memory>
+#include <unordered_set>
+
+#include "llvm/Support/Casting.h"
+
+#include "lldb/Breakpoint/BreakpointPrecondition.h"
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Core/ThreadSafeDenseMap.h"
+#include "lldb/Symbol/CompilerType.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 {
+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_up;
+ };
+
+ class ObjCExceptionPrecondition : public BreakpointPrecondition {
+ public:
+ ObjCExceptionPrecondition();
+
+ ~ObjCExceptionPrecondition() override = default;
+
+ bool EvaluatePrecondition(StoppointCallbackContext &context) override;
+ void GetDescription(Stream &stream, lldb::DescriptionLevel level) override;
+ Status ConfigurePrecondition(Args &args) override;
+
+ protected:
+ void AddClassName(const char *class_name);
+
+ private:
+ std::unordered_set<std::string> m_class_names;
+ };
+
+ static lldb::BreakpointPreconditionSP
+ GetBreakpointExceptionPrecondition(lldb::LanguageType language,
+ bool throw_bp);
+
+ 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;
+
+ static char ID;
+
+ bool isA(const void *ClassID) const override {
+ return ClassID == &ID || LanguageRuntime::isA(ClassID);
+ }
+
+ static bool classof(const LanguageRuntime *runtime) {
+ return runtime->isA(&ID);
+ }
+
+ static ObjCLanguageRuntime *Get(Process &process) {
+ return llvm::cast_or_null<ObjCLanguageRuntime>(
+ process.GetLanguageRuntime(lldb::eLanguageTypeObjC));
+ }
+
+ 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(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;
+
+ 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 ObjCISA GetISA(ConstString name);
+
+ virtual ConstString GetActualTypeName(ObjCISA isa);
+
+ virtual ObjCISA GetParentClass(ObjCISA isa);
+
+ // 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);
+
+ 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);
+ }
+
+ void SymbolsDidLoad(const ModuleList &module_list) override {
+ m_negative_complete_class_cache.clear();
+ }
+
+ bool GetTypeBitSize(const CompilerType &compiler_type,
+ uint64_t &size) override;
+
+ /// Check whether the name is "self" or "_cmd" and should show up in
+ /// "frame variable".
+ bool IsWhitelistedRuntimeValue(ConstString name) override;
+
+protected:
+ // Classes that inherit from ObjCLanguageRuntime can see and modify these
+ ObjCLanguageRuntime(Process *process);
+
+ 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;
+ }
+ 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;
+ }
+
+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;
+ };
+
+ 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;
+
+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()(ConstString arg) const // for hashing
+ {
+ return (size_t)arg.GetCString();
+ }
+ bool operator()(ConstString arg1,
+ 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(ConstString name);
+
+ friend class ::CommandObjectObjC_ClassTable_Dump;
+
+ std::pair<ISAToDescriptorIterator, ISAToDescriptorIterator>
+ GetDescriptorIteratorPair(bool update_if_needed = true);
+
+ void ReadObjCLibraryIfNeeded(const ModuleList &module_list);
+
+ DISALLOW_COPY_AND_ASSIGN(ObjCLanguageRuntime);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ObjCLanguageRuntime_h_
diff --git a/linux-x64/clang/include/lldb/Target/OperatingSystem.h b/linux-x64/clang/include/lldb/Target/OperatingSystem.h
new file mode 100644
index 0000000..c75d1ca
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/OperatingSystem.h
@@ -0,0 +1,78 @@
+//===-- OperatingSystem.h ----------------------------------------------*- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OperatingSystem_h_
+#define liblldb_OperatingSystem_h_
+
+
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+/// \class OperatingSystem OperatingSystem.h "lldb/Target/OperatingSystem.h"
+/// 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.
+/// 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 {
+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);
+
+protected:
+ // Member variables.
+ Process
+ *m_process; ///< The process that this dynamic loader plug-in is tracking.
+private:
+ DISALLOW_COPY_AND_ASSIGN(OperatingSystem);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_OperatingSystem_h_
diff --git a/linux-x64/clang/include/lldb/Target/PathMappingList.h b/linux-x64/clang/include/lldb/Target/PathMappingList.h
new file mode 100644
index 0000000..d175966
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/PathMappingList.h
@@ -0,0 +1,128 @@
+//===-- PathMappingList.h ---------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_PathMappingList_h_
+#define liblldb_PathMappingList_h_
+
+#include <map>
+#include <vector>
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/Status.h"
+
+namespace lldb_private {
+
+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(ConstString path, 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(ConstString path, ConstString replacement,
+ uint32_t insert_idx, bool notify);
+
+ bool Remove(size_t index, bool notify);
+
+ bool Remove(ConstString path, bool notify);
+
+ bool Replace(ConstString path, ConstString replacement,
+ bool notify);
+
+ bool Replace(ConstString path, ConstString replacement,
+ uint32_t index, bool notify);
+ bool RemapPath(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 FileSpec &file, FileSpec &fixed) 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(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(ConstString path);
+
+ const_iterator FindIteratorForPath(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_
diff --git a/linux-x64/clang/include/lldb/Target/Platform.h b/linux-x64/clang/include/lldb/Target/Platform.h
new file mode 100644
index 0000000..3ba58c0
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/Platform.h
@@ -0,0 +1,1063 @@
+//===-- Platform.h ----------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Platform_h_
+#define liblldb_Platform_h_
+
+#include <functional>
+#include <map>
+#include <memory>
+#include <mutex>
+#include <string>
+#include <vector>
+
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Core/UserSettingsController.h"
+#include "lldb/Interpreter/Options.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/Timeout.h"
+#include "lldb/Utility/UserIDResolver.h"
+#include "lldb/lldb-private-forward.h"
+#include "lldb/lldb-public.h"
+#include "llvm/Support/VersionTuple.h"
+
+namespace lldb_private {
+
+class ProcessInstanceInfo;
+class ProcessInstanceInfoList;
+class ProcessInstanceInfoMatch;
+
+class ModuleCache;
+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;
+typedef llvm::SmallVector<lldb::addr_t, 6> MmapArgList;
+
+/// \class Platform Platform.h "lldb/Target/Platform.h"
+/// 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(ConstString name);
+
+ static lldb::PlatformSP Create(ConstString name, Status &error);
+
+ static lldb::PlatformSP Create(const ArchSpec &arch,
+ ArchSpec *platform_arch_ptr, Status &error);
+
+ /// Augments the triple either with information from platform or the host
+ /// system (if platform is null).
+ static ArchSpec GetAugmentedArchSpec(Platform *platform,
+ llvm::StringRef triple);
+
+ /// 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, 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 Status 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 Status 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 llvm::VersionTuple GetOSVersion(Process *process = nullptr);
+
+ bool SetOSVersion(llvm::VersionTuple os_version);
+
+ 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);
+
+ /// Retrieve the system include directories on this platform for the
+ /// given language.
+ ///
+ /// \param[in] lang
+ /// The language for which the include directories should be queried.
+ ///
+ /// \param[out] directories
+ /// The include directories for this system.
+ virtual std::vector<std::string>
+ GetSystemIncludeDirectories(lldb::LanguageType lang) {
+ return {};
+ }
+
+ virtual UserIDResolver &GetUserIDResolver() = 0;
+
+ /// 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 Status 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 Status 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 Status ConnectRemote(Args &args);
+
+ virtual Status 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 Status 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 Status ShellExpandArguments(ProcessLaunchInfo &launch_info);
+
+ /// Kill process on a platform.
+ virtual Status 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
+ Status &error);
+
+ virtual lldb::ProcessSP ConnectProcess(llvm::StringRef connect_url,
+ llvm::StringRef plugin_name,
+ lldb_private::Debugger &debugger,
+ lldb_private::Target *target,
+ lldb_private::Status &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
+ Status &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,
+ // Status &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();
+ }
+
+ /// If the triple contains not specify the vendor, os, and environment
+ /// parts, we "augment" these using information from the platform and return
+ /// the resulting ArchSpec object.
+ ArchSpec GetAugmentedArchSpec(llvm::StringRef triple);
+
+ // 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; }
+
+ ConstString GetSDKRootDirectory() const { return m_sdk_sysroot; }
+
+ void SetSDKRootDirectory(ConstString dir) { m_sdk_sysroot = dir; }
+
+ ConstString GetSDKBuild() const { return m_sdk_build; }
+
+ void SetSDKBuild(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 Status MakeDirectory(const FileSpec &file_spec, uint32_t permissions);
+
+ virtual Status GetFilePermissions(const FileSpec &file_spec,
+ uint32_t &file_permissions);
+
+ virtual Status 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, Status &error) {
+ return UINT64_MAX;
+ }
+
+ virtual bool CloseFile(lldb::user_id_t fd, Status &error) { return false; }
+
+ virtual lldb::user_id_t GetFileSize(const FileSpec &file_spec) {
+ return UINT64_MAX;
+ }
+
+ virtual uint64_t ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst,
+ uint64_t dst_len, Status &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, Status &error) {
+ error.SetErrorStringWithFormat(
+ "Platform::WriteFile() is not supported in the %s platform",
+ GetName().GetCString());
+ return -1;
+ }
+
+ virtual Status GetFile(const FileSpec &source, const FileSpec &destination);
+
+ virtual Status PutFile(const FileSpec &source, const FileSpec &destination,
+ uint32_t uid = UINT32_MAX, uint32_t gid = UINT32_MAX);
+
+ virtual Status
+ 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 Status Install(const FileSpec &src, const FileSpec &dst);
+
+ virtual Environment GetEnvironment();
+
+ virtual bool GetFileExists(const lldb_private::FileSpec &file_spec);
+
+ virtual Status Unlink(const FileSpec &file_spec);
+
+ virtual MmapArgList GetMmapArgumentList(const ArchSpec &arch,
+ lldb::addr_t addr,
+ lldb::addr_t length,
+ unsigned prot, unsigned flags,
+ lldb::addr_t fd, lldb::addr_t offset);
+
+ 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::Status 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
+ const Timeout<std::micro> &timeout);
+
+ 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();
+
+ 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::Status &error);
+
+ /// Load a shared library specified by base name into this process,
+ /// looking by hand along a set of paths.
+ ///
+ /// \param[in] process
+ /// The process to load the image.
+ ///
+ /// \param[in] library_name
+ /// The name of the library to look for. If library_name is an
+ /// absolute path, the basename will be extracted and searched for
+ /// along the paths. This emulates the behavior of the loader when
+ /// given an install name and a set (e.g. DYLD_LIBRARY_PATH provided) of
+ /// alternate paths.
+ ///
+ /// \param[in] path_list
+ /// The list of paths to use to search for the library. First
+ /// match wins.
+ ///
+ /// \param[out] error
+ /// An error object that gets filled in with any errors that
+ /// might occur when trying to load the shared library.
+ ///
+ /// \param[out] loaded_path
+ /// If non-null, the path to the dylib that was successfully loaded
+ /// is stored in this path.
+ ///
+ /// \return
+ /// A token that represents the shared library which can be
+ /// passed to UnloadImage. A value of
+ /// LLDB_INVALID_IMAGE_TOKEN will be returned if the shared
+ /// library can't be opened.
+ uint32_t LoadImageUsingPaths(lldb_private::Process *process,
+ const lldb_private::FileSpec &library_name,
+ const std::vector<std::string> &paths,
+ lldb_private::Status &error,
+ lldb_private::FileSpec *loaded_path);
+
+ virtual uint32_t DoLoadImage(lldb_private::Process *process,
+ const lldb_private::FileSpec &remote_file,
+ const std::vector<std::string> *paths,
+ lldb_private::Status &error,
+ lldb_private::FileSpec *loaded_path = nullptr);
+
+ virtual Status 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::Status &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;
+ llvm::VersionTuple m_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;
+ 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;
+
+ Status GetCachedExecutable(ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr,
+ Platform &remote_platform);
+
+ virtual Status DownloadModuleSlice(const FileSpec &src_file_spec,
+ const uint64_t src_offset,
+ const uint64_t src_size,
+ const FileSpec &dst_file_spec);
+
+ virtual Status DownloadSymbolFile(const lldb::ModuleSP &module_sp,
+ const FileSpec &dst_file_spec);
+
+ virtual const char *GetCacheHostname();
+
+private:
+ typedef std::function<Status(const ModuleSpec &)> ModuleResolver;
+
+ Status 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);
+
+ Status LoadCachedExecutable(const ModuleSpec &module_spec,
+ lldb::ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr,
+ Platform &remote_platform);
+
+ FileSpec GetModuleCacheRoot();
+
+ DISALLOW_COPY_AND_ASSIGN(Platform);
+};
+
+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();
+ }
+
+ size_t GetSize() {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ return m_platforms.size();
+ }
+
+ 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();
+ }
+ }
+
+protected:
+ typedef std::vector<lldb::PlatformSP> collection;
+ mutable std::recursive_mutex m_mutex;
+ collection m_platforms;
+ lldb::PlatformSP m_selected_platform_sp;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(PlatformList);
+};
+
+class OptionGroupPlatformRSync : public lldb_private::OptionGroup {
+public:
+ OptionGroupPlatformRSync() = default;
+
+ ~OptionGroupPlatformRSync() override = default;
+
+ lldb_private::Status
+ SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
+ ExecutionContext *execution_context) override;
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override;
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override;
+
+ // 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::Status
+ SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
+ ExecutionContext *execution_context) override;
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override;
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override;
+
+ // 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::Status
+ SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
+ ExecutionContext *execution_context) override;
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override;
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override;
+
+ // 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/linux-x64/clang/include/lldb/Target/Process.h b/linux-x64/clang/include/lldb/Target/Process.h
new file mode 100644
index 0000000..f85069e
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/Process.h
@@ -0,0 +1,2858 @@
+//===-- Process.h -----------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Process_h_
+#define liblldb_Process_h_
+
+#include "lldb/Host/Config.h"
+
+#include <limits.h>
+
+#include <chrono>
+#include <list>
+#include <memory>
+#include <mutex>
+#include <string>
+#include <unordered_set>
+#include <vector>
+
+#include "lldb/Breakpoint/BreakpointSiteList.h"
+#include "lldb/Core/Communication.h"
+#include "lldb/Core/LoadedModuleInfoList.h"
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Core/ThreadSafeValue.h"
+#include "lldb/Core/UserSettingsController.h"
+#include "lldb/Host/HostThread.h"
+#include "lldb/Host/ProcessLaunchInfo.h"
+#include "lldb/Host/ProcessRunLock.h"
+#include "lldb/Interpreter/Options.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Target/InstrumentationRuntime.h"
+#include "lldb/Target/Memory.h"
+#include "lldb/Target/QueueList.h"
+#include "lldb/Target/ThreadList.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/Broadcaster.h"
+#include "lldb/Utility/Event.h"
+#include "lldb/Utility/Listener.h"
+#include "lldb/Utility/NameMatches.h"
+#include "lldb/Utility/ProcessInfo.h"
+#include "lldb/Utility/Status.h"
+#include "lldb/Utility/StructuredData.h"
+#include "lldb/Utility/TraceOptions.h"
+#include "lldb/Utility/UserIDResolver.h"
+#include "lldb/lldb-private.h"
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/VersionTuple.h"
+
+namespace lldb_private {
+
+template <typename B, typename S> struct Range;
+
+// ProcessProperties
+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;
+ bool GetStopOnExec() const;
+ std::chrono::seconds GetUtilityExpressionTimeout() const;
+
+protected:
+ static void OptionValueChangedCallback(void *baton,
+ OptionValue *option_value);
+
+ Process *m_process; // Can be nullptr for global ProcessProperties
+};
+
+typedef std::shared_ptr<ProcessProperties> ProcessPropertiesSP;
+
+// ProcessAttachInfo
+//
+// Describes any information that is required to attach to a process.
+
+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(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; }
+
+ bool GetAsync() const { return m_async; }
+
+ void SetAsync(bool b) { m_async = b; }
+
+ bool GetIgnoreExisting() const { return m_ignore_existing; }
+
+ void SetIgnoreExisting(bool b) { m_ignore_existing = b; }
+
+ bool GetContinueOnceAttached() const { return m_continue_once_attached; }
+
+ void SetContinueOnceAttached(bool b) { m_continue_once_attached = 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(llvm::StringRef plugin) { m_plugin_name = plugin; }
+
+ 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)
+};
+
+class ProcessLaunchCommandOptions : public Options {
+public:
+ ProcessLaunchCommandOptions() : Options() {
+ // Keep default values of all options in one place: OptionParsingStarting
+ // ()
+ OptionParsingStarting(nullptr);
+ }
+
+ ~ProcessLaunchCommandOptions() override = default;
+
+ Status 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;
+};
+
+// 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);
+
+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),
+ m_running_utility_function(0) {}
+
+ 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;
+ }
+
+ bool IsRunningUtilityFunction() const {
+ return m_running_utility_function > 0;
+ }
+
+ 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 SetRunningUtilityFunction(bool on) {
+ if (on)
+ m_running_utility_function++;
+ else {
+ assert(m_running_utility_function > 0 &&
+ "Called SetRunningUtilityFunction(false) without calling "
+ "SetRunningUtilityFunction(true) before?");
+ m_running_utility_function--;
+ }
+ }
+
+ 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;
+ uint32_t m_running_utility_function;
+ 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) {
+ return (!lhs.StopIDEqual(rhs) || !lhs.MemoryIDEqual(rhs));
+}
+
+/// \class Process Process.h "lldb/Target/Process.h"
+/// 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 DynamicLoader; // For LoadOperatingSystemPlugin
+ 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),
+ 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&)
+ 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 ConstString GetFlavorString();
+
+ 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);
+ };
+
+ /// 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 command <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 Status Launch(ProcessLaunchInfo &launch_info);
+
+ virtual Status LoadCore();
+
+ virtual Status DoLoadCore() {
+ Status error;
+ error.SetErrorStringWithFormat(
+ "error: %s does not support loading core files.",
+ GetPluginName().GetCString());
+ return error;
+ }
+
+ // FUTURE WORK: GetLoadImageUtilityFunction are the first use we've
+ // had of having other plugins cache data in the Process. This is handy for
+ // long-living plugins - like the Platform - which manage interactions whose
+ // lifetime is governed by the Process lifetime. If we find we need to do
+ // this more often, we should construct a general solution to the problem.
+ // The consensus suggestion was that we have a token based registry in the
+ // Process. Some undecided questions are (1) who manages the tokens. It's
+ // probably best that you add the element and get back a token that
+ // represents it. That will avoid collisions. But there may be some utility
+ // in the registerer controlling the token? (2) whether the thing added
+ // should be simply owned by Process, and just go away when it does (3)
+ // whether the registree should be notified of the Process' demise.
+ //
+ // We are postponing designing this till we have at least a second use case.
+ /// Get the cached UtilityFunction that assists in loading binary images
+ /// into the process.
+ ///
+ /// \param[in] platform
+ /// The platform fetching the UtilityFunction.
+ /// \param[in] factory
+ /// A function that will be called only once per-process in a
+ /// thread-safe way to create the UtilityFunction if it has not
+ /// been initialized yet.
+ ///
+ /// \return
+ /// The cached utility function or null if the platform is not the
+ /// same as the target's platform.
+ UtilityFunction *GetLoadImageUtilityFunction(
+ Platform *platform,
+ llvm::function_ref<std::unique_ptr<UtilityFunction>()> factory);
+
+ /// 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 extractor containing the contents of the AUXV data.
+ virtual DataExtractor 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; }
+
+protected:
+ virtual JITLoaderList &GetJITLoaders();
+
+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 Status 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 Status 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
+ void RegisterNotificationCallbacks(const Process::Notifications &callbacks);
+
+/// 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
+ bool UnregisterNotificationCallbacks(const Process::Notifications &callbacks);
+
+ //==================================================================
+ // 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()
+ Status Resume();
+
+ Status 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.
+ Status 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.
+ Status 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.
+ Status 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.
+ Status 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 Status WillAttachToProcessWithID(lldb::pid_t pid) { return Status(); }
+
+ /// Called before attaching to a process.
+ ///
+ /// Allow Process plug-ins to execute some code before attaching a process.
+ ///
+ /// \return
+ /// Returns an error object.
+ virtual Status WillAttachToProcessWithName(const char *process_name,
+ bool wait_for_launch) {
+ return Status();
+ }
+
+ /// 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 Status DoConnectRemote(Stream *strm, llvm::StringRef remote_url) {
+ Status 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 Status attaching was successful, or
+ /// an appropriate (possibly platform-specific) error code if
+ /// attaching fails.
+ /// hanming : need flag
+ virtual Status DoAttachToProcessWithID(lldb::pid_t pid,
+ const ProcessAttachInfo &attach_info) {
+ Status 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 Status attaching was successful, or
+ /// an appropriate (possibly platform-specific) error code if
+ /// attaching fails.
+ virtual Status
+ DoAttachToProcessWithName(const char *process_name,
+ const ProcessAttachInfo &attach_info) {
+ Status 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 Status WillLaunch(Module *module) { return Status(); }
+
+ /// 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 Status instance indicating success or failure of the
+ /// operation.
+ virtual Status DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) {
+ Status 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 Status WillResume() { return Status(); }
+
+ /// 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 Status DoResume() {
+ Status 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 Status WillHalt() { return Status(); }
+
+ /// 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 Status DoHalt(bool &caused_stop) {
+ Status 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 Status WillDetach() { return Status(); }
+
+ /// Detaches from a running or stopped process.
+ ///
+ /// \return
+ /// Returns \b true if the process successfully detaches, \b
+ /// false otherwise.
+ virtual Status DoDetach(bool keep_stopped) {
+ Status 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 Status WillSignal() { return Status(); }
+
+ /// Sends a process a UNIX signal \a signal.
+ ///
+ /// \return
+ /// Returns an error object.
+ virtual Status DoSignal(int signal) {
+ Status error;
+ error.SetErrorStringWithFormat(
+ "error: %s does not support sending signals to processes",
+ GetPluginName().GetCString());
+ return error;
+ }
+
+ virtual Status WillDestroy() { return Status(); }
+
+ virtual Status 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.
+ ///
+ /// \return
+ /// Returns the version tuple of the host OS. In case of failure an empty
+ /// VersionTuple is returner.
+ virtual llvm::VersionTuple GetHostOSVersion() { return llvm::VersionTuple(); }
+
+ /// 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_wp.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_wp.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);
+
+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.
+ ///
+ /// \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 number of bytes that were actually read into \a buf.
+ /// Zero is returned in the case of an error.
+ virtual size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
+ Status &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.
+ ///
+ /// \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 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 in the case of an error.
+ virtual size_t ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
+ Status &error);
+
+ /// Read of memory from a process.
+ ///
+ /// This function has the same semantics of ReadMemory except that it
+ /// bypasses caching.
+ ///
+ /// \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.
+ ///
+ /// \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 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 in the case of an error.
+ size_t ReadMemoryFromInferior(lldb::addr_t vm_addr, void *buf, size_t size,
+ Status &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,
+ Status &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, Status &error);
+
+ size_t ReadCStringFromMemory(lldb::addr_t vm_addr, std::string &out_str,
+ Status &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,
+ Status &error);
+
+ int64_t ReadSignedIntegerFromMemory(lldb::addr_t load_addr, size_t byte_size,
+ int64_t fail_value, Status &error);
+
+ lldb::addr_t ReadPointerFromMemory(lldb::addr_t vm_addr, Status &error);
+
+ bool WritePointerToMemory(lldb::addr_t vm_addr, lldb::addr_t ptr_value,
+ Status &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, Status &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, Status &error);
+
+ size_t ReadScalarIntegerFromMemory(lldb::addr_t addr, uint32_t byte_size,
+ bool is_signed, Scalar &scalar,
+ Status &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,
+ Status &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,
+ Status &error) {
+ error.SetErrorStringWithFormat(
+ "error: %s does not support allocating in the debug process",
+ GetPluginName().GetCString());
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ virtual Status WriteObjectFile(std::vector<ObjectFile::LoadableData> entries);
+
+ /// 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, Status &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,
+ Status &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,
+ Status &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 Status GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &range_info) {
+ Status 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 Status
+ GetMemoryRegions(lldb_private::MemoryRegionInfos ®ion_list);
+
+ virtual Status GetWatchpointSupportInfo(uint32_t &num) {
+ Status error;
+ num = 0;
+ error.SetErrorString("Process::GetWatchpointSupportInfo() not supported");
+ return error;
+ }
+
+ virtual Status GetWatchpointSupportInfo(uint32_t &num, bool &after) {
+ Status 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 Status DoDeallocateMemory(lldb::addr_t ptr) {
+ Status 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.
+ Status 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, Status &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, Status &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, Status &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, Status &error);
+
+ // Process Breakpoints
+ size_t GetSoftwareBreakpointTrapOpcode(BreakpointSite *bp_site);
+
+ virtual Status EnableBreakpointSite(BreakpointSite *bp_site) {
+ Status error;
+ error.SetErrorStringWithFormat(
+ "error: %s does not support enabling breakpoints",
+ GetPluginName().GetCString());
+ return error;
+ }
+
+ virtual Status DisableBreakpointSite(BreakpointSite *bp_site) {
+ Status 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 Status 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 Status DisableSoftwareBreakpoint(BreakpointSite *bp_site);
+
+ BreakpointSiteList &GetBreakpointSiteList();
+
+ const BreakpointSiteList &GetBreakpointSiteList() const;
+
+ void DisableAllBreakpointSites();
+
+ Status ClearBreakpointSiteByID(lldb::user_id_t break_id);
+
+ lldb::break_id_t CreateBreakpointSite(const lldb::BreakpointLocationSP &owner,
+ bool use_hardware);
+
+ Status DisableBreakpointSiteByID(lldb::user_id_t break_id);
+
+ Status 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 Status EnableWatchpoint(Watchpoint *wp, bool notify = true);
+
+ virtual Status 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
+ /// The maximum time length to wait for the process to transition to the
+ /// eStateRunning state.
+ void SyncIOHandler(uint32_t iohandler_id, const Timeout<std::micro> &timeout);
+
+ 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();
+
+ bool StateChangedIsHijackedForSynchronousResume();
+
+ bool StateChangedIsExternallyHijacked();
+
+ const lldb::ABISP &GetABI();
+
+ OperatingSystem *GetOperatingSystem() { return m_os_up.get(); }
+
+ std::vector<LanguageRuntime *>
+ GetLanguageRuntimes(bool retry_if_null = true);
+
+ LanguageRuntime *GetLanguageRuntime(lldb::LanguageType language,
+ bool retry_if_null = true);
+
+ bool IsPossibleDynamicValue(ValueObject &in_value);
+
+ bool IsRunning() const;
+
+ DynamicCheckerFunctions *GetDynamicCheckers() {
+ return m_dynamic_checkers_up.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);
+ void SetRunningUtilityFunction(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 ®ion);
+
+ // Remove a permanent region of memory that should never be read or written
+ // to that was previously added with AddInvalidMemoryRegion.
+ bool RemoveInvalidMemoryRange(const LoadRange ®ion);
+
+ // 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 Status SendEventData(const char *data) {
+ Status 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 Status GetFileLoadAddress(const FileSpec &file, bool &is_loaded,
+ lldb::addr_t &load_addr) {
+ return Status("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 Status
+ ConfigureStructuredData(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(ConstString type_name) const;
+
+ /// Starts tracing with the configuration provided in options. To enable
+ /// tracing on the complete process the thread_id in the options should be
+ /// set to LLDB_INVALID_THREAD_ID. The API returns a user_id which is needed
+ /// by other API's that manipulate the trace instance. The handling of
+ /// erroneous or unsupported configuration is left to the trace technology
+ /// implementations in the server, as they could be returned as an error, or
+ /// rounded to a valid configuration to start tracing. In the later case the
+ /// GetTraceConfig should supply the actual used trace configuration.
+ virtual lldb::user_id_t StartTrace(const TraceOptions &options,
+ Status &error) {
+ error.SetErrorString("Not implemented");
+ return LLDB_INVALID_UID;
+ }
+
+ /// Stops the tracing instance leading to deletion of the trace data. The
+ /// tracing instance is identified by the user_id which is obtained when
+ /// tracing was started from the StartTrace. In case tracing of the complete
+ /// process needs to be stopped the thread_id should be set to
+ /// LLDB_INVALID_THREAD_ID. In the other case that tracing on an individual
+ /// thread needs to be stopped a thread_id can be supplied.
+ virtual Status StopTrace(lldb::user_id_t uid, lldb::tid_t thread_id) {
+ return Status("Not implemented");
+ }
+
+ /// Provides the trace data as raw bytes. A buffer needs to be supplied to
+ /// copy the trace data. The exact behavior of this API may vary across
+ /// trace technology, as some may support partial reading of the trace data
+ /// from a specified offset while some may not. The thread_id should be used
+ /// to select a particular thread for trace extraction.
+ virtual Status GetData(lldb::user_id_t uid, lldb::tid_t thread_id,
+ llvm::MutableArrayRef<uint8_t> &buffer,
+ size_t offset = 0) {
+ return Status("Not implemented");
+ }
+
+ /// Similar API as above except for obtaining meta data
+ virtual Status GetMetaData(lldb::user_id_t uid, lldb::tid_t thread_id,
+ llvm::MutableArrayRef<uint8_t> &buffer,
+ size_t offset = 0) {
+ return Status("Not implemented");
+ }
+
+ /// API to obtain the trace configuration used by a trace instance.
+ /// Configurations that may be specific to some trace technology should be
+ /// stored in the custom parameters. The options are transported to the
+ /// server, which shall interpret accordingly. The thread_id can be
+ /// specified in the options to obtain the configuration used by a specific
+ /// thread. The thread_id specified should also match the uid otherwise an
+ /// error will be returned.
+ virtual Status GetTraceConfig(lldb::user_id_t uid, TraceOptions &options) {
+ return Status("Not implemented");
+ }
+
+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 Status object describing the success or failure of the resume.
+ Status 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:
+ enum EventActionResult {
+ eEventActionSuccess,
+ eEventActionRetry,
+ eEventActionExit
+ };
+
+ 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_up.get())
+ m_next_event_action_up->HandleBeingUnshipped();
+
+ m_next_event_action_up.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,
+ /// 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_wp; ///< 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_up;
+ lldb::JITLoaderListUP m_jit_loaders_up;
+ lldb::DynamicCheckerFunctionsUP m_dynamic_checkers_up; ///< The functions used
+ /// by the expression
+ /// parser to validate
+ /// data that
+ /// expressions use.
+ lldb::OperatingSystemUP m_os_up;
+ lldb::SystemRuntimeUP m_system_runtime_up;
+ 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;
+ std::recursive_mutex m_language_runtimes_mutex;
+ InstrumentationRuntimeCollection m_instrumentation_runtimes;
+ std::unique_ptr<NextEventAction> m_next_event_action_up;
+ std::vector<PreResumeCallbackAndBaton> m_pre_resume_actions;
+ ProcessRunLock m_public_run_lock;
+ ProcessRunLock m_private_run_lock;
+ 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;
+
+ std::unique_ptr<UtilityFunction> m_dlopen_utility_func_up;
+ std::once_flag m_dlopen_utility_func_flag_once;
+
+ 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();
+
+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);
+
+protected:
+ void HandlePrivateEvent(lldb::EventSP &event_sp);
+
+ Status HaltPrivate();
+
+ lldb::StateType WaitForProcessStopPrivate(lldb::EventSP &event_sp,
+ const Timeout<std::micro> &timeout);
+
+ // This waits for both the state change broadcaster, and the control
+ // broadcaster. If control_only, it only waits for the control broadcaster.
+
+ bool GetEventsPrivate(lldb::EventSP &event_sp,
+ const Timeout<std::micro> &timeout, bool control_only);
+
+ lldb::StateType
+ GetStateChangedEventsPrivate(lldb::EventSP &event_sp,
+ const Timeout<std::micro> &timeout);
+
+ size_t WriteMemoryPrivate(lldb::addr_t addr, const void *buf, size_t size,
+ Status &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);
+ }
+
+ Status StopForDestroyOrDetach(lldb::EventSP &exit_event_sp);
+
+ virtual Status UpdateAutomaticSignalFiltering();
+
+ 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);
+};
+
+/// RAII guard that should be aquired when an utility function is called within
+/// a given process.
+class UtilityFunctionScope {
+ Process *m_process;
+
+public:
+ UtilityFunctionScope(Process *p) : m_process(p) {
+ if (m_process)
+ m_process->SetRunningUtilityFunction(true);
+ }
+ ~UtilityFunctionScope() {
+ if (m_process)
+ m_process->SetRunningUtilityFunction(false);
+ }
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Process_h_
diff --git a/linux-x64/clang/include/lldb/Target/ProcessStructReader.h b/linux-x64/clang/include/lldb/Target/ProcessStructReader.h
new file mode 100644
index 0000000..ade29c0
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/ProcessStructReader.h
@@ -0,0 +1,104 @@
+//===---------------------ProcessStructReader.h ------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_TARGET_PROCESSSTRUCTREADER_H
+#define LLDB_TARGET_PROCESSSTRUCTREADER_H
+
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-types.h"
+
+#include "lldb/Symbol/CompilerType.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/Status.h"
+
+#include <initializer_list>
+#include <map>
+#include <string>
+
+namespace lldb_private {
+class ProcessStructReader {
+protected:
+ struct FieldImpl {
+ CompilerType type;
+ size_t offset;
+ size_t size;
+ };
+
+ std::map<ConstString, FieldImpl> m_fields;
+ DataExtractor m_data;
+ lldb::ByteOrder m_byte_order;
+ size_t m_addr_byte_size;
+
+public:
+ ProcessStructReader(Process *process, lldb::addr_t base_addr,
+ CompilerType struct_type) {
+ if (!process)
+ return;
+ if (base_addr == 0 || base_addr == LLDB_INVALID_ADDRESS)
+ return;
+ m_byte_order = process->GetByteOrder();
+ m_addr_byte_size = process->GetAddressByteSize();
+
+ for (size_t idx = 0; idx < struct_type.GetNumFields(); idx++) {
+ std::string name;
+ uint64_t bit_offset;
+ uint32_t bitfield_bit_size;
+ bool is_bitfield;
+ CompilerType field_type = struct_type.GetFieldAtIndex(
+ idx, name, &bit_offset, &bitfield_bit_size, &is_bitfield);
+ // no support for bitfields in here (yet)
+ if (is_bitfield)
+ return;
+ auto size = field_type.GetByteSize(nullptr);
+ // no support for things larger than a uint64_t (yet)
+ if (!size || *size > 8)
+ return;
+ ConstString const_name = ConstString(name.c_str());
+ size_t byte_index = static_cast<size_t>(bit_offset / 8);
+ m_fields[const_name] =
+ FieldImpl{field_type, byte_index, static_cast<size_t>(*size)};
+ }
+ auto total_size = struct_type.GetByteSize(nullptr);
+ if (!total_size)
+ return;
+ lldb::DataBufferSP buffer_sp(new DataBufferHeap(*total_size, 0));
+ Status error;
+ process->ReadMemoryFromInferior(base_addr, buffer_sp->GetBytes(),
+ *total_size, error);
+ if (error.Fail())
+ return;
+ m_data = DataExtractor(buffer_sp, m_byte_order, m_addr_byte_size);
+ }
+
+ template <typename RetType>
+ RetType GetField(ConstString name, RetType fail_value = RetType()) {
+ auto iter = m_fields.find(name), end = m_fields.end();
+ if (iter == end)
+ return fail_value;
+ auto size = iter->second.size;
+ if (sizeof(RetType) < size)
+ return fail_value;
+ lldb::offset_t offset = iter->second.offset;
+ if (offset + size > m_data.GetByteSize())
+ return fail_value;
+ return (RetType)(m_data.GetMaxU64(&offset, size));
+ }
+
+ size_t GetOffsetOf(ConstString name, size_t fail_value = SIZE_MAX) {
+ auto iter = m_fields.find(name), end = m_fields.end();
+ if (iter == end)
+ return fail_value;
+ return iter->second.offset;
+ }
+};
+}
+
+#endif // utility_ProcessStructReader_h_
diff --git a/linux-x64/clang/include/lldb/Target/Queue.h b/linux-x64/clang/include/lldb/Target/Queue.h
new file mode 100644
index 0000000..01e8994
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/Queue.h
@@ -0,0 +1,155 @@
+//===-- Queue.h ------------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Queue_h_
+#define liblldb_Queue_h_
+
+#include <string>
+#include <vector>
+
+#include "lldb/Target/QueueItem.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+// Queue:
+// This class represents a libdispatch aka Grand Central Dispatch queue in the
+// process.
+//
+// A program using libdispatch will create queues, put work items
+// (functions, blocks) on the queues. The system will create / reassign
+// pthreads to execute the work items for the queues. A serial queue will be
+// associated with a single thread (or possibly no thread, if it is not doing
+// any work). A concurrent queue may be associated with multiple threads.
+
+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);
+
+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);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Queue_h_
diff --git a/linux-x64/clang/include/lldb/Target/QueueItem.h b/linux-x64/clang/include/lldb/Target/QueueItem.h
new file mode 100644
index 0000000..dfae3b8
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/QueueItem.h
@@ -0,0 +1,167 @@
+//===-- QueueItem.h ---------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_QueueItem_h_
+#define liblldb_QueueItem_h_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private.h"
+
+#include "lldb/Core/Address.h"
+#include "lldb/Utility/ConstString.h"
+
+namespace lldb_private {
+
+// QueueItem:
+// This class represents a work item enqueued on a libdispatch aka 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", execution of the item
+// begins.
+
+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();
+
+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;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(QueueItem);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_QueueItem_h_
diff --git a/linux-x64/clang/include/lldb/Target/QueueList.h b/linux-x64/clang/include/lldb/Target/QueueList.h
new file mode 100644
index 0000000..761107e
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/QueueList.h
@@ -0,0 +1,110 @@
+//===-- QueueList.h --------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_QueueList_h_
+#define liblldb_QueueList_h_
+
+#include <mutex>
+#include <vector>
+
+#include "lldb/Utility/Iterable.h"
+#include "lldb/Utility/UserID.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+// QueueList:
+// 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 SystemRuntime.
+
+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();
+
+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;
+
+private:
+ QueueList() = delete;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_QueueList_h_
diff --git a/linux-x64/clang/include/lldb/Target/RegisterCheckpoint.h b/linux-x64/clang/include/lldb/Target/RegisterCheckpoint.h
new file mode 100644
index 0000000..4f9654f
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/RegisterCheckpoint.h
@@ -0,0 +1,53 @@
+//===-- RegisterCheckpoint.h ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_RegisterCheckpoint_h_
+#define liblldb_RegisterCheckpoint_h_
+
+#include "lldb/Target/StackID.h"
+#include "lldb/Utility/UserID.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);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_RegisterCheckpoint_h_
diff --git a/linux-x64/clang/include/lldb/Target/RegisterContext.h b/linux-x64/clang/include/lldb/Target/RegisterContext.h
new file mode 100644
index 0000000..d6212dd
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/RegisterContext.h
@@ -0,0 +1,209 @@
+//===-- RegisterContext.h ---------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_RegisterContext_h_
+#define liblldb_RegisterContext_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 {
+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 ®_value) = 0;
+
+ virtual bool WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue ®_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 ®_checkpoint);
+
+ virtual bool WriteAllRegisterValues(
+ const lldb_private::RegisterCheckpoint ®_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 Status
+ ReadRegisterValueFromMemory(const lldb_private::RegisterInfo *reg_info,
+ lldb::addr_t src_addr, uint32_t src_len,
+ RegisterValue ®_value);
+
+ virtual Status
+ WriteRegisterValueToMemory(const lldb_private::RegisterInfo *reg_info,
+ lldb::addr_t dst_addr, uint32_t dst_len,
+ const RegisterValue ®_value);
+
+ // Subclasses should not override these
+ virtual lldb::tid_t GetThreadID() const;
+
+ virtual Thread &GetThread() { return m_thread; }
+
+ const RegisterInfo *GetRegisterInfoByName(llvm::StringRef reg_name,
+ uint32_t start_idx = 0);
+
+ const RegisterInfo *GetRegisterInfo(lldb::RegisterKind reg_kind,
+ uint32_t reg_num);
+
+ uint64_t GetPC(uint64_t fail_value = LLDB_INVALID_ADDRESS);
+
+ bool SetPC(uint64_t pc);
+
+ bool SetPC(Address addr);
+
+ uint64_t GetSP(uint64_t fail_value = LLDB_INVALID_ADDRESS);
+
+ bool SetSP(uint64_t sp);
+
+ uint64_t GetFP(uint64_t fail_value = LLDB_INVALID_ADDRESS);
+
+ bool SetFP(uint64_t fp);
+
+ const char *GetRegisterName(uint32_t reg);
+
+ uint64_t GetReturnAddress(uint64_t fail_value = LLDB_INVALID_ADDRESS);
+
+ uint64_t GetFlags(uint64_t fail_value = 0);
+
+ uint64_t ReadRegisterAsUnsigned(uint32_t reg, uint64_t fail_value);
+
+ uint64_t ReadRegisterAsUnsigned(const RegisterInfo *reg_info,
+ uint64_t fail_value);
+
+ bool WriteRegisterFromUnsigned(uint32_t reg, uint64_t uval);
+
+ bool WriteRegisterFromUnsigned(const RegisterInfo *reg_info, uint64_t uval);
+
+ bool ConvertBetweenRegisterKinds(lldb::RegisterKind source_rk,
+ uint32_t source_regnum,
+ lldb::RegisterKind target_rk,
+ uint32_t &target_regnum);
+
+ // lldb::ExecutionContextScope pure virtual functions
+ lldb::TargetSP CalculateTarget() override;
+
+ lldb::ProcessSP CalculateProcess() override;
+
+ lldb::ThreadSP CalculateThread() override;
+
+ lldb::StackFrameSP CalculateStackFrame() override;
+
+ void CalculateExecutionContext(ExecutionContext &exe_ctx) override;
+
+ uint32_t GetStopID() const { return m_stop_id; }
+
+ void SetStopID(uint32_t stop_id) { m_stop_id = stop_id; }
+
+protected:
+ // Classes that inherit from RegisterContext can see and modify these
+ Thread &m_thread; // The thread that this register context belongs to.
+ uint32_t m_concrete_frame_idx; // The concrete frame index for this register
+ // context
+ uint32_t m_stop_id; // The stop ID that any data in this context is valid for
+private:
+ // For RegisterContext only
+ DISALLOW_COPY_AND_ASSIGN(RegisterContext);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_RegisterContext_h_
diff --git a/linux-x64/clang/include/lldb/Target/RegisterNumber.h b/linux-x64/clang/include/lldb/Target/RegisterNumber.h
new file mode 100644
index 0000000..0bef0c1
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/RegisterNumber.h
@@ -0,0 +1,59 @@
+//===-- RegisterNumber.h ----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_TARGET_REGISTERNUMBER_H
+#define LLDB_TARGET_REGISTERNUMBER_H
+
+#include "lldb/lldb-private.h"
+#include <map>
+
+/// A class to represent register numbers, and able to convert between
+/// different register numbering schemes that may be used in a single
+/// debug session.
+
+class RegisterNumber {
+public:
+ RegisterNumber(lldb_private::Thread &thread, lldb::RegisterKind kind,
+ uint32_t num);
+
+ // This constructor plus the init() method below allow for the placeholder
+ // creation of an invalid object initially, possibly to be filled in. It
+ // would be more consistent to have three Set* methods to set the three data
+ // that the object needs.
+ RegisterNumber();
+
+ void init(lldb_private::Thread &thread, lldb::RegisterKind kind,
+ uint32_t num);
+
+ const RegisterNumber &operator=(const RegisterNumber &rhs);
+
+ bool operator==(RegisterNumber &rhs);
+
+ bool operator!=(RegisterNumber &rhs);
+
+ bool IsValid() const;
+
+ uint32_t GetAsKind(lldb::RegisterKind kind);
+
+ uint32_t GetRegisterNumber() const;
+
+ lldb::RegisterKind GetRegisterKind() const;
+
+ const char *GetName();
+
+private:
+ typedef std::map<lldb::RegisterKind, uint32_t> Collection;
+
+ lldb::RegisterContextSP m_reg_ctx_sp;
+ uint32_t m_regnum;
+ lldb::RegisterKind m_kind;
+ Collection m_kind_regnum_map;
+ const char *m_name;
+};
+
+#endif // liblldb_RegisterNumber_h
diff --git a/linux-x64/clang/include/lldb/Target/RemoteAwarePlatform.h b/linux-x64/clang/include/lldb/Target/RemoteAwarePlatform.h
new file mode 100644
index 0000000..524332f
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/RemoteAwarePlatform.h
@@ -0,0 +1,97 @@
+//===-- RemoteAwarePlatform.h -----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_TARGET_REMOTEAWAREPLATFORM_H
+#define LLDB_TARGET_REMOTEAWAREPLATFORM_H
+
+#include "lldb/Target/Platform.h"
+
+namespace lldb_private {
+
+/// A base class for platforms which automatically want to be able to forward
+/// operations to a remote platform instance (such as PlatformRemoteGDBServer).
+class RemoteAwarePlatform : public Platform {
+public:
+ using Platform::Platform;
+
+ bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch,
+ ModuleSpec &module_spec) override;
+
+ lldb::user_id_t OpenFile(const FileSpec &file_spec, uint32_t flags,
+ uint32_t mode, Status &error) override;
+
+ bool CloseFile(lldb::user_id_t fd, Status &error) override;
+
+ uint64_t ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst,
+ uint64_t dst_len, Status &error) override;
+
+ uint64_t WriteFile(lldb::user_id_t fd, uint64_t offset, const void *src,
+ uint64_t src_len, Status &error) override;
+
+ lldb::user_id_t GetFileSize(const FileSpec &file_spec) override;
+
+ Status CreateSymlink(const FileSpec &src, const FileSpec &dst) override;
+
+ bool GetFileExists(const FileSpec &file_spec) override;
+
+ Status Unlink(const FileSpec &file_spec) override;
+
+ FileSpec GetRemoteWorkingDirectory() override;
+
+ bool SetRemoteWorkingDirectory(const FileSpec &working_dir) override;
+
+ Status MakeDirectory(const FileSpec &file_spec, uint32_t mode) override;
+
+ Status GetFilePermissions(const FileSpec &file_spec,
+ uint32_t &file_permissions) override;
+
+ Status SetFilePermissions(const FileSpec &file_spec,
+ uint32_t file_permissions) override;
+
+ bool CalculateMD5(const FileSpec &file_spec, uint64_t &low,
+ uint64_t &high) override;
+
+ Status GetFileWithUUID(const FileSpec &platform_file, const UUID *uuid,
+ FileSpec &local_file) override;
+
+ bool GetRemoteOSVersion() override;
+ bool GetRemoteOSBuildString(std::string &s) override;
+ bool GetRemoteOSKernelDescription(std::string &s) override;
+ ArchSpec GetRemoteSystemArchitecture() override;
+
+ Status RunShellCommand(const char *command, const FileSpec &working_dir,
+ int *status_ptr, int *signo_ptr,
+ std::string *command_output,
+ const Timeout<std::micro> &timeout) override;
+
+ const char *GetHostname() override;
+ UserIDResolver &GetUserIDResolver() override;
+ lldb_private::Environment GetEnvironment() override;
+
+ bool IsConnected() const override;
+
+ bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info) override;
+ uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info,
+ ProcessInstanceInfoList &process_infos) override;
+
+ lldb::ProcessSP ConnectProcess(llvm::StringRef connect_url,
+ llvm::StringRef plugin_name,
+ Debugger &debugger, Target *target,
+ Status &error) override;
+
+ Status LaunchProcess(ProcessLaunchInfo &launch_info) override;
+
+ Status KillProcess(const lldb::pid_t pid) override;
+
+protected:
+ lldb::PlatformSP m_remote_platform_sp;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_TARGET_REMOTEAWAREPLATFORM_H
diff --git a/linux-x64/clang/include/lldb/Target/SectionLoadHistory.h b/linux-x64/clang/include/lldb/Target/SectionLoadHistory.h
new file mode 100644
index 0000000..71b5d0c
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/SectionLoadHistory.h
@@ -0,0 +1,83 @@
+//===-- SectionLoadHistory.h ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_SectionLoadHistory_h_
+#define liblldb_SectionLoadHistory_h_
+
+#include <map>
+#include <mutex>
+
+#include "lldb/lldb-public.h"
+
+namespace lldb_private {
+
+class SectionLoadHistory {
+public:
+ enum : unsigned {
+ // Pass eStopIDNow to any function that takes a stop ID to get the current
+ // value.
+ eStopIDNow = UINT32_MAX
+ };
+ // Constructors and Destructors
+ SectionLoadHistory() : m_stop_id_to_section_load_list(), m_mutex() {}
+
+ ~SectionLoadHistory() {
+ // Call clear since this takes a lock and clears the section load list in
+ // case another thread is currently using this section load list
+ Clear();
+ }
+
+ SectionLoadList &GetCurrentSectionLoadList();
+
+ bool IsEmpty() const;
+
+ void Clear();
+
+ uint32_t GetLastStopID() const;
+
+ // Get the section load address given a process stop ID
+ lldb::addr_t GetSectionLoadAddress(uint32_t stop_id,
+ const lldb::SectionSP §ion_sp);
+
+ bool ResolveLoadAddress(uint32_t stop_id, lldb::addr_t load_addr,
+ Address &so_addr);
+
+ bool SetSectionLoadAddress(uint32_t stop_id,
+ const lldb::SectionSP §ion_sp,
+ lldb::addr_t load_addr,
+ bool warn_multiple = false);
+
+ // The old load address should be specified when unloading to ensure we get
+ // the correct instance of the section as a shared library could be loaded at
+ // more than one location.
+ bool SetSectionUnloaded(uint32_t stop_id, const lldb::SectionSP §ion_sp,
+ lldb::addr_t load_addr);
+
+ // Unload all instances of a section. This function can be used on systems
+ // that don't support multiple copies of the same shared library to be loaded
+ // at the same time.
+ size_t SetSectionUnloaded(uint32_t stop_id,
+ const lldb::SectionSP §ion_sp);
+
+ void Dump(Stream &s, Target *target);
+
+protected:
+ SectionLoadList *GetSectionLoadListForStopID(uint32_t stop_id,
+ bool read_only);
+
+ typedef std::map<uint32_t, lldb::SectionLoadListSP> StopIDToSectionLoadList;
+ StopIDToSectionLoadList m_stop_id_to_section_load_list;
+ mutable std::recursive_mutex m_mutex;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(SectionLoadHistory);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_SectionLoadHistory_h_
diff --git a/linux-x64/clang/include/lldb/Target/SectionLoadList.h b/linux-x64/clang/include/lldb/Target/SectionLoadList.h
new file mode 100644
index 0000000..caefa00
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/SectionLoadList.h
@@ -0,0 +1,73 @@
+//===-- SectionLoadList.h -----------------------------------------------*- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_SectionLoadList_h_
+#define liblldb_SectionLoadList_h_
+
+#include <map>
+#include <mutex>
+
+#include "llvm/ADT/DenseMap.h"
+#include "lldb/Core/Section.h"
+#include "lldb/lldb-public.h"
+
+namespace lldb_private {
+
+class SectionLoadList {
+public:
+ // Constructors and Destructors
+ SectionLoadList() : m_addr_to_sect(), m_sect_to_addr(), m_mutex() {}
+
+ SectionLoadList(const SectionLoadList &rhs);
+
+ ~SectionLoadList() {
+ // Call clear since this takes a lock and clears the section load list in
+ // case another thread is currently using this section load list
+ Clear();
+ }
+
+ void operator=(const SectionLoadList &rhs);
+
+ bool IsEmpty() const;
+
+ void Clear();
+
+ lldb::addr_t GetSectionLoadAddress(const lldb::SectionSP §ion_sp) const;
+
+ bool ResolveLoadAddress(lldb::addr_t load_addr, Address &so_addr,
+ bool allow_section_end = false) const;
+
+ bool SetSectionLoadAddress(const lldb::SectionSP §ion_sp,
+ lldb::addr_t load_addr,
+ bool warn_multiple = false);
+
+ // The old load address should be specified when unloading to ensure we get
+ // the correct instance of the section as a shared library could be loaded at
+ // more than one location.
+ bool SetSectionUnloaded(const lldb::SectionSP §ion_sp,
+ lldb::addr_t load_addr);
+
+ // Unload all instances of a section. This function can be used on systems
+ // that don't support multiple copies of the same shared library to be loaded
+ // at the same time.
+ size_t SetSectionUnloaded(const lldb::SectionSP §ion_sp);
+
+ void Dump(Stream &s, Target *target);
+
+protected:
+ typedef std::map<lldb::addr_t, lldb::SectionSP> addr_to_sect_collection;
+ typedef llvm::DenseMap<const Section *, lldb::addr_t> sect_to_addr_collection;
+ addr_to_sect_collection m_addr_to_sect;
+ sect_to_addr_collection m_sect_to_addr;
+ mutable std::recursive_mutex m_mutex;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_SectionLoadList_h_
diff --git a/linux-x64/clang/include/lldb/Target/StackFrame.h b/linux-x64/clang/include/lldb/Target/StackFrame.h
new file mode 100644
index 0000000..4e6e79b
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/StackFrame.h
@@ -0,0 +1,527 @@
+//===-- StackFrame.h --------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_StackFrame_h_
+#define liblldb_StackFrame_h_
+
+#include <memory>
+#include <mutex>
+
+#include "lldb/Utility/Flags.h"
+
+#include "lldb/Core/ValueObjectList.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Target/StackID.h"
+#include "lldb/Utility/Scalar.h"
+#include "lldb/Utility/Status.h"
+#include "lldb/Utility/StreamString.h"
+#include "lldb/Utility/UserID.h"
+
+namespace lldb_private {
+
+/// \class StackFrame StackFrame.h "lldb/Target/StackFrame.h"
+///
+/// This base class provides an interface to stack frames.
+///
+/// StackFrames may have a Canonical Frame Address (CFA) or not.
+/// A frame may have a plain pc value or it may indicate a specific point in
+/// the debug session so the correct section load list is used for
+/// symbolication.
+///
+/// Local variables may be available, or not. A register context may be
+/// available, or not.
+
+class StackFrame : public ExecutionContextScope,
+ public std::enable_shared_from_this<StackFrame> {
+public:
+ enum ExpressionPathOption {
+ eExpressionPathOptionCheckPtrVsMember = (1u << 0),
+ eExpressionPathOptionsNoFragileObjcIvar = (1u << 1),
+ eExpressionPathOptionsNoSyntheticChildren = (1u << 2),
+ eExpressionPathOptionsNoSyntheticArrayRange = (1u << 3),
+ eExpressionPathOptionsAllowDirectIVarAccess = (1u << 4),
+ eExpressionPathOptionsInspectAnonymousUnions = (1u << 5)
+ };
+
+ enum class Kind {
+ /// A regular stack frame with access to registers and local variables.
+ Regular,
+
+ /// A historical stack frame -- possibly without CFA or registers or
+ /// local variables.
+ History,
+
+ /// An artificial stack frame (e.g. a synthesized result of inferring
+ /// missing tail call frames from a backtrace) with limited support for
+ /// local variables.
+ Artificial
+ };
+
+ /// Construct a StackFrame object without supplying a RegisterContextSP.
+ ///
+ /// This is the one constructor that doesn't take a RegisterContext
+ /// parameter. This ctor may be called when creating a history StackFrame;
+ /// these are used if we've collected a stack trace of pc addresses at some
+ /// point in the past. We may only have pc values. We may have a CFA,
+ /// or more likely, we won't.
+ ///
+ /// \param [in] thread_sp
+ /// The Thread that this frame belongs to.
+ ///
+ /// \param [in] frame_idx
+ /// This StackFrame's frame index number in the Thread. If inlined stack
+ /// frames are being created, this may differ from the concrete_frame_idx
+ /// which is the frame index without any inlined stack frames.
+ ///
+ /// \param [in] concrete_frame_idx
+ /// The StackFrame's frame index number in the Thread without any inlined
+ /// stack frames being included in the index.
+ ///
+ /// \param [in] cfa
+ /// The Canonical Frame Address (this terminology from DWARF) for this
+ /// stack frame. The CFA for a stack frame does not change over the
+ /// span of the stack frame's existence. It is often the value of the
+ /// caller's stack pointer before the call instruction into this frame's
+ /// function. It is usually not the same as the frame pointer register's
+ /// value.
+ ///
+ /// \param [in] cfa_is_valid
+ /// A history stack frame may not have a CFA value collected. We want to
+ /// distinguish between "no CFA available" and a CFA of
+ /// LLDB_INVALID_ADDRESS.
+ ///
+ /// \param [in] pc
+ /// The current pc value of this stack frame.
+ ///
+ /// \param [in] frame_kind
+ ///
+ /// \param [in] sc_ptr
+ /// Optionally seed the StackFrame with the SymbolContext information that
+ /// has
+ /// already been discovered.
+ StackFrame(const lldb::ThreadSP &thread_sp, lldb::user_id_t frame_idx,
+ lldb::user_id_t concrete_frame_idx, lldb::addr_t cfa,
+ bool cfa_is_valid, lldb::addr_t pc, Kind frame_kind,
+ const SymbolContext *sc_ptr);
+
+ StackFrame(const lldb::ThreadSP &thread_sp, lldb::user_id_t frame_idx,
+ lldb::user_id_t concrete_frame_idx,
+ const lldb::RegisterContextSP ®_context_sp, lldb::addr_t cfa,
+ lldb::addr_t pc, const SymbolContext *sc_ptr);
+
+ StackFrame(const lldb::ThreadSP &thread_sp, lldb::user_id_t frame_idx,
+ lldb::user_id_t concrete_frame_idx,
+ const lldb::RegisterContextSP ®_context_sp, lldb::addr_t cfa,
+ const Address &pc, const SymbolContext *sc_ptr);
+
+ ~StackFrame() override;
+
+ lldb::ThreadSP GetThread() const { return m_thread_wp.lock(); }
+
+ StackID &GetStackID();
+
+ /// Get an Address for the current pc value in this StackFrame.
+ ///
+ /// May not be the same as the actual PC value for inlined stack frames.
+ ///
+ /// \return
+ /// The Address object set to the current PC value.
+ const Address &GetFrameCodeAddress();
+
+ /// Change the pc value for a given thread.
+ ///
+ /// Change the current pc value for the frame on this thread.
+ ///
+ /// \param[in] pc
+ /// The load address that the pc will be set to.
+ ///
+ /// \return
+ /// true if the pc was changed. false if this failed -- possibly
+ /// because this frame is not a live StackFrame.
+ bool ChangePC(lldb::addr_t pc);
+
+ /// Provide a SymbolContext for this StackFrame's current pc value.
+ ///
+ /// The StackFrame maintains this SymbolContext and adds additional
+ /// information to it on an as-needed basis. This helps to avoid different
+ /// functions looking up symbolic information for a given pc value multiple
+ /// times.
+ ///
+ /// \params [in] resolve_scope
+ /// Flags from the SymbolContextItem enumerated type which specify what
+ /// type of symbol context is needed by this caller.
+ ///
+ /// \return
+ /// A SymbolContext reference which includes the types of information
+ /// requested by resolve_scope, if they are available.
+ const SymbolContext &GetSymbolContext(lldb::SymbolContextItem resolve_scope);
+
+ /// Return the Canonical Frame Address (DWARF term) for this frame.
+ ///
+ /// The CFA is typically the value of the stack pointer register before the
+ /// call invocation is made. It will not change during the lifetime of a
+ /// stack frame. It is often not the same thing as the frame pointer
+ /// register value.
+ ///
+ /// Live StackFrames will always have a CFA but other types of frames may
+ /// not be able to supply one.
+ ///
+ /// \param [out] value
+ /// The address of the CFA for this frame, if available.
+ ///
+ /// \param [out] error_ptr
+ /// If there is an error determining the CFA address, this may contain a
+ /// string explaining the failure.
+ ///
+ /// \return
+ /// Returns true if the CFA value was successfully set in value. Some
+ /// frames may be unable to provide this value; they will return false.
+ bool GetFrameBaseValue(Scalar &value, Status *error_ptr);
+
+ /// Get the DWARFExpression corresponding to the Canonical Frame Address.
+ ///
+ /// Often a register (bp), but sometimes a register + offset.
+ ///
+ /// \param [out] error_ptr
+ /// If there is an error determining the CFA address, this may contain a
+ /// string explaining the failure.
+ ///
+ /// \return
+ /// Returns the corresponding DWARF expression, or NULL.
+ DWARFExpression *GetFrameBaseExpression(Status *error_ptr);
+
+ /// Get the current lexical scope block for this StackFrame, if possible.
+ ///
+ /// If debug information is available for this stack frame, return a pointer
+ /// to the innermost lexical Block that the frame is currently executing.
+ ///
+ /// \return
+ /// A pointer to the current Block. nullptr is returned if this can
+ /// not be provided.
+ Block *GetFrameBlock();
+
+ /// Get the RegisterContext for this frame, if possible.
+ ///
+ /// Returns a shared pointer to the RegisterContext for this stack frame.
+ /// Only a live StackFrame object will be able to return a RegisterContext -
+ /// callers must be prepared for an empty shared pointer being returned.
+ ///
+ /// Even a live StackFrame RegisterContext may not be able to provide all
+ /// registers. Only the currently executing frame (frame 0) can reliably
+ /// provide every register in the register context.
+ ///
+ /// \return
+ /// The RegisterContext shared point for this frame.
+ lldb::RegisterContextSP GetRegisterContext();
+
+ const lldb::RegisterContextSP &GetRegisterContextSP() const {
+ return m_reg_context_sp;
+ }
+
+ /// Retrieve the list of variables that are in scope at this StackFrame's
+ /// pc.
+ ///
+ /// A frame that is not live may return an empty VariableList for a given
+ /// pc value even though variables would be available at this point if it
+ /// were a live stack frame.
+ ///
+ /// \param[in] get_file_globals
+ /// Whether to also retrieve compilation-unit scoped variables
+ /// that are visible to the entire compilation unit (e.g. file
+ /// static in C, globals that are homed in this CU).
+ ///
+ /// \return
+ /// A pointer to a list of variables.
+ VariableList *GetVariableList(bool get_file_globals);
+
+ /// Retrieve the list of variables that are in scope at this StackFrame's
+ /// pc.
+ ///
+ /// A frame that is not live may return an empty VariableListSP for a
+ /// given pc value even though variables would be available at this point if
+ /// it were a live stack frame.
+ ///
+ /// \param[in] get_file_globals
+ /// Whether to also retrieve compilation-unit scoped variables
+ /// that are visible to the entire compilation unit (e.g. file
+ /// static in C, globals that are homed in this CU).
+ ///
+ /// \return
+ /// A pointer to a list of variables.
+ lldb::VariableListSP
+ GetInScopeVariableList(bool get_file_globals,
+ bool must_have_valid_location = false);
+
+ /// Create a ValueObject for a variable name / pathname, possibly including
+ /// simple dereference/child selection syntax.
+ ///
+ /// \param[in] var_expr
+ /// The string specifying a variable to base the VariableObject off
+ /// of.
+ ///
+ /// \param[in] use_dynamic
+ /// Whether the correct dynamic type of an object pointer should be
+ /// determined before creating the object, or if the static type is
+ /// sufficient. One of the DynamicValueType enumerated values.
+ ///
+ /// \param[in] options
+ /// An unsigned integer of flags, values from
+ /// StackFrame::ExpressionPathOption
+ /// enum.
+ /// \param[in] var_sp
+ /// A VariableSP that will be set to the variable described in the
+ /// var_expr path.
+ ///
+ /// \param[in] error
+ /// Record any errors encountered while evaluating var_expr.
+ ///
+ /// \return
+ /// A shared pointer to the ValueObject described by var_expr.
+ lldb::ValueObjectSP GetValueForVariableExpressionPath(
+ llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic,
+ uint32_t options, lldb::VariableSP &var_sp, Status &error);
+
+ /// Determine whether this StackFrame has debug information available or not
+ ///
+ /// \return
+ // true if debug information is available for this frame (function,
+ // compilation unit, block, etc.)
+ bool HasDebugInformation();
+
+ /// Return the disassembly for the instructions of this StackFrame's
+ /// function as a single C string.
+ ///
+ /// \return
+ // C string with the assembly instructions for this function.
+ const char *Disassemble();
+
+ /// Print a description for this frame using the frame-format formatter
+ /// settings.
+ ///
+ /// \param [in] strm
+ /// The Stream to print the description to.
+ ///
+ /// \param [in] show_unique
+ /// Whether to print the function arguments or not for backtrace unique.
+ ///
+ /// \param [in] frame_marker
+ /// Optional string that will be prepended to the frame output description.
+ void DumpUsingSettingsFormat(Stream *strm, bool show_unique = false,
+ const char *frame_marker = nullptr);
+
+ /// Print a description for this frame using a default format.
+ ///
+ /// \param [in] strm
+ /// The Stream to print the description to.
+ ///
+ /// \param [in] show_frame_index
+ /// Whether to print the frame number or not.
+ ///
+ /// \param [in] show_fullpaths
+ /// Whether to print the full source paths or just the file base name.
+ void Dump(Stream *strm, bool show_frame_index, bool show_fullpaths);
+
+ /// Print a description of this stack frame and/or the source
+ /// context/assembly for this stack frame.
+ ///
+ /// \param[in] strm
+ /// The Stream to send the output to.
+ ///
+ /// \param[in] show_frame_info
+ /// If true, print the frame info by calling DumpUsingSettingsFormat().
+ ///
+ /// \param[in] show_source
+ /// If true, print source or disassembly as per the user's settings.
+ ///
+ /// \param[in] show_unique
+ /// If true, print using backtrace unique style, without function
+ /// arguments as per the user's settings.
+ ///
+ /// \param[in] frame_marker
+ /// Passed to DumpUsingSettingsFormat() for the frame info printing.
+ ///
+ /// \return
+ /// Returns true if successful.
+ bool GetStatus(Stream &strm, bool show_frame_info, bool show_source,
+ bool show_unique = false, const char *frame_marker = nullptr);
+
+ /// Query whether this frame is a concrete frame on the call stack, or if it
+ /// is an inlined frame derived from the debug information and presented by
+ /// the debugger.
+ ///
+ /// \return
+ /// true if this is an inlined frame.
+ bool IsInlined();
+
+ /// Query whether this frame is part of a historical backtrace.
+ bool IsHistorical() const;
+
+ /// Query whether this frame is artificial (e.g a synthesized result of
+ /// inferring missing tail call frames from a backtrace). Artificial frames
+ /// may have limited support for inspecting variables.
+ bool IsArtificial() const;
+
+ /// Query this frame to find what frame it is in this Thread's
+ /// StackFrameList.
+ ///
+ /// \return
+ /// StackFrame index 0 indicates the currently-executing function. Inline
+ /// frames are included in this frame index count.
+ uint32_t GetFrameIndex() const;
+
+ /// Set this frame's synthetic frame index.
+ void SetFrameIndex(uint32_t index) { m_frame_index = index; }
+
+ /// Query this frame to find what frame it is in this Thread's
+ /// StackFrameList, not counting inlined frames.
+ ///
+ /// \return
+ /// StackFrame index 0 indicates the currently-executing function. Inline
+ /// frames are not included in this frame index count; their concrete
+ /// frame index will be the same as the concrete frame that they are
+ /// derived from.
+ uint32_t GetConcreteFrameIndex() const { return m_concrete_frame_index; }
+
+ /// Create a ValueObject for a given Variable in this StackFrame.
+ ///
+ /// \params [in] variable_sp
+ /// The Variable to base this ValueObject on
+ ///
+ /// \params [in] use_dynamic
+ /// Whether the correct dynamic type of the variable should be
+ /// determined before creating the ValueObject, or if the static type
+ /// is sufficient. One of the DynamicValueType enumerated values.
+ ///
+ /// \return
+ // A ValueObject for this variable.
+ lldb::ValueObjectSP
+ GetValueObjectForFrameVariable(const lldb::VariableSP &variable_sp,
+ lldb::DynamicValueType use_dynamic);
+
+ /// Add an arbitrary Variable object (e.g. one that specifics a global or
+ /// static) to a StackFrame's list of ValueObjects.
+ ///
+ /// \params [in] variable_sp
+ /// The Variable to base this ValueObject on
+ ///
+ /// \params [in] use_dynamic
+ /// Whether the correct dynamic type of the variable should be
+ /// determined before creating the ValueObject, or if the static type
+ /// is sufficient. One of the DynamicValueType enumerated values.
+ ///
+ /// \return
+ // A ValueObject for this variable.
+ lldb::ValueObjectSP TrackGlobalVariable(const lldb::VariableSP &variable_sp,
+ lldb::DynamicValueType use_dynamic);
+
+ /// Query this frame to determine what the default language should be when
+ /// parsing expressions given the execution context.
+ ///
+ /// \return
+ /// The language of the frame if known, else lldb::eLanguageTypeUnknown.
+ lldb::LanguageType GetLanguage();
+
+ // similar to GetLanguage(), but is allowed to take a potentially incorrect
+ // guess if exact information is not available
+ lldb::LanguageType GuessLanguage();
+
+ /// Attempt to econstruct the ValueObject for a given raw address touched by
+ /// the current instruction. The ExpressionPath should indicate how to get
+ /// to this value using "frame variable."
+ ///
+ /// \params [in] addr
+ /// The raw address.
+ ///
+ /// \return
+ /// The ValueObject if found. If valid, it has a valid ExpressionPath.
+ lldb::ValueObjectSP GuessValueForAddress(lldb::addr_t addr);
+
+ /// Attempt to reconstruct the ValueObject for the address contained in a
+ /// given register plus an offset. The ExpressionPath should indicate how
+ /// to get to this value using "frame variable."
+ ///
+ /// \params [in] reg
+ /// The name of the register.
+ ///
+ /// \params [in] offset
+ /// The offset from the register. Particularly important for sp...
+ ///
+ /// \return
+ /// The ValueObject if found. If valid, it has a valid ExpressionPath.
+ lldb::ValueObjectSP GuessValueForRegisterAndOffset(ConstString reg,
+ int64_t offset);
+
+ /// Attempt to reconstruct the ValueObject for a variable with a given \a name
+ /// from within the current StackFrame, within the current block. The search
+ /// for the variable starts in the deepest block corresponding to the current
+ /// PC in the stack frame and traverse through all parent blocks stopping at
+ /// inlined function boundaries.
+ ///
+ /// \params [in] name
+ /// The name of the variable.
+ ///
+ /// \return
+ /// The ValueObject if found.
+ lldb::ValueObjectSP FindVariable(ConstString name);
+
+ // lldb::ExecutionContextScope pure virtual functions
+ lldb::TargetSP CalculateTarget() override;
+
+ lldb::ProcessSP CalculateProcess() override;
+
+ lldb::ThreadSP CalculateThread() override;
+
+ lldb::StackFrameSP CalculateStackFrame() override;
+
+ void CalculateExecutionContext(ExecutionContext &exe_ctx) override;
+
+ lldb::RecognizedStackFrameSP GetRecognizedFrame();
+
+protected:
+ friend class StackFrameList;
+
+ void SetSymbolContextScope(SymbolContextScope *symbol_scope);
+
+ void UpdateCurrentFrameFromPreviousFrame(StackFrame &prev_frame);
+
+ void UpdatePreviousFrameFromCurrentFrame(StackFrame &curr_frame);
+
+ bool HasCachedData() const;
+
+private:
+ // For StackFrame only
+ lldb::ThreadWP m_thread_wp;
+ uint32_t m_frame_index;
+ uint32_t m_concrete_frame_index;
+ lldb::RegisterContextSP m_reg_context_sp;
+ StackID m_id;
+ Address m_frame_code_addr; // The frame code address (might not be the same as
+ // the actual PC for inlined frames) as a
+ // section/offset address
+ SymbolContext m_sc;
+ Flags m_flags;
+ Scalar m_frame_base;
+ Status m_frame_base_error;
+ bool m_cfa_is_valid; // Does this frame have a CFA? Different from CFA ==
+ // LLDB_INVALID_ADDRESS
+ Kind m_stack_frame_kind;
+ lldb::VariableListSP m_variable_list_sp;
+ ValueObjectList m_variable_list_value_objects; // Value objects for each
+ // variable in
+ // m_variable_list_sp
+ lldb::RecognizedStackFrameSP m_recognized_frame_sp;
+ StreamString m_disassembly;
+ std::recursive_mutex m_mutex;
+
+ DISALLOW_COPY_AND_ASSIGN(StackFrame);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_StackFrame_h_
diff --git a/linux-x64/clang/include/lldb/Target/StackFrameList.h b/linux-x64/clang/include/lldb/Target/StackFrameList.h
new file mode 100644
index 0000000..5eb7919
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/StackFrameList.h
@@ -0,0 +1,163 @@
+//===-- StackFrameList.h ----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_StackFrameList_h_
+#define liblldb_StackFrameList_h_
+
+#include <memory>
+#include <mutex>
+#include <vector>
+
+#include "lldb/Target/StackFrame.h"
+
+namespace lldb_private {
+
+class StackFrameList {
+public:
+ // Constructors and Destructors
+ StackFrameList(Thread &thread, const lldb::StackFrameListSP &prev_frames_sp,
+ bool show_inline_frames);
+
+ ~StackFrameList();
+
+ /// Get the number of visible frames. Frames may be created if \p can_create
+ /// is true. Synthetic (inline) frames expanded from the concrete frame #0
+ /// (aka invisible frames) are not included in this count.
+ uint32_t GetNumFrames(bool can_create = true);
+
+ /// Get the frame at index \p idx. Invisible frames cannot be indexed.
+ lldb::StackFrameSP GetFrameAtIndex(uint32_t idx);
+
+ /// Get the first concrete frame with index greater than or equal to \p idx.
+ /// Unlike \ref GetFrameAtIndex, this cannot return a synthetic frame.
+ lldb::StackFrameSP GetFrameWithConcreteFrameIndex(uint32_t unwind_idx);
+
+ /// Retrieve the stack frame with the given ID \p stack_id.
+ lldb::StackFrameSP GetFrameWithStackID(const StackID &stack_id);
+
+ /// Mark a stack frame as the currently selected frame and return its index.
+ uint32_t SetSelectedFrame(lldb_private::StackFrame *frame);
+
+ /// Get the currently selected frame index.
+ uint32_t GetSelectedFrameIndex() const;
+
+ /// Mark a stack frame as the currently selected frame using the frame index
+ /// \p idx. Like \ref GetFrameAtIndex, invisible frames cannot be selected.
+ bool SetSelectedFrameByIndex(uint32_t idx);
+
+ /// If the current inline depth (i.e the number of invisible frames) is valid,
+ /// subtract it from \p idx. Otherwise simply return \p idx.
+ uint32_t GetVisibleStackFrameIndex(uint32_t idx) {
+ if (m_current_inlined_depth < UINT32_MAX)
+ return idx - m_current_inlined_depth;
+ else
+ return idx;
+ }
+
+ /// Calculate and set the current inline depth. This may be used to update
+ /// the StackFrameList's set of inline frames when execution stops, e.g when
+ /// a breakpoint is hit.
+ void CalculateCurrentInlinedDepth();
+
+ /// If the currently selected frame comes from the currently selected thread,
+ /// point the default file and line of the thread's target to the location
+ /// specified by the frame.
+ void SetDefaultFileAndLineToSelectedFrame();
+
+ /// Clear the cache of frames.
+ void Clear();
+
+ void Dump(Stream *s);
+
+ /// If \p stack_frame_ptr is contained in this StackFrameList, return its
+ /// wrapping shared pointer.
+ lldb::StackFrameSP
+ GetStackFrameSPForStackFramePtr(StackFrame *stack_frame_ptr);
+
+ size_t GetStatus(Stream &strm, uint32_t first_frame, uint32_t num_frames,
+ bool show_frame_info, uint32_t num_frames_with_source,
+ bool show_unique = false,
+ const char *frame_marker = nullptr);
+
+protected:
+ friend class Thread;
+
+ bool SetFrameAtIndex(uint32_t idx, lldb::StackFrameSP &frame_sp);
+
+ static void Merge(std::unique_ptr<StackFrameList> &curr_up,
+ lldb::StackFrameListSP &prev_sp);
+
+ void GetFramesUpTo(uint32_t end_idx);
+
+ void GetOnlyConcreteFramesUpTo(uint32_t end_idx, Unwind *unwinder);
+
+ void SynthesizeTailCallFrames(StackFrame &next_frame);
+
+ bool GetAllFramesFetched() { return m_concrete_frames_fetched == UINT32_MAX; }
+
+ void SetAllFramesFetched() { m_concrete_frames_fetched = UINT32_MAX; }
+
+ bool DecrementCurrentInlinedDepth();
+
+ void ResetCurrentInlinedDepth();
+
+ uint32_t GetCurrentInlinedDepth();
+
+ void SetCurrentInlinedDepth(uint32_t new_depth);
+
+ typedef std::vector<lldb::StackFrameSP> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+
+ /// The thread this frame list describes.
+ Thread &m_thread;
+
+ /// The old stack frame list.
+ // TODO: The old stack frame list is used to fill in missing frame info
+ // heuristically when it's otherwise unavailable (say, because the unwinder
+ // fails). We should have stronger checks to make sure that this is a valid
+ // source of information.
+ lldb::StackFrameListSP m_prev_frames_sp;
+
+ /// A mutex for this frame list.
+ // TODO: This mutex may not always be held when required. In particular, uses
+ // of the StackFrameList APIs in lldb_private::Thread look suspect. Consider
+ // passing around a lock_guard reference to enforce proper locking.
+ mutable std::recursive_mutex m_mutex;
+
+ /// A cache of frames. This may need to be updated when the program counter
+ /// changes.
+ collection m_frames;
+
+ /// The currently selected frame.
+ uint32_t m_selected_frame_idx;
+
+ /// The number of concrete frames fetched while filling the frame list. This
+ /// is only used when synthetic frames are enabled.
+ uint32_t m_concrete_frames_fetched;
+
+ /// The number of synthetic function activations (invisible frames) expanded
+ /// from the concrete frame #0 activation.
+ // TODO: Use an optional instead of UINT32_MAX to denote invalid values.
+ uint32_t m_current_inlined_depth;
+
+ /// The program counter value at the currently selected synthetic activation.
+ /// This is only valid if m_current_inlined_depth is valid.
+ // TODO: Use an optional instead of UINT32_MAX to denote invalid values.
+ lldb::addr_t m_current_inlined_pc;
+
+ /// Whether or not to show synthetic (inline) frames. Immutable.
+ const bool m_show_inlined_frames;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(StackFrameList);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_StackFrameList_h_
diff --git a/linux-x64/clang/include/lldb/Target/StackFrameRecognizer.h b/linux-x64/clang/include/lldb/Target/StackFrameRecognizer.h
new file mode 100644
index 0000000..2021ac5
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/StackFrameRecognizer.h
@@ -0,0 +1,161 @@
+//===-- StackFrameRecognizer.h ----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_StackFrameRecognizer_h_
+#define liblldb_StackFrameRecognizer_h_
+
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Core/ValueObjectList.h"
+#include "lldb/Symbol/VariableList.h"
+#include "lldb/Utility/StructuredData.h"
+#include "lldb/lldb-private-forward.h"
+#include "lldb/lldb-public.h"
+
+namespace lldb_private {
+
+/// \class RecognizedStackFrame
+///
+/// This class provides extra information about a stack frame that was
+/// provided by a specific stack frame recognizer. Right now, this class only
+/// holds recognized arguments (via GetRecognizedArguments).
+
+class RecognizedStackFrame
+ : public std::enable_shared_from_this<RecognizedStackFrame> {
+public:
+ virtual lldb::ValueObjectListSP GetRecognizedArguments() {
+ return m_arguments;
+ }
+ virtual lldb::ValueObjectSP GetExceptionObject() {
+ return lldb::ValueObjectSP();
+ }
+ virtual ~RecognizedStackFrame(){};
+
+protected:
+ lldb::ValueObjectListSP m_arguments;
+};
+
+/// \class StackFrameRecognizer
+///
+/// A base class for frame recognizers. Subclasses (actual frame recognizers)
+/// should implement RecognizeFrame to provide a RecognizedStackFrame for a
+/// given stack frame.
+
+class StackFrameRecognizer
+ : public std::enable_shared_from_this<StackFrameRecognizer> {
+public:
+ virtual lldb::RecognizedStackFrameSP RecognizeFrame(
+ lldb::StackFrameSP frame) {
+ return lldb::RecognizedStackFrameSP();
+ };
+ virtual std::string GetName() {
+ return "";
+ }
+
+ virtual ~StackFrameRecognizer(){};
+};
+
+/// \class ScriptedStackFrameRecognizer
+///
+/// Python implementation for frame recognizers. An instance of this class
+/// tracks a particular Python classobject, which will be asked to recognize
+/// stack frames.
+
+class ScriptedStackFrameRecognizer : public StackFrameRecognizer {
+ lldb_private::ScriptInterpreter *m_interpreter;
+ lldb_private::StructuredData::ObjectSP m_python_object_sp;
+ std::string m_python_class;
+
+public:
+ ScriptedStackFrameRecognizer(lldb_private::ScriptInterpreter *interpreter,
+ const char *pclass);
+ ~ScriptedStackFrameRecognizer() override {}
+
+ std::string GetName() override {
+ return GetPythonClassName();
+ }
+
+ const char *GetPythonClassName() { return m_python_class.c_str(); }
+
+ lldb::RecognizedStackFrameSP RecognizeFrame(
+ lldb::StackFrameSP frame) override;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(ScriptedStackFrameRecognizer);
+};
+
+/// \class StackFrameRecognizerManager
+///
+/// Static class that provides a registry of known stack frame recognizers.
+/// Has static methods to add, enumerate, remove, query and invoke recognizers.
+
+class StackFrameRecognizerManager {
+public:
+ static void AddRecognizer(lldb::StackFrameRecognizerSP recognizer,
+ ConstString module,
+ ConstString symbol,
+ bool first_instruction_only = true);
+
+ static void AddRecognizer(lldb::StackFrameRecognizerSP recognizer,
+ lldb::RegularExpressionSP module,
+ lldb::RegularExpressionSP symbol,
+ bool first_instruction_only = true);
+
+ static void ForEach(
+ std::function<void(uint32_t recognizer_id, std::string recognizer_name,
+ std::string module, std::string symbol,
+ bool regexp)> const &callback);
+
+ static bool RemoveRecognizerWithID(uint32_t recognizer_id);
+
+ static void RemoveAllRecognizers();
+
+ static lldb::StackFrameRecognizerSP GetRecognizerForFrame(
+ lldb::StackFrameSP frame);
+
+ static lldb::RecognizedStackFrameSP RecognizeFrame(lldb::StackFrameSP frame);
+};
+
+/// \class ValueObjectRecognizerSynthesizedValue
+///
+/// ValueObject subclass that presents the passed ValueObject as a recognized
+/// value with the specified ValueType. Frame recognizers should return
+/// instances of this class as the returned objects in GetRecognizedArguments().
+
+class ValueObjectRecognizerSynthesizedValue : public ValueObject {
+ public:
+ static lldb::ValueObjectSP Create(ValueObject &parent, lldb::ValueType type) {
+ return (new ValueObjectRecognizerSynthesizedValue(parent, type))->GetSP();
+ }
+ ValueObjectRecognizerSynthesizedValue(ValueObject &parent,
+ lldb::ValueType type)
+ : ValueObject(parent), m_type(type) {
+ SetName(parent.GetName());
+ }
+
+ uint64_t GetByteSize() override { return m_parent->GetByteSize(); }
+ lldb::ValueType GetValueType() const override { return m_type; }
+ bool UpdateValue() override {
+ if (!m_parent->UpdateValueIfNeeded()) return false;
+ m_value = m_parent->GetValue();
+ return true;
+ }
+ size_t CalculateNumChildren(uint32_t max = UINT32_MAX) override {
+ return m_parent->GetNumChildren(max);
+ }
+ CompilerType GetCompilerTypeImpl() override {
+ return m_parent->GetCompilerType();
+ }
+ bool IsSynthetic() override { return true; }
+
+ private:
+ lldb::ValueType m_type;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_StackFrameRecognizer_h_
diff --git a/linux-x64/clang/include/lldb/Target/StackID.h b/linux-x64/clang/include/lldb/Target/StackID.h
new file mode 100644
index 0000000..a649a4f
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/StackID.h
@@ -0,0 +1,99 @@
+//===-- StackID.h -----------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_StackID_h_
+#define liblldb_StackID_h_
+
+#include "lldb/Core/AddressRange.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+class StackID {
+public:
+ // Constructors and Destructors
+ StackID()
+ : m_pc(LLDB_INVALID_ADDRESS), m_cfa(LLDB_INVALID_ADDRESS),
+ m_symbol_scope(nullptr) {}
+
+ explicit StackID(lldb::addr_t pc, lldb::addr_t cfa,
+ SymbolContextScope *symbol_scope)
+ : m_pc(pc), m_cfa(cfa), m_symbol_scope(symbol_scope) {}
+
+ StackID(const StackID &rhs)
+ : m_pc(rhs.m_pc), m_cfa(rhs.m_cfa), m_symbol_scope(rhs.m_symbol_scope) {}
+
+ ~StackID() = default;
+
+ lldb::addr_t GetPC() const { return m_pc; }
+
+ lldb::addr_t GetCallFrameAddress() const { return m_cfa; }
+
+ SymbolContextScope *GetSymbolContextScope() const { return m_symbol_scope; }
+
+ void SetSymbolContextScope(SymbolContextScope *symbol_scope) {
+ m_symbol_scope = symbol_scope;
+ }
+
+ void Clear() {
+ m_pc = LLDB_INVALID_ADDRESS;
+ m_cfa = LLDB_INVALID_ADDRESS;
+ m_symbol_scope = nullptr;
+ }
+
+ bool IsValid() const {
+ return m_pc != LLDB_INVALID_ADDRESS || m_cfa != LLDB_INVALID_ADDRESS;
+ }
+
+ void Dump(Stream *s);
+
+ // Operators
+ const StackID &operator=(const StackID &rhs) {
+ if (this != &rhs) {
+ m_pc = rhs.m_pc;
+ m_cfa = rhs.m_cfa;
+ m_symbol_scope = rhs.m_symbol_scope;
+ }
+ return *this;
+ }
+
+protected:
+ friend class StackFrame;
+
+ void SetPC(lldb::addr_t pc) { m_pc = pc; }
+
+ void SetCFA(lldb::addr_t cfa) { m_cfa = cfa; }
+
+ lldb::addr_t
+ m_pc; // The pc value for the function/symbol for this frame. This will
+ // only get used if the symbol scope is nullptr (the code where we are
+ // stopped is not represented by any function or symbol in any shared
+ // library).
+ lldb::addr_t m_cfa; // The call frame address (stack pointer) value
+ // at the beginning of the function that uniquely
+ // identifies this frame (along with m_symbol_scope
+ // below)
+ SymbolContextScope *
+ m_symbol_scope; // If nullptr, there is no block or symbol for this frame.
+ // If not nullptr, this will either be the scope for the
+ // lexical block for the frame, or the scope for the
+ // symbol. Symbol context scopes are always be unique
+ // pointers since the are part of the Block and Symbol
+ // objects and can easily be used to tell if a stack ID
+ // is the same as another.
+};
+
+bool operator==(const StackID &lhs, const StackID &rhs);
+bool operator!=(const StackID &lhs, const StackID &rhs);
+
+// frame_id_1 < frame_id_2 means "frame_id_1 is YOUNGER than frame_id_2"
+bool operator<(const StackID &lhs, const StackID &rhs);
+
+} // namespace lldb_private
+
+#endif // liblldb_StackID_h_
diff --git a/linux-x64/clang/include/lldb/Target/StopInfo.h b/linux-x64/clang/include/lldb/Target/StopInfo.h
new file mode 100644
index 0000000..59033b1
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/StopInfo.h
@@ -0,0 +1,188 @@
+//===-- StopInfo.h ----------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_StopInfo_h_
+#define liblldb_StopInfo_h_
+
+#include <string>
+
+#include "lldb/Target/Process.h"
+#include "lldb/Utility/StructuredData.h"
+#include "lldb/lldb-public.h"
+
+namespace lldb_private {
+
+class StopInfo {
+ friend class Process::ProcessEventData;
+ friend class ThreadPlanBase;
+
+public:
+ // Constructors and Destructors
+ StopInfo(Thread &thread, uint64_t value);
+
+ virtual ~StopInfo() {}
+
+ bool IsValid() const;
+
+ void SetThread(const lldb::ThreadSP &thread_sp) { m_thread_wp = thread_sp; }
+
+ lldb::ThreadSP GetThread() const { return m_thread_wp.lock(); }
+
+ // The value of the StopInfo depends on the StopReason. StopReason
+ // Meaning ----------------------------------------------
+ // eStopReasonBreakpoint BreakpointSiteID eStopReasonSignal
+ // Signal number eStopReasonWatchpoint WatchpointLocationID
+ // eStopReasonPlanComplete No significance
+
+ uint64_t GetValue() const { return m_value; }
+
+ virtual lldb::StopReason GetStopReason() const = 0;
+
+ // ShouldStopSynchronous will get called before any thread plans are
+ // consulted, and if it says we should resume the target, then we will just
+ // immediately resume. This should not run any code in or resume the target.
+
+ virtual bool ShouldStopSynchronous(Event *event_ptr) { return true; }
+
+ void OverrideShouldNotify(bool override_value) {
+ m_override_should_notify = override_value ? eLazyBoolYes : eLazyBoolNo;
+ }
+
+ // If should stop returns false, check if we should notify of this event
+ virtual bool ShouldNotify(Event *event_ptr) {
+ if (m_override_should_notify == eLazyBoolCalculate)
+ return DoShouldNotify(event_ptr);
+ else
+ return m_override_should_notify == eLazyBoolYes;
+ }
+
+ virtual void WillResume(lldb::StateType resume_state) {
+ // By default, don't do anything
+ }
+
+ virtual const char *GetDescription() { return m_description.c_str(); }
+
+ virtual void SetDescription(const char *desc_cstr) {
+ if (desc_cstr && desc_cstr[0])
+ m_description.assign(desc_cstr);
+ else
+ m_description.clear();
+ }
+
+ virtual bool IsValidForOperatingSystemThread(Thread &thread) { return true; }
+
+ // Sometimes the thread plan logic will know that it wants a given stop to
+ // stop or not, regardless of what the ordinary logic for that StopInfo would
+ // dictate. The main example of this is the ThreadPlanCallFunction, which
+ // for instance knows - based on how that particular expression was executed
+ // - whether it wants all breakpoints to auto-continue or not. Use
+ // OverrideShouldStop on the StopInfo to implement this.
+
+ void OverrideShouldStop(bool override_value) {
+ m_override_should_stop = override_value ? eLazyBoolYes : eLazyBoolNo;
+ }
+
+ bool GetOverrideShouldStop() {
+ return m_override_should_stop != eLazyBoolCalculate;
+ }
+
+ bool GetOverriddenShouldStopValue() {
+ return m_override_should_stop == eLazyBoolYes;
+ }
+
+ StructuredData::ObjectSP GetExtendedInfo() { return m_extended_info; }
+
+ static lldb::StopInfoSP
+ CreateStopReasonWithBreakpointSiteID(Thread &thread,
+ lldb::break_id_t break_id);
+
+ // This creates a StopInfo for the thread where the should_stop is already
+ // set, and won't be recalculated.
+ static lldb::StopInfoSP CreateStopReasonWithBreakpointSiteID(
+ Thread &thread, lldb::break_id_t break_id, bool should_stop);
+
+ static lldb::StopInfoSP CreateStopReasonWithWatchpointID(
+ Thread &thread, lldb::break_id_t watch_id,
+ lldb::addr_t watch_hit_addr = LLDB_INVALID_ADDRESS);
+
+ static lldb::StopInfoSP
+ CreateStopReasonWithSignal(Thread &thread, int signo,
+ const char *description = nullptr);
+
+ static lldb::StopInfoSP CreateStopReasonToTrace(Thread &thread);
+
+ static lldb::StopInfoSP
+ CreateStopReasonWithPlan(lldb::ThreadPlanSP &plan,
+ lldb::ValueObjectSP return_valobj_sp,
+ lldb::ExpressionVariableSP expression_variable_sp);
+
+ static lldb::StopInfoSP
+ CreateStopReasonWithException(Thread &thread, const char *description);
+
+ static lldb::StopInfoSP CreateStopReasonWithExec(Thread &thread);
+
+ static lldb::ValueObjectSP
+ GetReturnValueObject(lldb::StopInfoSP &stop_info_sp);
+
+ static lldb::ExpressionVariableSP
+ GetExpressionVariable(lldb::StopInfoSP &stop_info_sp);
+
+ static lldb::ValueObjectSP
+ GetCrashingDereference(lldb::StopInfoSP &stop_info_sp,
+ lldb::addr_t *crashing_address = nullptr);
+
+protected:
+ // Perform any action that is associated with this stop. This is done as the
+ // Event is removed from the event queue. ProcessEventData::DoOnRemoval does
+ // the job.
+
+ virtual void PerformAction(Event *event_ptr) {}
+
+ virtual bool DoShouldNotify(Event *event_ptr) { return false; }
+
+ // Stop the thread by default. Subclasses can override this to allow the
+ // thread to continue if desired. The ShouldStop method should not do
+ // anything that might run code. If you need to run code when deciding
+ // whether to stop at this StopInfo, that must be done in the PerformAction.
+ // The PerformAction will always get called before the ShouldStop. This is
+ // done by the ProcessEventData::DoOnRemoval, though the ThreadPlanBase needs
+ // to consult this later on.
+ virtual bool ShouldStop(Event *event_ptr) { return true; }
+
+ // Classes that inherit from StackID can see and modify these
+ lldb::ThreadWP m_thread_wp; // The thread corresponding to the stop reason.
+ uint32_t m_stop_id; // The process stop ID for which this stop info is valid
+ uint32_t m_resume_id; // This is the resume ID when we made this stop ID.
+ uint64_t m_value; // A generic value that can be used for things pertaining to
+ // this stop info
+ std::string m_description; // A textual description describing this stop.
+ LazyBool m_override_should_notify;
+ LazyBool m_override_should_stop;
+
+ StructuredData::ObjectSP
+ m_extended_info; // The extended info for this stop info
+
+ // This determines whether the target has run since this stop info. N.B.
+ // running to evaluate a user expression does not count.
+ bool HasTargetRunSinceMe();
+
+ // MakeStopInfoValid is necessary to allow saved stop infos to resurrect
+ // themselves as valid. It should only be used by
+ // Thread::RestoreThreadStateFromCheckpoint and to make sure the one-step
+ // needed for before-the-fact watchpoints does not prevent us from stopping
+ void MakeStopInfoValid();
+
+private:
+ friend class Thread;
+
+ DISALLOW_COPY_AND_ASSIGN(StopInfo);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_StopInfo_h_
diff --git a/linux-x64/clang/include/lldb/Target/StructuredDataPlugin.h b/linux-x64/clang/include/lldb/Target/StructuredDataPlugin.h
new file mode 100644
index 0000000..b20bdb3
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/StructuredDataPlugin.h
@@ -0,0 +1,169 @@
+//===-- StructuredDataPlugin.h ----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef StructuredDataPlugin_h
+#define StructuredDataPlugin_h
+
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Utility/StructuredData.h"
+
+namespace lldb_private {
+
+class CommandObjectMultiword;
+
+/// Plugin that supports process-related structured data sent asynchronously
+/// from the debug monitor (e.g. debugserver, lldb-server, etc.)
+///
+/// This plugin type is activated by a Process-derived instance when that
+/// instance detects that a given structured data feature is available.
+///
+/// StructuredDataPlugin instances are inherently tied to a process. The
+/// main functionality they support is the ability to consume asynchronously-
+/// delivered structured data from the process monitor, and do something
+/// reasonable with it. Something reasonable can include broadcasting a
+/// StructuredData event, which other parts of the system can then do with
+/// as they please. An IDE could use this facility to retrieve CPU usage,
+/// memory usage, and other run-time aspects of the process. That data
+/// can then be displayed meaningfully to the user through the IDE.
+
+/// For command-line LLDB, the Debugger instance listens for the structured
+/// data events raised by the plugin, and give the plugin both the output
+/// and error streams such that the plugin can display something about the
+/// event, at a time when the debugger ensures it is safe to write to the
+/// output or error streams.
+
+class StructuredDataPlugin
+ : public PluginInterface,
+ public std::enable_shared_from_this<StructuredDataPlugin> {
+public:
+ ~StructuredDataPlugin() override;
+
+ lldb::ProcessSP GetProcess() const;
+
+ // Public instance API
+
+ /// Return whether this plugin supports the given StructuredData feature.
+ ///
+ /// When Process is informed of a list of process-monitor-supported
+ /// structured data features, Process will go through the list of plugins,
+ /// one at a time, and have the first plugin that supports a given feature
+ /// be the plugin instantiated to handle that feature. There is a 1-1
+ /// correspondence between a Process instance and a StructuredDataPlugin
+ /// mapped to that process. A plugin can support handling multiple
+ /// features, and if that happens, there is a single plugin instance
+ /// created covering all of the mapped features for a given process.
+ ///
+ /// \param[in] type_name
+ /// The name of the feature tag supported by a process.
+ /// e.g. "darwin-log".
+ ///
+ /// \return
+ /// true if the plugin supports the feature; otherwise, false.
+ virtual bool SupportsStructuredDataType(ConstString type_name) = 0;
+
+ /// Handle the arrival of asynchronous structured data from the process.
+ ///
+ /// When asynchronous structured data arrives from the process monitor,
+ /// it is immediately delivered to the plugin mapped for that feature
+ /// if one exists. The structured data that arrives from a process
+ /// monitor must be a dictionary, and it must have a string field named
+ /// "type" that must contain the StructuredData feature name set as the
+ /// value. This is the manner in which the data is routed to the proper
+ /// plugin instance.
+ ///
+ /// \param[in] process
+ /// The process instance that just received the structured data.
+ /// This will always be the same process for a given instance of
+ /// a plugin.
+ ///
+ /// \param[in] type_name
+ /// The name of the feature tag for the asynchronous structured data.
+ /// Note this data will also be present in the \b object_sp dictionary
+ /// under the string value with key "type".
+ ///
+ /// \param[in] object_sp
+ /// A shared pointer to the structured data that arrived. This must
+ /// be a dictionary. The only key required is the aforementioned
+ /// key named "type" that must be a string value containing the
+ /// structured data type name.
+ virtual void
+ HandleArrivalOfStructuredData(Process &process, ConstString type_name,
+ const StructuredData::ObjectSP &object_sp) = 0;
+
+ /// Get a human-readable description of the contents of the data.
+ ///
+ /// In command-line LLDB, this method will be called by the Debugger
+ /// instance for each structured data event generated, and the output
+ /// will be printed to the LLDB console. If nothing is added to the stream,
+ /// nothing will be printed; otherwise, a newline will be added to the end
+ /// when displayed.
+ ///
+ /// \param[in] object_sp
+ /// A shared pointer to the structured data to format.
+ ///
+ /// \param[in] stream
+ /// The stream where the structured data should be pretty printed.
+ ///
+ /// \return
+ /// The error if formatting the object contents failed; otherwise,
+ /// success.
+ virtual Status GetDescription(const StructuredData::ObjectSP &object_sp,
+ lldb_private::Stream &stream) = 0;
+
+ /// Returns whether the plugin's features are enabled.
+ ///
+ /// This is a convenience method for plugins that can enable or disable
+ /// their functionality. It allows retrieval of this state without
+ /// requiring a cast.
+ ///
+ /// \param[in] type_name
+ /// The name of the feature tag for the asynchronous structured data.
+ /// This is needed for plugins that support more than one feature.
+ virtual bool GetEnabled(ConstString type_name) const;
+
+ /// Allow the plugin to do work related to modules that loaded in the
+ /// the corresponding process.
+ ///
+ /// This method defaults to doing nothing. Plugins can override it
+ /// if they have any behavior they want to enable/modify based on loaded
+ /// modules.
+ ///
+ /// \param[in] process
+ /// The process that just was notified of modules having been loaded.
+ /// This will always be the same process for a given instance of
+ /// a plugin.
+ ///
+ /// \param[in] module_list
+ /// The list of modules that the process registered as having just
+ /// loaded. See \b Process::ModulesDidLoad(...).
+ virtual void ModulesDidLoad(Process &process, ModuleList &module_list);
+
+protected:
+ // Derived-class API
+ StructuredDataPlugin(const lldb::ProcessWP &process_wp);
+
+ /// Derived classes must call this before attempting to hook up commands
+ /// to the 'plugin structured-data' tree.
+ ///
+ /// This ensures the relevant command and options hook points for all
+ /// StructuredDataPlugin derived classes are available for this debugger.
+ /// If this has already happened, this call is a no-op.
+ ///
+ /// \param[in] debugger
+ /// The Debugger instance for which we're creating the required shared
+ /// components for the StructuredDataPlugin derived classes.
+ static void InitializeBasePluginForDebugger(Debugger &debugger);
+
+private:
+ lldb::ProcessWP m_process_wp;
+
+ DISALLOW_COPY_AND_ASSIGN(StructuredDataPlugin);
+};
+}
+
+#endif
diff --git a/linux-x64/clang/include/lldb/Target/SystemRuntime.h b/linux-x64/clang/include/lldb/Target/SystemRuntime.h
new file mode 100644
index 0000000..b45f882
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/SystemRuntime.h
@@ -0,0 +1,308 @@
+//===-- SystemRuntime.h -----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_SystemRuntime_h_
+#define liblldb_SystemRuntime_h_
+
+#include <vector>
+
+#include "lldb/Core/ModuleList.h"
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Target/QueueItem.h"
+#include "lldb/Target/QueueList.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/StructuredData.h"
+#include "lldb/lldb-private.h"
+#include "lldb/lldb-public.h"
+
+namespace lldb_private {
+
+/// \class SystemRuntime SystemRuntime.h "lldb/Target/SystemRuntime.h"
+/// A plug-in interface definition class for system runtimes.
+///
+/// The system runtime plugins can collect information from the system
+/// libraries during a Process' lifetime and provide information about how
+/// objects/threads were originated.
+///
+/// For instance, a system runtime plugin use a breakpoint when threads are
+/// created to record the backtrace of where that thread was created. Later,
+/// when backtracing the created thread, it could extend the backtrace to show
+/// where it was originally created from.
+///
+/// The plugin will insert its own breakpoint when Created and start
+/// collecting information. Later when it comes time to augment a Thread, it
+/// can be asked to provide that information.
+///
+
+class SystemRuntime : public PluginInterface {
+public:
+ /// Find a system runtime plugin for a given process.
+ ///
+ /// Scans the installed SystemRuntime plugins 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 system runtime
+ /// plugin instance.
+ static SystemRuntime *FindPlugin(Process *process);
+
+ /// Construct with a process.
+ SystemRuntime(lldb_private::Process *process);
+
+ /// Destructor.
+ ///
+ /// The destructor is virtual since this class is designed to be inherited
+ /// by the plug-in instance.
+ ~SystemRuntime() override;
+
+ /// Called after attaching to a process.
+ ///
+ /// Allow the SystemRuntime plugin to execute some code after attaching to a
+ /// process.
+ virtual void DidAttach();
+
+ /// Called after launching a process.
+ ///
+ /// Allow the SystemRuntime plugin to execute some code after launching a
+ /// process.
+ virtual void DidLaunch();
+
+ /// Called when modules have been loaded in the process.
+ ///
+ /// Allow the SystemRuntime plugin to enable logging features in the system
+ /// runtime libraries.
+ virtual void ModulesDidLoad(lldb_private::ModuleList &module_list);
+
+ /// Called before detaching from a process.
+ ///
+ /// This will give a SystemRuntime plugin a chance to free any resources in
+ /// the inferior process before we detach.
+ virtual void Detach();
+
+ /// Return a list of thread origin extended backtraces that may be
+ /// available.
+ ///
+ /// A System Runtime may be able to provide a backtrace of when this
+ /// thread was originally created. Furthermore, it may be able to provide
+ /// that extended backtrace for different styles of creation. On a system
+ /// with both pthreads and libdispatch, aka Grand Central Dispatch, queues,
+ /// the system runtime may be able to provide the pthread creation of the
+ /// thread and it may also be able to provide the backtrace of when this GCD
+ /// queue work block was enqueued. The caller may request these different
+ /// origins by name.
+ ///
+ /// The names will be provided in the order that they are most likely to be
+ /// requested. For instance, a most natural order may be to request the GCD
+ /// libdispatch queue origin. If there is none, then request the pthread
+ /// origin.
+ ///
+ /// \return
+ /// A vector of ConstStrings with names like "pthread" or "libdispatch".
+ /// An empty vector may be returned if no thread origin extended
+ /// backtrace capabilities are available.
+ virtual const std::vector<ConstString> &GetExtendedBacktraceTypes();
+
+ /// Return a Thread which shows the origin of this thread's creation.
+ ///
+ /// This likely returns a HistoryThread which shows how thread was
+ /// originally created (e.g. "pthread" type), or how the work that is
+ /// currently executing on it was originally enqueued (e.g. "libdispatch"
+ /// type).
+ ///
+ /// There may be a chain of thread-origins; it may be informative to the end
+ /// user to query the returned ThreadSP for its origins as well.
+ ///
+ /// \param [in] thread
+ /// The thread to examine.
+ ///
+ /// \param [in] type
+ /// The type of thread origin being requested. The types supported
+ /// are returned from SystemRuntime::GetExtendedBacktraceTypes.
+ ///
+ /// \return
+ /// A ThreadSP which will have a StackList of frames. This Thread will
+ /// not appear in the Process' list of current threads. Normal thread
+ /// operations like stepping will not be available. This is a historical
+ /// view thread and may be only useful for showing a backtrace.
+ ///
+ /// An empty ThreadSP will be returned if no thread origin is available.
+ virtual lldb::ThreadSP GetExtendedBacktraceThread(lldb::ThreadSP thread,
+ ConstString type);
+
+ /// Get the extended backtrace thread for a QueueItem
+ ///
+ /// A QueueItem represents a function/block that will be executed on
+ /// a libdispatch queue in the future, or it represents a function/block
+ /// that is currently executing on a thread.
+ ///
+ /// This method will report a thread backtrace of the function that enqueued
+ /// it originally, if possible.
+ ///
+ /// \param [in] queue_item_sp
+ /// The QueueItem that we are getting an extended backtrace for.
+ ///
+ /// \param [in] type
+ /// The type of extended backtrace to fetch. The types supported
+ /// are returned from SystemRuntime::GetExtendedBacktraceTypes.
+ ///
+ /// \return
+ /// If an extended backtrace is available, it is returned. Else
+ /// an empty ThreadSP is returned.
+ virtual lldb::ThreadSP
+ GetExtendedBacktraceForQueueItem(lldb::QueueItemSP queue_item_sp,
+ ConstString type) {
+ return lldb::ThreadSP();
+ }
+
+ /// Populate the Process' QueueList with libdispatch / GCD queues that
+ /// exist.
+ ///
+ /// When process execution is paused, the SystemRuntime may be called to
+ /// fill in the list of Queues that currently exist.
+ ///
+ /// \param [out] queue_list
+ /// This QueueList will be cleared, and any queues that currently exist
+ /// will be added. An empty QueueList will be returned if no queues
+ /// exist or if this Systemruntime does not support libdispatch queues.
+ virtual void PopulateQueueList(lldb_private::QueueList &queue_list) {}
+
+ /// Get the queue name for a thread given a thread's dispatch_qaddr.
+ ///
+ /// On systems using libdispatch queues, a thread may be associated with a
+ /// queue. There will be a call to get the thread's dispatch_qaddr. At the
+ /// dispatch_qaddr we will find the address of this thread's
+ /// dispatch_queue_t structure. Given the address of the dispatch_queue_t
+ /// structure for a thread, get the queue name and return it.
+ ///
+ /// \param [in] dispatch_qaddr
+ /// The address of the dispatch_qaddr pointer for this thread.
+ ///
+ /// \return
+ /// The string of this queue's name. An empty string is returned if the
+ /// name could not be found.
+ virtual std::string
+ GetQueueNameFromThreadQAddress(lldb::addr_t dispatch_qaddr) {
+ return "";
+ }
+
+ /// Get the QueueID for the libdispatch queue given the thread's
+ /// dispatch_qaddr.
+ ///
+ /// On systems using libdispatch queues, a thread may be associated with a
+ /// queue. There will be a call to get the thread's dispatch_qaddr. At the
+ /// dispatch_qaddr we will find the address of this thread's
+ /// dispatch_queue_t structure. Given the address of the dispatch_queue_t
+ /// structure for a thread, get the queue ID and return it.
+ ///
+ /// \param [in] dispatch_qaddr
+ /// The address of the dispatch_qaddr pointer for this thread.
+ ///
+ /// \return
+ /// The queue ID, or if it could not be retrieved, LLDB_INVALID_QUEUE_ID.
+ virtual lldb::queue_id_t
+ GetQueueIDFromThreadQAddress(lldb::addr_t dispatch_qaddr) {
+ return LLDB_INVALID_QUEUE_ID;
+ }
+
+ /// Get the libdispatch_queue_t address for the queue given the thread's
+ /// dispatch_qaddr.
+ ///
+ /// On systems using libdispatch queues, a thread may be associated with a
+ /// queue. There will be a call to get the thread's dispatch_qaddr. Given
+ /// the thread's dispatch_qaddr, find the libdispatch_queue_t address and
+ /// return it.
+ ///
+ /// \param [in] dispatch_qaddr
+ /// The address of the dispatch_qaddr pointer for this thread.
+ ///
+ /// \return
+ /// The libdispatch_queue_t address, or LLDB_INVALID_ADDRESS if
+ /// unavailable/not found.
+ virtual lldb::addr_t
+ GetLibdispatchQueueAddressFromThreadQAddress(lldb::addr_t dispatch_qaddr) {
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ /// Retrieve the Queue kind for the queue at a thread's dispatch_qaddr.
+ ///
+ /// Retrieve the Queue kind - either eQueueKindSerial or
+ /// eQueueKindConcurrent, indicating that this queue processes work items
+ /// serially or concurrently.
+ ///
+ /// \return
+ /// The Queue kind, if it could be read, else eQueueKindUnknown.
+ virtual lldb::QueueKind GetQueueKind(lldb::addr_t dispatch_qaddr) {
+ return lldb::eQueueKindUnknown;
+ }
+
+ /// Get the pending work items for a libdispatch Queue
+ ///
+ /// If this system/process is using libdispatch and the runtime can do so,
+ /// retrieve the list of pending work items for the specified Queue and add
+ /// it to the Queue.
+ ///
+ /// \param [in] queue
+ /// The queue of interest.
+ virtual void PopulatePendingItemsForQueue(lldb_private::Queue *queue) {}
+
+ /// Complete the fields in a QueueItem
+ ///
+ /// PopulatePendingItemsForQueue() may not fill in all of the QueueItem
+ /// details; when the remaining fields are needed, they will be fetched by
+ /// call this method.
+ ///
+ /// \param [in] queue_item
+ /// The QueueItem that we will be completing.
+ ///
+ /// \param [in] item_ref
+ /// The item_ref token that is needed to retrieve the rest of the
+ /// information about the QueueItem.
+ virtual void CompleteQueueItem(lldb_private::QueueItem *queue_item,
+ lldb::addr_t item_ref) {}
+
+ /// Add key-value pairs to the StructuredData dictionary object with
+ /// information debugserver may need when constructing the
+ /// jThreadExtendedInfo packet.
+ ///
+ /// \param [out] dict
+ /// Dictionary to which key-value pairs should be added; they will
+ /// be sent to the remote gdb server stub as arguments in the
+ /// jThreadExtendedInfo request.
+ virtual void AddThreadExtendedInfoPacketHints(
+ lldb_private::StructuredData::ObjectSP dict) {}
+
+ /// Determine whether it is safe to run an expression on a given thread
+ ///
+ /// If a system must not run functions on a thread in some particular state,
+ /// this method gives a way for it to flag that the expression should not be
+ /// run.
+ ///
+ /// \param [in] thread_sp
+ /// The thread we want to run the expression on.
+ ///
+ /// \return
+ /// True will be returned if there are no known problems with running an
+ /// expression on this thread. False means that the inferior function
+ /// call should not be made on this thread.
+ virtual bool SafeToCallFunctionsOnThisThread(lldb::ThreadSP thread_sp) {
+ return true;
+ }
+
+protected:
+ // Member variables.
+ Process *m_process;
+
+ std::vector<ConstString> m_types;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(SystemRuntime);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_SystemRuntime_h_
diff --git a/linux-x64/clang/include/lldb/Target/Target.h b/linux-x64/clang/include/lldb/Target/Target.h
new file mode 100644
index 0000000..875a8b1
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/Target.h
@@ -0,0 +1,1359 @@
+//===-- Target.h ------------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Target_h_
+#define liblldb_Target_h_
+
+#include <list>
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "lldb/Breakpoint/BreakpointList.h"
+#include "lldb/Breakpoint/BreakpointName.h"
+#include "lldb/Breakpoint/WatchpointList.h"
+#include "lldb/Core/Architecture.h"
+#include "lldb/Core/Disassembler.h"
+#include "lldb/Core/ModuleList.h"
+#include "lldb/Core/UserSettingsController.h"
+#include "lldb/Expression/Expression.h"
+#include "lldb/Host/ProcessLaunchInfo.h"
+#include "lldb/Symbol/TypeSystem.h"
+#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Target/PathMappingList.h"
+#include "lldb/Target/SectionLoadHistory.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/Broadcaster.h"
+#include "lldb/Utility/LLDBAssert.h"
+#include "lldb/Utility/Timeout.h"
+#include "lldb/lldb-public.h"
+
+namespace lldb_private {
+
+OptionEnumValues GetDynamicValueTypes();
+
+enum InlineStrategy {
+ eInlineBreakpointsNever = 0,
+ eInlineBreakpointsHeaders,
+ eInlineBreakpointsAlways
+};
+
+enum LoadScriptFromSymFile {
+ eLoadScriptFromSymFileTrue,
+ eLoadScriptFromSymFileFalse,
+ eLoadScriptFromSymFileWarn
+};
+
+enum LoadCWDlldbinitFile {
+ eLoadCWDlldbinitTrue,
+ eLoadCWDlldbinitFalse,
+ eLoadCWDlldbinitWarn
+};
+
+enum LoadDependentFiles {
+ eLoadDependentsDefault,
+ eLoadDependentsYes,
+ eLoadDependentsNo,
+};
+
+// TargetProperties
+class TargetExperimentalProperties : public Properties {
+public:
+ TargetExperimentalProperties();
+};
+
+class TargetProperties : public Properties {
+public:
+ TargetProperties(Target *target);
+
+ ~TargetProperties() override;
+
+ ArchSpec GetDefaultArchitecture() const;
+
+ void SetDefaultArchitecture(const ArchSpec &arch);
+
+ bool GetMoveToNearestCode() const;
+
+ lldb::DynamicValueType GetPreferDynamicValue() const;
+
+ bool SetPreferDynamicValue(lldb::DynamicValueType d);
+
+ bool GetPreloadSymbols() const;
+
+ void SetPreloadSymbols(bool b);
+
+ bool GetDisableASLR() const;
+
+ void SetDisableASLR(bool b);
+
+ bool GetDetachOnError() const;
+
+ void SetDetachOnError(bool b);
+
+ bool GetDisableSTDIO() const;
+
+ void SetDisableSTDIO(bool b);
+
+ const char *GetDisassemblyFlavor() const;
+
+ InlineStrategy GetInlineStrategy() const;
+
+ llvm::StringRef GetArg0() const;
+
+ void SetArg0(llvm::StringRef arg);
+
+ bool GetRunArguments(Args &args) const;
+
+ void SetRunArguments(const Args &args);
+
+ Environment GetEnvironment() const;
+ void SetEnvironment(Environment env);
+
+ bool GetSkipPrologue() const;
+
+ PathMappingList &GetSourcePathMap() const;
+
+ FileSpecList GetExecutableSearchPaths();
+
+ void AppendExecutableSearchPaths(const FileSpec&);
+
+ FileSpecList GetDebugFileSearchPaths();
+
+ FileSpecList GetClangModuleSearchPaths();
+
+ bool GetEnableAutoImportClangModules() const;
+
+ bool GetEnableImportStdModule() const;
+
+ bool GetEnableAutoApplyFixIts() const;
+
+ bool GetEnableNotifyAboutFixIts() const;
+
+ bool GetEnableSaveObjects() const;
+
+ bool GetEnableSyntheticValue() const;
+
+ uint32_t GetMaximumNumberOfChildrenToDisplay() const;
+
+ uint32_t GetMaximumSizeOfStringSummary() const;
+
+ uint32_t GetMaximumMemReadSize() const;
+
+ FileSpec GetStandardInputPath() const;
+ FileSpec GetStandardErrorPath() const;
+ FileSpec GetStandardOutputPath() const;
+
+ void SetStandardInputPath(llvm::StringRef path);
+ void SetStandardOutputPath(llvm::StringRef path);
+ void SetStandardErrorPath(llvm::StringRef path);
+
+ void SetStandardInputPath(const char *path) = delete;
+ void SetStandardOutputPath(const char *path) = delete;
+ void SetStandardErrorPath(const char *path) = delete;
+
+ bool GetBreakpointsConsultPlatformAvoidList();
+
+ lldb::LanguageType GetLanguage() const;
+
+ llvm::StringRef GetExpressionPrefixContents();
+
+ bool GetUseHexImmediates() const;
+
+ bool GetUseFastStepping() const;
+
+ bool GetDisplayExpressionsInCrashlogs() const;
+
+ LoadScriptFromSymFile GetLoadScriptFromSymbolFile() const;
+
+ LoadCWDlldbinitFile GetLoadCWDlldbinitFile() const;
+
+ Disassembler::HexImmediateStyle GetHexImmediateStyle() const;
+
+ MemoryModuleLoadLevel GetMemoryModuleLoadLevel() const;
+
+ bool GetUserSpecifiedTrapHandlerNames(Args &args) const;
+
+ void SetUserSpecifiedTrapHandlerNames(const Args &args);
+
+ bool GetNonStopModeEnabled() const;
+
+ void SetNonStopModeEnabled(bool b);
+
+ bool GetDisplayRuntimeSupportValues() const;
+
+ void SetDisplayRuntimeSupportValues(bool b);
+
+ bool GetDisplayRecognizedArguments() const;
+
+ void SetDisplayRecognizedArguments(bool b);
+
+ const ProcessLaunchInfo &GetProcessLaunchInfo();
+
+ void SetProcessLaunchInfo(const ProcessLaunchInfo &launch_info);
+
+ bool GetInjectLocalVariables(ExecutionContext *exe_ctx) const;
+
+ void SetInjectLocalVariables(ExecutionContext *exe_ctx, bool b);
+
+ bool GetUseModernTypeLookup() const;
+
+ void SetRequireHardwareBreakpoints(bool b);
+
+ bool GetRequireHardwareBreakpoints() const;
+
+private:
+ // Callbacks for m_launch_info.
+ static void Arg0ValueChangedCallback(void *target_property_ptr,
+ OptionValue *);
+ static void RunArgsValueChangedCallback(void *target_property_ptr,
+ OptionValue *);
+ static void EnvVarsValueChangedCallback(void *target_property_ptr,
+ OptionValue *);
+ static void InheritEnvValueChangedCallback(void *target_property_ptr,
+ OptionValue *);
+ static void InputPathValueChangedCallback(void *target_property_ptr,
+ OptionValue *);
+ static void OutputPathValueChangedCallback(void *target_property_ptr,
+ OptionValue *);
+ static void ErrorPathValueChangedCallback(void *target_property_ptr,
+ OptionValue *);
+ static void DetachOnErrorValueChangedCallback(void *target_property_ptr,
+ OptionValue *);
+ static void DisableASLRValueChangedCallback(void *target_property_ptr,
+ OptionValue *);
+ static void DisableSTDIOValueChangedCallback(void *target_property_ptr,
+ OptionValue *);
+
+ // Member variables.
+ ProcessLaunchInfo m_launch_info;
+ std::unique_ptr<TargetExperimentalProperties> m_experimental_properties_up;
+};
+
+class EvaluateExpressionOptions {
+public:
+// MSVC has a bug here that reports C4268: 'const' static/global data
+// initialized with compiler generated default constructor fills the object
+// with zeros. Confirmed that MSVC is *not* zero-initializing, it's just a
+// bogus warning.
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable : 4268)
+#endif
+ static constexpr std::chrono::milliseconds default_timeout{500};
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
+ static constexpr ExecutionPolicy default_execution_policy =
+ eExecutionPolicyOnlyWhenNeeded;
+
+ EvaluateExpressionOptions() = default;
+
+ ExecutionPolicy GetExecutionPolicy() const { return m_execution_policy; }
+
+ void SetExecutionPolicy(ExecutionPolicy policy = eExecutionPolicyAlways) {
+ m_execution_policy = policy;
+ }
+
+ lldb::LanguageType GetLanguage() const { return m_language; }
+
+ void SetLanguage(lldb::LanguageType language) { m_language = language; }
+
+ bool DoesCoerceToId() const { return m_coerce_to_id; }
+
+ const char *GetPrefix() const {
+ return (m_prefix.empty() ? nullptr : m_prefix.c_str());
+ }
+
+ void SetPrefix(const char *prefix) {
+ if (prefix && prefix[0])
+ m_prefix = prefix;
+ else
+ m_prefix.clear();
+ }
+
+ void SetCoerceToId(bool coerce = true) { m_coerce_to_id = coerce; }
+
+ bool DoesUnwindOnError() const { return m_unwind_on_error; }
+
+ void SetUnwindOnError(bool unwind = false) { m_unwind_on_error = unwind; }
+
+ bool DoesIgnoreBreakpoints() const { return m_ignore_breakpoints; }
+
+ void SetIgnoreBreakpoints(bool ignore = false) {
+ m_ignore_breakpoints = ignore;
+ }
+
+ bool DoesKeepInMemory() const { return m_keep_in_memory; }
+
+ void SetKeepInMemory(bool keep = true) { m_keep_in_memory = keep; }
+
+ lldb::DynamicValueType GetUseDynamic() const { return m_use_dynamic; }
+
+ void
+ SetUseDynamic(lldb::DynamicValueType dynamic = lldb::eDynamicCanRunTarget) {
+ m_use_dynamic = dynamic;
+ }
+
+ const Timeout<std::micro> &GetTimeout() const { return m_timeout; }
+
+ void SetTimeout(const Timeout<std::micro> &timeout) { m_timeout = timeout; }
+
+ const Timeout<std::micro> &GetOneThreadTimeout() const {
+ return m_one_thread_timeout;
+ }
+
+ void SetOneThreadTimeout(const Timeout<std::micro> &timeout) {
+ m_one_thread_timeout = timeout;
+ }
+
+ bool GetTryAllThreads() const { return m_try_others; }
+
+ void SetTryAllThreads(bool try_others = true) { m_try_others = try_others; }
+
+ bool GetStopOthers() const { return m_stop_others; }
+
+ void SetStopOthers(bool stop_others = true) { m_stop_others = stop_others; }
+
+ bool GetDebug() const { return m_debug; }
+
+ void SetDebug(bool b) {
+ m_debug = b;
+ if (m_debug)
+ m_generate_debug_info = true;
+ }
+
+ bool GetGenerateDebugInfo() const { return m_generate_debug_info; }
+
+ void SetGenerateDebugInfo(bool b) { m_generate_debug_info = b; }
+
+ bool GetColorizeErrors() const { return m_ansi_color_errors; }
+
+ void SetColorizeErrors(bool b) { m_ansi_color_errors = b; }
+
+ bool GetTrapExceptions() const { return m_trap_exceptions; }
+
+ void SetTrapExceptions(bool b) { m_trap_exceptions = b; }
+
+ bool GetREPLEnabled() const { return m_repl; }
+
+ void SetREPLEnabled(bool b) { m_repl = b; }
+
+ void SetCancelCallback(lldb::ExpressionCancelCallback callback, void *baton) {
+ m_cancel_callback_baton = baton;
+ m_cancel_callback = callback;
+ }
+
+ bool InvokeCancelCallback(lldb::ExpressionEvaluationPhase phase) const {
+ return ((m_cancel_callback != nullptr)
+ ? m_cancel_callback(phase, m_cancel_callback_baton)
+ : false);
+ }
+
+ // Allows the expression contents to be remapped to point to the specified
+ // file and line using #line directives.
+ void SetPoundLine(const char *path, uint32_t line) const {
+ if (path && path[0]) {
+ m_pound_line_file = path;
+ m_pound_line_line = line;
+ } else {
+ m_pound_line_file.clear();
+ m_pound_line_line = 0;
+ }
+ }
+
+ const char *GetPoundLineFilePath() const {
+ return (m_pound_line_file.empty() ? nullptr : m_pound_line_file.c_str());
+ }
+
+ uint32_t GetPoundLineLine() const { return m_pound_line_line; }
+
+ void SetResultIsInternal(bool b) { m_result_is_internal = b; }
+
+ bool GetResultIsInternal() const { return m_result_is_internal; }
+
+ void SetAutoApplyFixIts(bool b) { m_auto_apply_fixits = b; }
+
+ bool GetAutoApplyFixIts() const { return m_auto_apply_fixits; }
+
+ bool IsForUtilityExpr() const { return m_running_utility_expression; }
+
+ void SetIsForUtilityExpr(bool b) { m_running_utility_expression = b; }
+
+private:
+ ExecutionPolicy m_execution_policy = default_execution_policy;
+ lldb::LanguageType m_language = lldb::eLanguageTypeUnknown;
+ std::string m_prefix;
+ bool m_coerce_to_id = false;
+ bool m_unwind_on_error = true;
+ bool m_ignore_breakpoints = false;
+ bool m_keep_in_memory = false;
+ bool m_try_others = true;
+ bool m_stop_others = true;
+ bool m_debug = false;
+ bool m_trap_exceptions = true;
+ bool m_repl = false;
+ bool m_generate_debug_info = false;
+ bool m_ansi_color_errors = false;
+ bool m_result_is_internal = false;
+ bool m_auto_apply_fixits = true;
+ /// True if the executed code should be treated as utility code that is only
+ /// used by LLDB internally.
+ bool m_running_utility_expression = false;
+
+ lldb::DynamicValueType m_use_dynamic = lldb::eNoDynamicValues;
+ Timeout<std::micro> m_timeout = default_timeout;
+ Timeout<std::micro> m_one_thread_timeout = llvm::None;
+ lldb::ExpressionCancelCallback m_cancel_callback = nullptr;
+ void *m_cancel_callback_baton = nullptr;
+ // If m_pound_line_file is not empty and m_pound_line_line is non-zero, use
+ // #line %u "%s" before the expression content to remap where the source
+ // originates
+ mutable std::string m_pound_line_file;
+ mutable uint32_t m_pound_line_line;
+};
+
+// Target
+class Target : public std::enable_shared_from_this<Target>,
+ public TargetProperties,
+ public Broadcaster,
+ public ExecutionContextScope,
+ public ModuleList::Notifier {
+public:
+ friend class TargetList;
+
+ /// Broadcaster event bits definitions.
+ enum {
+ eBroadcastBitBreakpointChanged = (1 << 0),
+ eBroadcastBitModulesLoaded = (1 << 1),
+ eBroadcastBitModulesUnloaded = (1 << 2),
+ eBroadcastBitWatchpointChanged = (1 << 3),
+ eBroadcastBitSymbolsLoaded = (1 << 4)
+ };
+
+ // These two functions fill out the Broadcaster interface:
+
+ static ConstString &GetStaticBroadcasterClass();
+
+ ConstString &GetBroadcasterClass() const override {
+ return GetStaticBroadcasterClass();
+ }
+
+ // This event data class is for use by the TargetList to broadcast new target
+ // notifications.
+ class TargetEventData : public EventData {
+ public:
+ TargetEventData(const lldb::TargetSP &target_sp);
+
+ TargetEventData(const lldb::TargetSP &target_sp,
+ const ModuleList &module_list);
+
+ ~TargetEventData() override;
+
+ static ConstString GetFlavorString();
+
+ ConstString GetFlavor() const override {
+ return TargetEventData::GetFlavorString();
+ }
+
+ void Dump(Stream *s) const override;
+
+ static const TargetEventData *GetEventDataFromEvent(const Event *event_ptr);
+
+ static lldb::TargetSP GetTargetFromEvent(const Event *event_ptr);
+
+ static ModuleList GetModuleListFromEvent(const Event *event_ptr);
+
+ const lldb::TargetSP &GetTarget() const { return m_target_sp; }
+
+ const ModuleList &GetModuleList() const { return m_module_list; }
+
+ private:
+ lldb::TargetSP m_target_sp;
+ ModuleList m_module_list;
+
+ DISALLOW_COPY_AND_ASSIGN(TargetEventData);
+ };
+
+ ~Target() override;
+
+ static void SettingsInitialize();
+
+ static void SettingsTerminate();
+
+ static FileSpecList GetDefaultExecutableSearchPaths();
+
+ static FileSpecList GetDefaultDebugFileSearchPaths();
+
+ static FileSpecList GetDefaultClangModuleSearchPaths();
+
+ static ArchSpec GetDefaultArchitecture();
+
+ static void SetDefaultArchitecture(const ArchSpec &arch);
+
+ /// Find a binary on the system and return its Module,
+ /// or return an existing Module that is already in the Target.
+ ///
+ /// Given a ModuleSpec, find a binary satisifying that specification,
+ /// or identify a matching Module already present in the Target,
+ /// and return a shared pointer to it.
+ ///
+ /// \param[in] module_spec
+ /// The criteria that must be matched for the binary being loaded.
+ /// e.g. UUID, architecture, file path.
+ ///
+ /// \param[in] notify
+ /// If notify is true, and the Module is new to this Target,
+ /// Target::ModulesDidLoad will be called.
+ /// If notify is false, it is assumed that the caller is adding
+ /// multiple Modules and will call ModulesDidLoad with the
+ /// full list at the end.
+ /// ModulesDidLoad must be called when a Module/Modules have
+ /// been added to the target, one way or the other.
+ ///
+ /// \param[out] error_ptr
+ /// Optional argument, pointing to a Status object to fill in
+ /// with any results / messages while attempting to find/load
+ /// this binary. Many callers will be internal functions that
+ /// will handle / summarize the failures in a custom way and
+ /// don't use these messages.
+ ///
+ /// \return
+ /// An empty ModuleSP will be returned if no matching file
+ /// was found. If error_ptr was non-nullptr, an error message
+ /// will likely be provided.
+ lldb::ModuleSP GetOrCreateModule(const ModuleSpec &module_spec,
+ bool notify,
+ Status *error_ptr = nullptr);
+
+ // Settings accessors
+
+ static const lldb::TargetPropertiesSP &GetGlobalProperties();
+
+ std::recursive_mutex &GetAPIMutex() { return m_mutex; }
+
+ void DeleteCurrentProcess();
+
+ void CleanupProcess();
+
+ /// Dump a description of this object to a Stream.
+ ///
+ /// Dump a description of the contents of this object to the
+ /// supplied stream \a s. The dumped content will be only what has
+ /// been loaded or parsed up to this point at which this function
+ /// is called, so this is a good way to see what has been parsed
+ /// in a target.
+ ///
+ /// \param[in] s
+ /// The stream to which to dump the object description.
+ void Dump(Stream *s, lldb::DescriptionLevel description_level);
+
+ // If listener_sp is null, the listener of the owning Debugger object will be
+ // used.
+ const lldb::ProcessSP &CreateProcess(lldb::ListenerSP listener_sp,
+ llvm::StringRef plugin_name,
+ const FileSpec *crash_file);
+
+ const lldb::ProcessSP &GetProcessSP() const;
+
+ bool IsValid() { return m_valid; }
+
+ void Destroy();
+
+ Status Launch(ProcessLaunchInfo &launch_info,
+ Stream *stream); // Optional stream to receive first stop info
+
+ Status Attach(ProcessAttachInfo &attach_info,
+ Stream *stream); // Optional stream to receive first stop info
+
+ // This part handles the breakpoints.
+
+ BreakpointList &GetBreakpointList(bool internal = false);
+
+ const BreakpointList &GetBreakpointList(bool internal = false) const;
+
+ lldb::BreakpointSP GetLastCreatedBreakpoint() {
+ return m_last_created_breakpoint;
+ }
+
+ lldb::BreakpointSP GetBreakpointByID(lldb::break_id_t break_id);
+
+ // Use this to create a file and line breakpoint to a given module or all
+ // module it is nullptr
+ lldb::BreakpointSP CreateBreakpoint(const FileSpecList *containingModules,
+ const FileSpec &file, uint32_t line_no,
+ uint32_t column, lldb::addr_t offset,
+ LazyBool check_inlines,
+ LazyBool skip_prologue, bool internal,
+ bool request_hardware,
+ LazyBool move_to_nearest_code);
+
+ // Use this to create breakpoint that matches regex against the source lines
+ // in files given in source_file_list: If function_names is non-empty, also
+ // filter by function after the matches are made.
+ lldb::BreakpointSP CreateSourceRegexBreakpoint(
+ const FileSpecList *containingModules,
+ const FileSpecList *source_file_list,
+ const std::unordered_set<std::string> &function_names,
+ RegularExpression &source_regex, bool internal, bool request_hardware,
+ LazyBool move_to_nearest_code);
+
+ // Use this to create a breakpoint from a load address
+ lldb::BreakpointSP CreateBreakpoint(lldb::addr_t load_addr, bool internal,
+ bool request_hardware);
+
+ // Use this to create a breakpoint from a load address and a module file spec
+ lldb::BreakpointSP CreateAddressInModuleBreakpoint(lldb::addr_t file_addr,
+ bool internal,
+ const FileSpec *file_spec,
+ bool request_hardware);
+
+ // Use this to create Address breakpoints:
+ lldb::BreakpointSP CreateBreakpoint(const Address &addr, bool internal,
+ bool request_hardware);
+
+ // Use this to create a function breakpoint by regexp in
+ // containingModule/containingSourceFiles, or all modules if it is nullptr
+ // When "skip_prologue is set to eLazyBoolCalculate, we use the current
+ // target setting, else we use the values passed in
+ lldb::BreakpointSP CreateFuncRegexBreakpoint(
+ const FileSpecList *containingModules,
+ const FileSpecList *containingSourceFiles, RegularExpression &func_regexp,
+ lldb::LanguageType requested_language, LazyBool skip_prologue,
+ bool internal, bool request_hardware);
+
+ // Use this to create a function breakpoint by name in containingModule, or
+ // all modules if it is nullptr When "skip_prologue is set to
+ // eLazyBoolCalculate, we use the current target setting, else we use the
+ // values passed in. func_name_type_mask is or'ed values from the
+ // FunctionNameType enum.
+ lldb::BreakpointSP CreateBreakpoint(
+ const FileSpecList *containingModules,
+ const FileSpecList *containingSourceFiles, const char *func_name,
+ lldb::FunctionNameType func_name_type_mask, lldb::LanguageType language,
+ lldb::addr_t offset, LazyBool skip_prologue, bool internal,
+ bool request_hardware);
+
+ lldb::BreakpointSP
+ CreateExceptionBreakpoint(enum lldb::LanguageType language, bool catch_bp,
+ bool throw_bp, bool internal,
+ Args *additional_args = nullptr,
+ Status *additional_args_error = nullptr);
+
+ lldb::BreakpointSP
+ CreateScriptedBreakpoint(const llvm::StringRef class_name,
+ const FileSpecList *containingModules,
+ const FileSpecList *containingSourceFiles,
+ bool internal,
+ bool request_hardware,
+ StructuredData::ObjectSP extra_args_sp,
+ Status *creation_error = nullptr);
+
+ // This is the same as the func_name breakpoint except that you can specify a
+ // vector of names. This is cheaper than a regular expression breakpoint in
+ // the case where you just want to set a breakpoint on a set of names you
+ // already know. func_name_type_mask is or'ed values from the
+ // FunctionNameType enum.
+ lldb::BreakpointSP CreateBreakpoint(
+ const FileSpecList *containingModules,
+ const FileSpecList *containingSourceFiles, const char *func_names[],
+ size_t num_names, lldb::FunctionNameType func_name_type_mask,
+ lldb::LanguageType language, lldb::addr_t offset, LazyBool skip_prologue,
+ bool internal, bool request_hardware);
+
+ lldb::BreakpointSP
+ CreateBreakpoint(const FileSpecList *containingModules,
+ const FileSpecList *containingSourceFiles,
+ const std::vector<std::string> &func_names,
+ lldb::FunctionNameType func_name_type_mask,
+ lldb::LanguageType language, lldb::addr_t m_offset,
+ LazyBool skip_prologue, bool internal,
+ bool request_hardware);
+
+ // Use this to create a general breakpoint:
+ lldb::BreakpointSP CreateBreakpoint(lldb::SearchFilterSP &filter_sp,
+ lldb::BreakpointResolverSP &resolver_sp,
+ bool internal, bool request_hardware,
+ bool resolve_indirect_symbols);
+
+ // Use this to create a watchpoint:
+ lldb::WatchpointSP CreateWatchpoint(lldb::addr_t addr, size_t size,
+ const CompilerType *type, uint32_t kind,
+ Status &error);
+
+ lldb::WatchpointSP GetLastCreatedWatchpoint() {
+ return m_last_created_watchpoint;
+ }
+
+ WatchpointList &GetWatchpointList() { return m_watchpoint_list; }
+
+ // Manages breakpoint names:
+ void AddNameToBreakpoint(BreakpointID &id, const char *name, Status &error);
+
+ void AddNameToBreakpoint(lldb::BreakpointSP &bp_sp, const char *name,
+ Status &error);
+
+ void RemoveNameFromBreakpoint(lldb::BreakpointSP &bp_sp,
+ ConstString name);
+
+ BreakpointName *FindBreakpointName(ConstString name, bool can_create,
+ Status &error);
+
+ void DeleteBreakpointName(ConstString name);
+
+ void ConfigureBreakpointName(BreakpointName &bp_name,
+ const BreakpointOptions &options,
+ const BreakpointName::Permissions &permissions);
+ void ApplyNameToBreakpoints(BreakpointName &bp_name);
+
+ // This takes ownership of the name obj passed in.
+ void AddBreakpointName(BreakpointName *bp_name);
+
+ void GetBreakpointNames(std::vector<std::string> &names);
+
+ //This call removes ALL breakpoints regardless of permission.
+ void RemoveAllBreakpoints(bool internal_also = false);
+
+ // This removes all the breakpoints, but obeys the ePermDelete on them.
+ void RemoveAllowedBreakpoints();
+
+ void DisableAllBreakpoints(bool internal_also = false);
+
+ void DisableAllowedBreakpoints();
+
+ void EnableAllBreakpoints(bool internal_also = false);
+
+ void EnableAllowedBreakpoints();
+
+ bool DisableBreakpointByID(lldb::break_id_t break_id);
+
+ bool EnableBreakpointByID(lldb::break_id_t break_id);
+
+ bool RemoveBreakpointByID(lldb::break_id_t break_id);
+
+ // The flag 'end_to_end', default to true, signifies that the operation is
+ // performed end to end, for both the debugger and the debuggee.
+
+ bool RemoveAllWatchpoints(bool end_to_end = true);
+
+ bool DisableAllWatchpoints(bool end_to_end = true);
+
+ bool EnableAllWatchpoints(bool end_to_end = true);
+
+ bool ClearAllWatchpointHitCounts();
+
+ bool ClearAllWatchpointHistoricValues();
+
+ bool IgnoreAllWatchpoints(uint32_t ignore_count);
+
+ bool DisableWatchpointByID(lldb::watch_id_t watch_id);
+
+ bool EnableWatchpointByID(lldb::watch_id_t watch_id);
+
+ bool RemoveWatchpointByID(lldb::watch_id_t watch_id);
+
+ bool IgnoreWatchpointByID(lldb::watch_id_t watch_id, uint32_t ignore_count);
+
+ Status SerializeBreakpointsToFile(const FileSpec &file,
+ const BreakpointIDList &bp_ids,
+ bool append);
+
+ Status CreateBreakpointsFromFile(const FileSpec &file,
+ BreakpointIDList &new_bps);
+
+ Status CreateBreakpointsFromFile(const FileSpec &file,
+ std::vector<std::string> &names,
+ BreakpointIDList &new_bps);
+
+ /// Get \a load_addr as a callable code load address for this target
+ ///
+ /// Take \a load_addr and potentially add any address bits that are
+ /// needed to make the address callable. For ARM this can set bit
+ /// zero (if it already isn't) if \a load_addr is a thumb function.
+ /// If \a addr_class is set to AddressClass::eInvalid, then the address
+ /// adjustment will always happen. If it is set to an address class
+ /// that doesn't have code in it, LLDB_INVALID_ADDRESS will be
+ /// returned.
+ lldb::addr_t GetCallableLoadAddress(
+ lldb::addr_t load_addr,
+ AddressClass addr_class = AddressClass::eInvalid) const;
+
+ /// Get \a load_addr as an opcode for this target.
+ ///
+ /// Take \a load_addr and potentially strip any address bits that are
+ /// needed to make the address point to an opcode. For ARM this can
+ /// clear bit zero (if it already isn't) if \a load_addr is a
+ /// thumb function and load_addr is in code.
+ /// If \a addr_class is set to AddressClass::eInvalid, then the address
+ /// adjustment will always happen. If it is set to an address class
+ /// that doesn't have code in it, LLDB_INVALID_ADDRESS will be
+ /// returned.
+ lldb::addr_t
+ GetOpcodeLoadAddress(lldb::addr_t load_addr,
+ AddressClass addr_class = AddressClass::eInvalid) const;
+
+ // Get load_addr as breakable load address for this target. Take a addr and
+ // check if for any reason there is a better address than this to put a
+ // breakpoint on. If there is then return that address. For MIPS, if
+ // instruction at addr is a delay slot instruction then this method will find
+ // the address of its previous instruction and return that address.
+ lldb::addr_t GetBreakableLoadAddress(lldb::addr_t addr);
+
+ void ModulesDidLoad(ModuleList &module_list);
+
+ void ModulesDidUnload(ModuleList &module_list, bool delete_locations);
+
+ void SymbolsDidLoad(ModuleList &module_list);
+
+ void ClearModules(bool delete_locations);
+
+ /// Called as the last function in Process::DidExec().
+ ///
+ /// Process::DidExec() will clear a lot of state in the process,
+ /// then try to reload a dynamic loader plugin to discover what
+ /// binaries are currently available and then this function should
+ /// be called to allow the target to do any cleanup after everything
+ /// has been figured out. It can remove breakpoints that no longer
+ /// make sense as the exec might have changed the target
+ /// architecture, and unloaded some modules that might get deleted.
+ void DidExec();
+
+ /// Gets the module for the main executable.
+ ///
+ /// Each process has a notion of a main executable that is the file
+ /// that will be executed or attached to. Executable files can have
+ /// dependent modules that are discovered from the object files, or
+ /// discovered at runtime as things are dynamically loaded.
+ ///
+ /// \return
+ /// The shared pointer to the executable module which can
+ /// contains a nullptr Module object if no executable has been
+ /// set.
+ ///
+ /// \see DynamicLoader
+ /// \see ObjectFile::GetDependentModules (FileSpecList&)
+ /// \see Process::SetExecutableModule(lldb::ModuleSP&)
+ lldb::ModuleSP GetExecutableModule();
+
+ Module *GetExecutableModulePointer();
+
+ /// Set the main executable module.
+ ///
+ /// Each process has a notion of a main executable that is the file
+ /// that will be executed or attached to. Executable files can have
+ /// dependent modules that are discovered from the object files, or
+ /// discovered at runtime as things are dynamically loaded.
+ ///
+ /// Setting the executable causes any of the current dependent
+ /// image information to be cleared and replaced with the static
+ /// dependent image information found by calling
+ /// ObjectFile::GetDependentModules (FileSpecList&) on the main
+ /// executable and any modules on which it depends. Calling
+ /// Process::GetImages() will return the newly found images that
+ /// were obtained from all of the object files.
+ ///
+ /// \param[in] module_sp
+ /// A shared pointer reference to the module that will become
+ /// the main executable for this process.
+ ///
+ /// \param[in] load_dependent_files
+ /// If \b true then ask the object files to track down any
+ /// known dependent files.
+ ///
+ /// \see ObjectFile::GetDependentModules (FileSpecList&)
+ /// \see Process::GetImages()
+ void SetExecutableModule(
+ lldb::ModuleSP &module_sp,
+ LoadDependentFiles load_dependent_files = eLoadDependentsDefault);
+
+ bool LoadScriptingResources(std::list<Status> &errors,
+ Stream *feedback_stream = nullptr,
+ bool continue_on_error = true) {
+ return m_images.LoadScriptingResourcesInTarget(
+ this, errors, feedback_stream, continue_on_error);
+ }
+
+ /// Get accessor for the images for this process.
+ ///
+ /// Each process has a notion of a main executable that is the file
+ /// that will be executed or attached to. Executable files can have
+ /// dependent modules that are discovered from the object files, or
+ /// discovered at runtime as things are dynamically loaded. After
+ /// a main executable has been set, the images will contain a list
+ /// of all the files that the executable depends upon as far as the
+ /// object files know. These images will usually contain valid file
+ /// virtual addresses only. When the process is launched or attached
+ /// to, the DynamicLoader plug-in will discover where these images
+ /// were loaded in memory and will resolve the load virtual
+ /// addresses is each image, and also in images that are loaded by
+ /// code.
+ ///
+ /// \return
+ /// A list of Module objects in a module list.
+ const ModuleList &GetImages() const { return m_images; }
+
+ ModuleList &GetImages() { return m_images; }
+
+ /// Return whether this FileSpec corresponds to a module that should be
+ /// considered for general searches.
+ ///
+ /// This API will be consulted by the SearchFilterForUnconstrainedSearches
+ /// and any module that returns \b true will not be searched. Note the
+ /// SearchFilterForUnconstrainedSearches is the search filter that
+ /// gets used in the CreateBreakpoint calls when no modules is provided.
+ ///
+ /// The target call at present just consults the Platform's call of the
+ /// same name.
+ ///
+ /// \param[in] module_sp
+ /// A shared pointer reference to the module that checked.
+ ///
+ /// \return \b true if the module should be excluded, \b false otherwise.
+ bool ModuleIsExcludedForUnconstrainedSearches(const FileSpec &module_spec);
+
+ /// Return whether this module should be considered for general searches.
+ ///
+ /// This API will be consulted by the SearchFilterForUnconstrainedSearches
+ /// and any module that returns \b true will not be searched. Note the
+ /// SearchFilterForUnconstrainedSearches is the search filter that
+ /// gets used in the CreateBreakpoint calls when no modules is provided.
+ ///
+ /// The target call at present just consults the Platform's call of the
+ /// same name.
+ ///
+ /// FIXME: When we get time we should add a way for the user to set modules
+ /// that they
+ /// don't want searched, in addition to or instead of the platform ones.
+ ///
+ /// \param[in] module_sp
+ /// A shared pointer reference to the module that checked.
+ ///
+ /// \return \b true if the module should be excluded, \b false otherwise.
+ bool
+ ModuleIsExcludedForUnconstrainedSearches(const lldb::ModuleSP &module_sp);
+
+ const ArchSpec &GetArchitecture() const { return m_arch.GetSpec(); }
+
+ /// Set the architecture for this target.
+ ///
+ /// If the current target has no Images read in, then this just sets the
+ /// architecture, which will be used to select the architecture of the
+ /// ExecutableModule when that is set. If the current target has an
+ /// ExecutableModule, then calling SetArchitecture with a different
+ /// architecture from the currently selected one will reset the
+ /// ExecutableModule to that slice of the file backing the ExecutableModule.
+ /// If the file backing the ExecutableModule does not contain a fork of this
+ /// architecture, then this code will return false, and the architecture
+ /// won't be changed. If the input arch_spec is the same as the already set
+ /// architecture, this is a no-op.
+ ///
+ /// \param[in] arch_spec
+ /// The new architecture.
+ ///
+ /// \param[in] set_platform
+ /// If \b true, then the platform will be adjusted if the currently
+ /// selected platform is not compatible with the archicture being set.
+ /// If \b false, then just the architecture will be set even if the
+ /// currently selected platform isn't compatible (in case it might be
+ /// manually set following this function call).
+ ///
+ /// \return
+ /// \b true if the architecture was successfully set, \bfalse otherwise.
+ bool SetArchitecture(const ArchSpec &arch_spec, bool set_platform = false);
+
+ bool MergeArchitecture(const ArchSpec &arch_spec);
+
+ Architecture *GetArchitecturePlugin() const { return m_arch.GetPlugin(); }
+
+ Debugger &GetDebugger() { return m_debugger; }
+
+ size_t ReadMemoryFromFileCache(const Address &addr, void *dst, size_t dst_len,
+ Status &error);
+
+ // Reading memory through the target allows us to skip going to the process
+ // for reading memory if possible and it allows us to try and read from any
+ // constant sections in our object files on disk. If you always want live
+ // program memory, read straight from the process. If you possibly want to
+ // read from const sections in object files, read from the target. This
+ // version of ReadMemory will try and read memory from the process if the
+ // process is alive. The order is:
+ // 1 - if (prefer_file_cache == true) then read from object file cache
+ // 2 - if there is a valid process, try and read from its memory
+ // 3 - if (prefer_file_cache == false) then read from object file cache
+ size_t ReadMemory(const Address &addr, bool prefer_file_cache, void *dst,
+ size_t dst_len, Status &error,
+ lldb::addr_t *load_addr_ptr = nullptr);
+
+ size_t ReadCStringFromMemory(const Address &addr, std::string &out_str,
+ Status &error);
+
+ size_t ReadCStringFromMemory(const Address &addr, char *dst,
+ size_t dst_max_len, Status &result_error);
+
+ size_t ReadScalarIntegerFromMemory(const Address &addr,
+ bool prefer_file_cache, uint32_t byte_size,
+ bool is_signed, Scalar &scalar,
+ Status &error);
+
+ uint64_t ReadUnsignedIntegerFromMemory(const Address &addr,
+ bool prefer_file_cache,
+ size_t integer_byte_size,
+ uint64_t fail_value, Status &error);
+
+ bool ReadPointerFromMemory(const Address &addr, bool prefer_file_cache,
+ Status &error, Address &pointer_addr);
+
+ SectionLoadList &GetSectionLoadList() {
+ return m_section_load_history.GetCurrentSectionLoadList();
+ }
+
+ static Target *GetTargetFromContexts(const ExecutionContext *exe_ctx_ptr,
+ const SymbolContext *sc_ptr);
+
+ // lldb::ExecutionContextScope pure virtual functions
+ lldb::TargetSP CalculateTarget() override;
+
+ lldb::ProcessSP CalculateProcess() override;
+
+ lldb::ThreadSP CalculateThread() override;
+
+ lldb::StackFrameSP CalculateStackFrame() override;
+
+ void CalculateExecutionContext(ExecutionContext &exe_ctx) override;
+
+ PathMappingList &GetImageSearchPathList();
+
+ TypeSystem *GetScratchTypeSystemForLanguage(Status *error,
+ lldb::LanguageType language,
+ bool create_on_demand = true);
+
+ PersistentExpressionState *
+ GetPersistentExpressionStateForLanguage(lldb::LanguageType language);
+
+ // Creates a UserExpression for the given language, the rest of the
+ // parameters have the same meaning as for the UserExpression constructor.
+ // Returns a new-ed object which the caller owns.
+
+ UserExpression *GetUserExpressionForLanguage(
+ llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language,
+ Expression::ResultType desired_type,
+ const EvaluateExpressionOptions &options,
+ ValueObject *ctx_obj, Status &error);
+
+ // Creates a FunctionCaller for the given language, the rest of the
+ // parameters have the same meaning as for the FunctionCaller constructor.
+ // Since a FunctionCaller can't be
+ // IR Interpreted, it makes no sense to call this with an
+ // ExecutionContextScope that lacks
+ // a Process.
+ // Returns a new-ed object which the caller owns.
+
+ FunctionCaller *GetFunctionCallerForLanguage(lldb::LanguageType language,
+ const CompilerType &return_type,
+ const Address &function_address,
+ const ValueList &arg_value_list,
+ const char *name, Status &error);
+
+ // Creates a UtilityFunction for the given language, the rest of the
+ // parameters have the same meaning as for the UtilityFunction constructor.
+ // Returns a new-ed object which the caller owns.
+
+ UtilityFunction *GetUtilityFunctionForLanguage(const char *expr,
+ lldb::LanguageType language,
+ const char *name,
+ Status &error);
+
+ ClangASTContext *GetScratchClangASTContext(bool create_on_demand = true);
+
+ lldb::ClangASTImporterSP GetClangASTImporter();
+
+ // Install any files through the platform that need be to installed prior to
+ // launching or attaching.
+ Status Install(ProcessLaunchInfo *launch_info);
+
+ bool ResolveFileAddress(lldb::addr_t load_addr, Address &so_addr);
+
+ bool ResolveLoadAddress(lldb::addr_t load_addr, Address &so_addr,
+ uint32_t stop_id = SectionLoadHistory::eStopIDNow);
+
+ bool SetSectionLoadAddress(const lldb::SectionSP §ion,
+ lldb::addr_t load_addr,
+ bool warn_multiple = false);
+
+ size_t UnloadModuleSections(const lldb::ModuleSP &module_sp);
+
+ size_t UnloadModuleSections(const ModuleList &module_list);
+
+ bool SetSectionUnloaded(const lldb::SectionSP §ion_sp);
+
+ bool SetSectionUnloaded(const lldb::SectionSP §ion_sp,
+ lldb::addr_t load_addr);
+
+ void ClearAllLoadedSections();
+
+ // Since expressions results can persist beyond the lifetime of a process,
+ // and the const expression results are available after a process is gone, we
+ // provide a way for expressions to be evaluated from the Target itself. If
+ // an expression is going to be run, then it should have a frame filled in in
+ // the execution context.
+ lldb::ExpressionResults EvaluateExpression(
+ llvm::StringRef expression, ExecutionContextScope *exe_scope,
+ lldb::ValueObjectSP &result_valobj_sp,
+ const EvaluateExpressionOptions &options = EvaluateExpressionOptions(),
+ std::string *fixed_expression = nullptr,
+ ValueObject *ctx_obj = nullptr);
+
+ lldb::ExpressionVariableSP GetPersistentVariable(ConstString name);
+
+ /// Return the next available number for numbered persistent variables.
+ unsigned GetNextPersistentVariableIndex() {
+ return m_next_persistent_variable_index++;
+ }
+
+ lldb::addr_t GetPersistentSymbol(ConstString name);
+
+ // Target Stop Hooks
+ class StopHook : public UserID {
+ public:
+ StopHook(const StopHook &rhs);
+
+ ~StopHook();
+
+ StringList *GetCommandPointer() { return &m_commands; }
+
+ const StringList &GetCommands() { return m_commands; }
+
+ lldb::TargetSP &GetTarget() { return m_target_sp; }
+
+ void SetCommands(StringList &in_commands) { m_commands = in_commands; }
+
+ // Set the specifier. The stop hook will own the specifier, and is
+ // responsible for deleting it when we're done.
+ void SetSpecifier(SymbolContextSpecifier *specifier);
+
+ SymbolContextSpecifier *GetSpecifier() { return m_specifier_sp.get(); }
+
+ // Set the Thread Specifier. The stop hook will own the thread specifier,
+ // and is responsible for deleting it when we're done.
+ void SetThreadSpecifier(ThreadSpec *specifier);
+
+ ThreadSpec *GetThreadSpecifier() { return m_thread_spec_up.get(); }
+
+ bool IsActive() { return m_active; }
+
+ void SetIsActive(bool is_active) { m_active = is_active; }
+
+ void SetAutoContinue(bool auto_continue) {m_auto_continue = auto_continue;}
+
+ bool GetAutoContinue() const { return m_auto_continue; }
+
+ void GetDescription(Stream *s, lldb::DescriptionLevel level) const;
+
+ private:
+ lldb::TargetSP m_target_sp;
+ StringList m_commands;
+ lldb::SymbolContextSpecifierSP m_specifier_sp;
+ std::unique_ptr<ThreadSpec> m_thread_spec_up;
+ bool m_active = true;
+ bool m_auto_continue = false;
+
+ // Use CreateStopHook to make a new empty stop hook. The GetCommandPointer
+ // and fill it with commands, and SetSpecifier to set the specifier shared
+ // pointer (can be null, that will match anything.)
+ StopHook(lldb::TargetSP target_sp, lldb::user_id_t uid);
+ friend class Target;
+ };
+ typedef std::shared_ptr<StopHook> StopHookSP;
+
+ // Add an empty stop hook to the Target's stop hook list, and returns a
+ // shared pointer to it in new_hook. Returns the id of the new hook.
+ StopHookSP CreateStopHook();
+
+ void RunStopHooks();
+
+ size_t GetStopHookSize();
+
+ bool SetSuppresStopHooks(bool suppress) {
+ bool old_value = m_suppress_stop_hooks;
+ m_suppress_stop_hooks = suppress;
+ return old_value;
+ }
+
+ bool GetSuppressStopHooks() { return m_suppress_stop_hooks; }
+
+ bool RemoveStopHookByID(lldb::user_id_t uid);
+
+ void RemoveAllStopHooks();
+
+ StopHookSP GetStopHookByID(lldb::user_id_t uid);
+
+ bool SetStopHookActiveStateByID(lldb::user_id_t uid, bool active_state);
+
+ void SetAllStopHooksActiveState(bool active_state);
+
+ size_t GetNumStopHooks() const { return m_stop_hooks.size(); }
+
+ StopHookSP GetStopHookAtIndex(size_t index) {
+ if (index >= GetNumStopHooks())
+ return StopHookSP();
+ StopHookCollection::iterator pos = m_stop_hooks.begin();
+
+ while (index > 0) {
+ pos++;
+ index--;
+ }
+ return (*pos).second;
+ }
+
+ lldb::PlatformSP GetPlatform() { return m_platform_sp; }
+
+ void SetPlatform(const lldb::PlatformSP &platform_sp) {
+ m_platform_sp = platform_sp;
+ }
+
+ SourceManager &GetSourceManager();
+
+ ClangModulesDeclVendor *GetClangModulesDeclVendor();
+
+ // Methods.
+ lldb::SearchFilterSP
+ GetSearchFilterForModule(const FileSpec *containingModule);
+
+ lldb::SearchFilterSP
+ GetSearchFilterForModuleList(const FileSpecList *containingModuleList);
+
+ lldb::SearchFilterSP
+ GetSearchFilterForModuleAndCUList(const FileSpecList *containingModules,
+ const FileSpecList *containingSourceFiles);
+
+ lldb::REPLSP GetREPL(Status &err, lldb::LanguageType language,
+ const char *repl_options, bool can_create);
+
+ void SetREPL(lldb::LanguageType language, lldb::REPLSP repl_sp);
+
+protected:
+ /// Implementing of ModuleList::Notifier.
+
+ void NotifyModuleAdded(const ModuleList &module_list,
+ const lldb::ModuleSP &module_sp) override;
+
+ void NotifyModuleRemoved(const ModuleList &module_list,
+ const lldb::ModuleSP &module_sp) override;
+
+ void NotifyModuleUpdated(const ModuleList &module_list,
+ const lldb::ModuleSP &old_module_sp,
+ const lldb::ModuleSP &new_module_sp) override;
+
+ void NotifyWillClearList(const ModuleList &module_list) override;
+
+ void NotifyModulesRemoved(lldb_private::ModuleList &module_list) override;
+
+ class Arch {
+ public:
+ explicit Arch(const ArchSpec &spec);
+ const Arch &operator=(const ArchSpec &spec);
+
+ const ArchSpec &GetSpec() const { return m_spec; }
+ Architecture *GetPlugin() const { return m_plugin_up.get(); }
+
+ private:
+ ArchSpec m_spec;
+ std::unique_ptr<Architecture> m_plugin_up;
+ };
+ // Member variables.
+ Debugger &m_debugger;
+ lldb::PlatformSP m_platform_sp; ///< The platform for this target.
+ std::recursive_mutex m_mutex; ///< An API mutex that is used by the lldb::SB*
+ /// classes make the SB interface thread safe
+ Arch m_arch;
+ ModuleList m_images; ///< The list of images for this process (shared
+ /// libraries and anything dynamically loaded).
+ SectionLoadHistory m_section_load_history;
+ BreakpointList m_breakpoint_list;
+ BreakpointList m_internal_breakpoint_list;
+ using BreakpointNameList = std::map<ConstString, BreakpointName *>;
+ BreakpointNameList m_breakpoint_names;
+
+ lldb::BreakpointSP m_last_created_breakpoint;
+ WatchpointList m_watchpoint_list;
+ lldb::WatchpointSP m_last_created_watchpoint;
+ // We want to tightly control the process destruction process so we can
+ // correctly tear down everything that we need to, so the only class that
+ // knows about the process lifespan is this target class.
+ lldb::ProcessSP m_process_sp;
+ lldb::SearchFilterSP m_search_filter_sp;
+ PathMappingList m_image_search_paths;
+ TypeSystemMap m_scratch_type_system_map;
+
+ typedef std::map<lldb::LanguageType, lldb::REPLSP> REPLMap;
+ REPLMap m_repl_map;
+
+ lldb::ClangASTImporterSP m_ast_importer_sp;
+ lldb::ClangModulesDeclVendorUP m_clang_modules_decl_vendor_up;
+
+ lldb::SourceManagerUP m_source_manager_up;
+
+ typedef std::map<lldb::user_id_t, StopHookSP> StopHookCollection;
+ StopHookCollection m_stop_hooks;
+ lldb::user_id_t m_stop_hook_next_id;
+ bool m_valid;
+ bool m_suppress_stop_hooks;
+ bool m_is_dummy_target;
+ unsigned m_next_persistent_variable_index = 0;
+
+ static void ImageSearchPathsChanged(const PathMappingList &path_list,
+ void *baton);
+
+ // Utilities for `statistics` command.
+private:
+ std::vector<uint32_t> m_stats_storage;
+ bool m_collecting_stats = false;
+
+public:
+ void SetCollectingStats(bool v) { m_collecting_stats = v; }
+
+ bool GetCollectingStats() { return m_collecting_stats; }
+
+ void IncrementStats(lldb_private::StatisticKind key) {
+ if (!GetCollectingStats())
+ return;
+ lldbassert(key < lldb_private::StatisticKind::StatisticMax &&
+ "invalid statistics!");
+ m_stats_storage[key] += 1;
+ }
+
+ std::vector<uint32_t> GetStatistics() { return m_stats_storage; }
+
+private:
+ /// Construct with optional file and arch.
+ ///
+ /// This member is private. Clients must use
+ /// TargetList::CreateTarget(const FileSpec*, const ArchSpec*)
+ /// so all targets can be tracked from the central target list.
+ ///
+ /// \see TargetList::CreateTarget(const FileSpec*, const ArchSpec*)
+ Target(Debugger &debugger, const ArchSpec &target_arch,
+ const lldb::PlatformSP &platform_sp, bool is_dummy_target);
+
+ // Helper function.
+ bool ProcessIsValid();
+
+ // Copy breakpoints, stop hooks and so forth from the dummy target:
+ void PrimeFromDummyTarget(Target *dummy_target);
+
+ void AddBreakpoint(lldb::BreakpointSP breakpoint_sp, bool internal);
+
+ void FinalizeFileActions(ProcessLaunchInfo &info);
+
+ DISALLOW_COPY_AND_ASSIGN(Target);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Target_h_
diff --git a/linux-x64/clang/include/lldb/Target/TargetList.h b/linux-x64/clang/include/lldb/Target/TargetList.h
new file mode 100644
index 0000000..ece0705
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/TargetList.h
@@ -0,0 +1,214 @@
+//===-- TargetList.h --------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_TargetList_h_
+#define liblldb_TargetList_h_
+
+#include <mutex>
+#include <vector>
+
+#include "lldb/Target/Target.h"
+#include "lldb/Utility/Broadcaster.h"
+
+namespace lldb_private {
+
+class TargetList : public Broadcaster {
+private:
+ friend class Debugger;
+
+ /// Constructor
+ ///
+ /// The constructor for the target list is private. Clients can
+ /// get ahold of of the one and only target list through the
+ /// lldb_private::Debugger::GetSharedInstance().GetTargetList().
+ ///
+ /// \see static TargetList& lldb_private::Debugger::GetTargetList().
+ TargetList(Debugger &debugger);
+
+public:
+ /// Broadcaster event bits definitions.
+ enum { eBroadcastBitInterrupt = (1 << 0) };
+
+ // These two functions fill out the Broadcaster interface:
+
+ static ConstString &GetStaticBroadcasterClass();
+
+ ConstString &GetBroadcasterClass() const override {
+ return GetStaticBroadcasterClass();
+ }
+
+ ~TargetList() override;
+
+ /// Create a new Target.
+ ///
+ /// Clients must use this function to create a Target. This allows
+ /// a global list of targets to be maintained in a central location
+ /// so signal handlers and other global functions can use it to
+ /// locate an appropriate target to deliver asynchronous information
+ /// to.
+ ///
+ /// \param[in] debugger
+ /// The debugger to associate this target with
+ ///
+ /// \param[in] file_spec
+ /// The main executable file for a debug target. This value
+ /// can be nullptr and the file can be set later using:
+ /// Target::SetExecutableModule (ModuleSP&)
+ ///
+ /// \param[in] triple_cstr
+ /// A target triple string to be used for the target. This can
+ /// be nullptr if the triple is not known or when attaching to a
+ /// process.
+ ///
+ /// \param[in] get_dependent_modules
+ /// Track down the dependent modules for an executable and
+ /// load those into the module list.
+ ///
+ /// \param[in] platform_options
+ /// A pointer to the platform options to use when creating this
+ /// target. If this value is nullptr, then the currently selected
+ /// platform will be used.
+ ///
+ /// \param[out] target_sp
+ /// A shared pointer to a target that will be filled in if
+ /// this call is successful.
+ ///
+ /// \return
+ /// An error object that indicates success or failure
+ Status CreateTarget(Debugger &debugger, llvm::StringRef user_exe_path,
+ llvm::StringRef triple_str,
+ LoadDependentFiles get_dependent_modules,
+ const OptionGroupPlatform *platform_options,
+ lldb::TargetSP &target_sp);
+
+ /// Create a new Target.
+ ///
+ /// Same as the function above, but used when you already know the
+ /// platform you will be using
+ Status CreateTarget(Debugger &debugger, llvm::StringRef user_exe_path,
+ const ArchSpec &arch,
+ LoadDependentFiles get_dependent_modules,
+ lldb::PlatformSP &platform_sp, lldb::TargetSP &target_sp);
+
+ /// Delete a Target object from the list.
+ ///
+ /// When clients are done with the Target objects, this function
+ /// should be called to release the memory associated with a target
+ /// object.
+ ///
+ /// \param[in] target_sp
+ /// The shared pointer to a target.
+ ///
+ /// \return
+ /// Returns \b true if the target was successfully removed from
+ /// from this target list, \b false otherwise. The client will
+ /// be left with the last remaining shared pointer to the target
+ /// in \a target_sp which can then be properly released.
+ bool DeleteTarget(lldb::TargetSP &target_sp);
+
+ int GetNumTargets() const;
+
+ lldb::TargetSP GetTargetAtIndex(uint32_t index) const;
+
+ uint32_t GetIndexOfTarget(lldb::TargetSP target_sp) const;
+
+ /// Find the target that contains has an executable whose path
+ /// matches \a exe_file_spec, and whose architecture matches
+ /// \a arch_ptr if arch_ptr is not nullptr.
+ ///
+ /// \param[in] exe_file_spec
+ /// A file spec containing a basename, or a full path (directory
+ /// and basename). If \a exe_file_spec contains only a filename
+ /// (empty GetDirectory() value) then matching will be done
+ /// solely based on the filenames and directories won't be
+ /// compared. If \a exe_file_spec contains a filename and a
+ /// directory, then both must match.
+ ///
+ /// \param[in] exe_arch_ptr
+ /// If not nullptr then the architecture also needs to match, else
+ /// the architectures will be compared.
+ ///
+ /// \return
+ /// A shared pointer to a target object. The returned shared
+ /// pointer will contain nullptr if no target objects have a
+ /// executable whose full or partial path matches
+ /// with a matching process ID.
+ lldb::TargetSP FindTargetWithExecutableAndArchitecture(
+ const FileSpec &exe_file_spec,
+ const ArchSpec *exe_arch_ptr = nullptr) const;
+
+ /// Find the target that contains a process with process ID \a
+ /// pid.
+ ///
+ /// \param[in] pid
+ /// The process ID to search our target list for.
+ ///
+ /// \return
+ /// A shared pointer to a target object. The returned shared
+ /// pointer will contain nullptr if no target objects own a process
+ /// with a matching process ID.
+ lldb::TargetSP FindTargetWithProcessID(lldb::pid_t pid) const;
+
+ lldb::TargetSP FindTargetWithProcess(lldb_private::Process *process) const;
+
+ lldb::TargetSP GetTargetSP(Target *target) const;
+
+ /// Send an async interrupt to one or all processes.
+ ///
+ /// Find the target that contains the process with process ID \a
+ /// pid and send a LLDB_EVENT_ASYNC_INTERRUPT event to the process's
+ /// event queue.
+ ///
+ /// \param[in] pid
+ /// The process ID to search our target list for, if \a pid is
+ /// LLDB_INVALID_PROCESS_ID, then the interrupt will be sent to
+ /// all processes.
+ ///
+ /// \return
+ /// The number of async interrupts sent.
+ uint32_t SendAsyncInterrupt(lldb::pid_t pid = LLDB_INVALID_PROCESS_ID);
+
+ uint32_t SignalIfRunning(lldb::pid_t pid, int signo);
+
+ uint32_t SetSelectedTarget(Target *target);
+
+ lldb::TargetSP GetSelectedTarget();
+
+protected:
+ typedef std::vector<lldb::TargetSP> collection;
+ // Member variables.
+ collection m_target_list;
+ lldb::TargetSP m_dummy_target_sp;
+ mutable std::recursive_mutex m_target_list_mutex;
+ uint32_t m_selected_target_idx;
+
+private:
+ lldb::TargetSP GetDummyTarget(lldb_private::Debugger &debugger);
+
+ Status CreateDummyTarget(Debugger &debugger,
+ llvm::StringRef specified_arch_name,
+ lldb::TargetSP &target_sp);
+
+ Status CreateTargetInternal(Debugger &debugger, llvm::StringRef user_exe_path,
+ llvm::StringRef triple_str,
+ LoadDependentFiles load_dependent_files,
+ const OptionGroupPlatform *platform_options,
+ lldb::TargetSP &target_sp, bool is_dummy_target);
+
+ Status CreateTargetInternal(Debugger &debugger, llvm::StringRef user_exe_path,
+ const ArchSpec &arch,
+ LoadDependentFiles get_dependent_modules,
+ lldb::PlatformSP &platform_sp,
+ lldb::TargetSP &target_sp, bool is_dummy_target);
+
+ DISALLOW_COPY_AND_ASSIGN(TargetList);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_TargetList_h_
diff --git a/linux-x64/clang/include/lldb/Target/Thread.h b/linux-x64/clang/include/lldb/Target/Thread.h
new file mode 100644
index 0000000..7aeaece
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/Thread.h
@@ -0,0 +1,1268 @@
+//===-- Thread.h ------------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Thread_h_
+#define liblldb_Thread_h_
+
+#include <memory>
+#include <mutex>
+#include <string>
+#include <vector>
+
+#include "lldb/Core/UserSettingsController.h"
+#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Target/RegisterCheckpoint.h"
+#include "lldb/Target/StackFrameList.h"
+#include "lldb/Utility/Broadcaster.h"
+#include "lldb/Utility/Event.h"
+#include "lldb/Utility/StructuredData.h"
+#include "lldb/Utility/UserID.h"
+#include "lldb/lldb-private.h"
+
+#define LLDB_THREAD_MAX_STOP_EXC_DATA 8
+
+namespace lldb_private {
+
+class ThreadProperties : public Properties {
+public:
+ ThreadProperties(bool is_global);
+
+ ~ThreadProperties() override;
+
+ /// The regular expression returned determines symbols that this
+ /// thread won't stop in during "step-in" operations.
+ ///
+ /// \return
+ /// A pointer to a regular expression to compare against symbols,
+ /// or nullptr if all symbols are allowed.
+ ///
+ const RegularExpression *GetSymbolsToAvoidRegexp();
+
+ FileSpecList GetLibrariesToAvoid() const;
+
+ bool GetTraceEnabledState() const;
+
+ bool GetStepInAvoidsNoDebug() const;
+
+ bool GetStepOutAvoidsNoDebug() const;
+
+ uint64_t GetMaxBacktraceDepth() const;
+};
+
+typedef std::shared_ptr<ThreadProperties> ThreadPropertiesSP;
+
+class Thread : public std::enable_shared_from_this<Thread>,
+ public ThreadProperties,
+ public UserID,
+ public ExecutionContextScope,
+ public Broadcaster {
+public:
+ /// Broadcaster event bits definitions.
+ enum {
+ eBroadcastBitStackChanged = (1 << 0),
+ eBroadcastBitThreadSuspended = (1 << 1),
+ eBroadcastBitThreadResumed = (1 << 2),
+ eBroadcastBitSelectedFrameChanged = (1 << 3),
+ eBroadcastBitThreadSelected = (1 << 4)
+ };
+
+ static ConstString &GetStaticBroadcasterClass();
+
+ ConstString &GetBroadcasterClass() const override {
+ return GetStaticBroadcasterClass();
+ }
+
+ class ThreadEventData : public EventData {
+ public:
+ ThreadEventData(const lldb::ThreadSP thread_sp);
+
+ ThreadEventData(const lldb::ThreadSP thread_sp, const StackID &stack_id);
+
+ ThreadEventData();
+
+ ~ThreadEventData() override;
+
+ static ConstString GetFlavorString();
+
+ ConstString GetFlavor() const override {
+ return ThreadEventData::GetFlavorString();
+ }
+
+ void Dump(Stream *s) const override;
+
+ static const ThreadEventData *GetEventDataFromEvent(const Event *event_ptr);
+
+ static lldb::ThreadSP GetThreadFromEvent(const Event *event_ptr);
+
+ static StackID GetStackIDFromEvent(const Event *event_ptr);
+
+ static lldb::StackFrameSP GetStackFrameFromEvent(const Event *event_ptr);
+
+ lldb::ThreadSP GetThread() const { return m_thread_sp; }
+
+ StackID GetStackID() const { return m_stack_id; }
+
+ private:
+ lldb::ThreadSP m_thread_sp;
+ StackID m_stack_id;
+
+ DISALLOW_COPY_AND_ASSIGN(ThreadEventData);
+ };
+
+ struct ThreadStateCheckpoint {
+ uint32_t orig_stop_id; // Dunno if I need this yet but it is an interesting
+ // bit of data.
+ lldb::StopInfoSP stop_info_sp; // You have to restore the stop info or you
+ // might continue with the wrong signals.
+ std::vector<lldb::ThreadPlanSP> m_completed_plan_stack;
+ lldb::RegisterCheckpointSP
+ register_backup_sp; // You need to restore the registers, of course...
+ uint32_t current_inlined_depth;
+ lldb::addr_t current_inlined_pc;
+ };
+
+ /// Constructor
+ ///
+ /// \param [in] process
+ ///
+ /// \param [in] tid
+ ///
+ /// \param [in] use_invalid_index_id
+ /// Optional parameter, defaults to false. The only subclass that
+ /// is likely to set use_invalid_index_id == true is the HistoryThread
+ /// class. In that case, the Thread we are constructing represents
+ /// a thread from earlier in the program execution. We may have the
+ /// tid of the original thread that they represent but we don't want
+ /// to reuse the IndexID of that thread, or create a new one. If a
+ /// client wants to know the original thread's IndexID, they should use
+ /// Thread::GetExtendedBacktraceOriginatingIndexID().
+ Thread(Process &process, lldb::tid_t tid, bool use_invalid_index_id = false);
+
+ ~Thread() override;
+
+ static void SettingsInitialize();
+
+ static void SettingsTerminate();
+
+ static const ThreadPropertiesSP &GetGlobalProperties();
+
+ lldb::ProcessSP GetProcess() const { return m_process_wp.lock(); }
+
+ int GetResumeSignal() const { return m_resume_signal; }
+
+ void SetResumeSignal(int signal) { m_resume_signal = signal; }
+
+ lldb::StateType GetState() const;
+
+ void SetState(lldb::StateType state);
+
+ /// Sets the USER resume state for this thread. If you set a thread to
+ /// suspended with
+ /// this API, it won't take part in any of the arbitration for ShouldResume,
+ /// and will stay
+ /// suspended even when other threads do get to run.
+ ///
+ /// N.B. This is not the state that is used internally by thread plans to
+ /// implement
+ /// staying on one thread while stepping over a breakpoint, etc. The is the
+ /// TemporaryResume state, and if you are implementing some bit of strategy in
+ /// the stepping
+ /// machinery you should be using that state and not the user resume state.
+ ///
+ /// If you are just preparing all threads to run, you should not override the
+ /// threads that are
+ /// marked as suspended by the debugger. In that case, pass override_suspend
+ /// = false. If you want
+ /// to force the thread to run (e.g. the "thread continue" command, or are
+ /// resetting the state
+ /// (e.g. in SBThread::Resume()), then pass true to override_suspend.
+ /// \return
+ /// The User resume state for this thread.
+ void SetResumeState(lldb::StateType state, bool override_suspend = false) {
+ if (m_resume_state == lldb::eStateSuspended && !override_suspend)
+ return;
+ m_resume_state = state;
+ }
+
+ /// Gets the USER resume state for this thread. This is not the same as what
+ /// this thread is going to do for any particular step, however if this thread
+ /// returns eStateSuspended, then the process control logic will never allow
+ /// this
+ /// thread to run.
+ ///
+ /// \return
+ /// The User resume state for this thread.
+ lldb::StateType GetResumeState() const { return m_resume_state; }
+
+ // This function is called on all the threads before "ShouldResume" and
+ // "WillResume" in case a thread needs to change its state before the
+ // ThreadList polls all the threads to figure out which ones actually will
+ // get to run and how.
+ void SetupForResume();
+
+ // Do not override this function, it is for thread plan logic only
+ bool ShouldResume(lldb::StateType resume_state);
+
+ // Override this to do platform specific tasks before resume.
+ virtual void WillResume(lldb::StateType resume_state) {}
+
+ // This clears generic thread state after a resume. If you subclass this, be
+ // sure to call it.
+ virtual void DidResume();
+
+ // This notifies the thread when a private stop occurs.
+ virtual void DidStop();
+
+ virtual void RefreshStateAfterStop() = 0;
+
+ void WillStop();
+
+ bool ShouldStop(Event *event_ptr);
+
+ Vote ShouldReportStop(Event *event_ptr);
+
+ Vote ShouldReportRun(Event *event_ptr);
+
+ void Flush();
+
+ // Return whether this thread matches the specification in ThreadSpec. This
+ // is a virtual method because at some point we may extend the thread spec
+ // with a platform specific dictionary of attributes, which then only the
+ // platform specific Thread implementation would know how to match. For now,
+ // this just calls through to the ThreadSpec's ThreadPassesBasicTests method.
+ virtual bool MatchesSpec(const ThreadSpec *spec);
+
+ lldb::StopInfoSP GetStopInfo();
+
+ lldb::StopReason GetStopReason();
+
+ bool StopInfoIsUpToDate() const;
+
+ // This sets the stop reason to a "blank" stop reason, so you can call
+ // functions on the thread without having the called function run with
+ // whatever stop reason you stopped with.
+ void SetStopInfoToNothing();
+
+ bool ThreadStoppedForAReason();
+
+ static const char *RunModeAsCString(lldb::RunMode mode);
+
+ static const char *StopReasonAsCString(lldb::StopReason reason);
+
+ virtual const char *GetInfo() { return nullptr; }
+
+ /// Retrieve a dictionary of information about this thread
+ ///
+ /// On Mac OS X systems there may be voucher information.
+ /// The top level dictionary returned will have an "activity" key and the
+ /// value of the activity is a dictionary. Keys in that dictionary will
+ /// be "name" and "id", among others.
+ /// There may also be "trace_messages" (an array) with each entry in that
+ /// array
+ /// being a dictionary (keys include "message" with the text of the trace
+ /// message).
+ StructuredData::ObjectSP GetExtendedInfo() {
+ if (!m_extended_info_fetched) {
+ m_extended_info = FetchThreadExtendedInfo();
+ m_extended_info_fetched = true;
+ }
+ return m_extended_info;
+ }
+
+ virtual const char *GetName() { return nullptr; }
+
+ virtual void SetName(const char *name) {}
+
+ /// Whether this thread can be associated with a libdispatch queue
+ ///
+ /// The Thread may know if it is associated with a libdispatch queue,
+ /// it may know definitively that it is NOT associated with a libdispatch
+ /// queue, or it may be unknown whether it is associated with a libdispatch
+ /// queue.
+ ///
+ /// \return
+ /// eLazyBoolNo if this thread is definitely not associated with a
+ /// libdispatch queue (e.g. on a non-Darwin system where GCD aka
+ /// libdispatch is not available).
+ ///
+ /// eLazyBoolYes this thread is associated with a libdispatch queue.
+ ///
+ /// eLazyBoolCalculate this thread may be associated with a libdispatch
+ /// queue but the thread doesn't know one way or the other.
+ virtual lldb_private::LazyBool GetAssociatedWithLibdispatchQueue() {
+ return eLazyBoolNo;
+ }
+
+ virtual void SetAssociatedWithLibdispatchQueue(
+ lldb_private::LazyBool associated_with_libdispatch_queue) {}
+
+ /// Retrieve the Queue ID for the queue currently using this Thread
+ ///
+ /// If this Thread is doing work on behalf of a libdispatch/GCD queue,
+ /// retrieve the QueueID.
+ ///
+ /// This is a unique identifier for the libdispatch/GCD queue in a
+ /// process. Often starting at 1 for the initial system-created
+ /// queues and incrementing, a QueueID will not be reused for a
+ /// different queue during the lifetime of a process.
+ ///
+ /// \return
+ /// A QueueID if the Thread subclass implements this, else
+ /// LLDB_INVALID_QUEUE_ID.
+ virtual lldb::queue_id_t GetQueueID() { return LLDB_INVALID_QUEUE_ID; }
+
+ virtual void SetQueueID(lldb::queue_id_t new_val) {}
+
+ /// Retrieve the Queue name for the queue currently using this Thread
+ ///
+ /// If this Thread is doing work on behalf of a libdispatch/GCD queue,
+ /// retrieve the Queue name.
+ ///
+ /// \return
+ /// The Queue name, if the Thread subclass implements this, else
+ /// nullptr.
+ virtual const char *GetQueueName() { return nullptr; }
+
+ virtual void SetQueueName(const char *name) {}
+
+ /// Retrieve the Queue kind for the queue currently using this Thread
+ ///
+ /// If this Thread is doing work on behalf of a libdispatch/GCD queue,
+ /// retrieve the Queue kind - either eQueueKindSerial or
+ /// eQueueKindConcurrent, indicating that this queue processes work
+ /// items serially or concurrently.
+ ///
+ /// \return
+ /// The Queue kind, if the Thread subclass implements this, else
+ /// eQueueKindUnknown.
+ virtual lldb::QueueKind GetQueueKind() { return lldb::eQueueKindUnknown; }
+
+ virtual void SetQueueKind(lldb::QueueKind kind) {}
+
+ /// Retrieve the Queue for this thread, if any.
+ ///
+ /// \return
+ /// A QueueSP for the queue that is currently associated with this
+ /// thread.
+ /// An empty shared pointer indicates that this thread is not
+ /// associated with a queue, or libdispatch queues are not
+ /// supported on this target.
+ virtual lldb::QueueSP GetQueue() { return lldb::QueueSP(); }
+
+ /// Retrieve the address of the libdispatch_queue_t struct for queue
+ /// currently using this Thread
+ ///
+ /// If this Thread is doing work on behalf of a libdispatch/GCD queue,
+ /// retrieve the address of the libdispatch_queue_t structure describing
+ /// the queue.
+ ///
+ /// This address may be reused for different queues later in the Process
+ /// lifetime and should not be used to identify a queue uniquely. Use
+ /// the GetQueueID() call for that.
+ ///
+ /// \return
+ /// The Queue's libdispatch_queue_t address if the Thread subclass
+ /// implements this, else LLDB_INVALID_ADDRESS.
+ virtual lldb::addr_t GetQueueLibdispatchQueueAddress() {
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ virtual void SetQueueLibdispatchQueueAddress(lldb::addr_t dispatch_queue_t) {}
+
+ /// Whether this Thread already has all the Queue information cached or not
+ ///
+ /// A Thread may be associated with a libdispatch work Queue at a given
+ /// public stop event. If so, the thread can satisify requests like
+ /// GetQueueLibdispatchQueueAddress, GetQueueKind, GetQueueName, and
+ /// GetQueueID
+ /// either from information from the remote debug stub when it is initially
+ /// created, or it can query the SystemRuntime for that information.
+ ///
+ /// This method allows the SystemRuntime to discover if a thread has this
+ /// information already, instead of calling the thread to get the information
+ /// and having the thread call the SystemRuntime again.
+ virtual bool ThreadHasQueueInformation() const { return false; }
+
+ virtual uint32_t GetStackFrameCount() {
+ return GetStackFrameList()->GetNumFrames();
+ }
+
+ virtual lldb::StackFrameSP GetStackFrameAtIndex(uint32_t idx) {
+ return GetStackFrameList()->GetFrameAtIndex(idx);
+ }
+
+ virtual lldb::StackFrameSP
+ GetFrameWithConcreteFrameIndex(uint32_t unwind_idx);
+
+ bool DecrementCurrentInlinedDepth() {
+ return GetStackFrameList()->DecrementCurrentInlinedDepth();
+ }
+
+ uint32_t GetCurrentInlinedDepth() {
+ return GetStackFrameList()->GetCurrentInlinedDepth();
+ }
+
+ Status ReturnFromFrameWithIndex(uint32_t frame_idx,
+ lldb::ValueObjectSP return_value_sp,
+ bool broadcast = false);
+
+ Status ReturnFromFrame(lldb::StackFrameSP frame_sp,
+ lldb::ValueObjectSP return_value_sp,
+ bool broadcast = false);
+
+ Status JumpToLine(const FileSpec &file, uint32_t line,
+ bool can_leave_function, std::string *warnings = nullptr);
+
+ virtual lldb::StackFrameSP GetFrameWithStackID(const StackID &stack_id) {
+ if (stack_id.IsValid())
+ return GetStackFrameList()->GetFrameWithStackID(stack_id);
+ return lldb::StackFrameSP();
+ }
+
+ uint32_t GetSelectedFrameIndex() {
+ return GetStackFrameList()->GetSelectedFrameIndex();
+ }
+
+ lldb::StackFrameSP GetSelectedFrame();
+
+ uint32_t SetSelectedFrame(lldb_private::StackFrame *frame,
+ bool broadcast = false);
+
+ bool SetSelectedFrameByIndex(uint32_t frame_idx, bool broadcast = false);
+
+ bool SetSelectedFrameByIndexNoisily(uint32_t frame_idx,
+ Stream &output_stream);
+
+ void SetDefaultFileAndLineToSelectedFrame() {
+ GetStackFrameList()->SetDefaultFileAndLineToSelectedFrame();
+ }
+
+ virtual lldb::RegisterContextSP GetRegisterContext() = 0;
+
+ virtual lldb::RegisterContextSP
+ CreateRegisterContextForFrame(StackFrame *frame) = 0;
+
+ virtual void ClearStackFrames();
+
+ virtual bool SetBackingThread(const lldb::ThreadSP &thread_sp) {
+ return false;
+ }
+
+ virtual lldb::ThreadSP GetBackingThread() const { return lldb::ThreadSP(); }
+
+ virtual void ClearBackingThread() {
+ // Subclasses can use this function if a thread is actually backed by
+ // another thread. This is currently used for the OperatingSystem plug-ins
+ // where they might have a thread that is in memory, yet its registers are
+ // available through the lldb_private::Thread subclass for the current
+ // lldb_private::Process class. Since each time the process stops the
+ // backing threads for memory threads can change, we need a way to clear
+ // the backing thread for all memory threads each time we stop.
+ }
+
+ // If stop_format is true, this will be the form used when we print stop
+ // info. If false, it will be the form we use for thread list and co.
+ void DumpUsingSettingsFormat(Stream &strm, uint32_t frame_idx,
+ bool stop_format);
+
+ bool GetDescription(Stream &s, lldb::DescriptionLevel level,
+ bool print_json_thread, bool print_json_stopinfo);
+
+ /// Default implementation for stepping into.
+ ///
+ /// This function is designed to be used by commands where the
+ /// process is publicly stopped.
+ ///
+ /// \param[in] source_step
+ /// If true and the frame has debug info, then do a source level
+ /// step in, else do a single instruction step in.
+ ///
+ /// \param[in] step_in_avoids_code_without_debug_info
+ /// If \a true, then avoid stepping into code that doesn't have
+ /// debug info, else step into any code regardless of whether it
+ /// has debug info.
+ ///
+ /// \param[in] step_out_avoids_code_without_debug_info
+ /// If \a true, then if you step out to code with no debug info, keep
+ /// stepping out till you get to code with debug info.
+ ///
+ /// \return
+ /// An error that describes anything that went wrong
+ virtual Status
+ StepIn(bool source_step,
+ LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate,
+ LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate);
+
+ /// Default implementation for stepping over.
+ ///
+ /// This function is designed to be used by commands where the
+ /// process is publicly stopped.
+ ///
+ /// \param[in] source_step
+ /// If true and the frame has debug info, then do a source level
+ /// step over, else do a single instruction step over.
+ ///
+ /// \return
+ /// An error that describes anything that went wrong
+ virtual Status StepOver(
+ bool source_step,
+ LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate);
+
+ /// Default implementation for stepping out.
+ ///
+ /// This function is designed to be used by commands where the
+ /// process is publicly stopped.
+ ///
+ /// \return
+ /// An error that describes anything that went wrong
+ virtual Status StepOut();
+
+ /// Retrieves the per-thread data area.
+ /// Most OSs maintain a per-thread pointer (e.g. the FS register on
+ /// x64), which we return the value of here.
+ ///
+ /// \return
+ /// LLDB_INVALID_ADDRESS if not supported, otherwise the thread
+ /// pointer value.
+ virtual lldb::addr_t GetThreadPointer();
+
+ /// Retrieves the per-module TLS block for a thread.
+ ///
+ /// \param[in] module
+ /// The module to query TLS data for.
+ ///
+ /// \param[in] tls_file_addr
+ /// The thread local address in module
+ /// \return
+ /// If the 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,
+ lldb::addr_t tls_file_addr);
+
+ /// Check whether this thread is safe to run functions
+ ///
+ /// The SystemRuntime may know of certain thread states (functions in
+ /// process of execution, for instance) which can make it unsafe for
+ /// functions to be called.
+ ///
+ /// \return
+ /// True if it is safe to call functions on this thread.
+ /// False if function calls should be avoided on this thread.
+ virtual bool SafeToCallFunctions();
+
+ // Thread Plan Providers:
+ // This section provides the basic thread plans that the Process control
+ // machinery uses to run the target. ThreadPlan.h provides more details on
+ // how this mechanism works. The thread provides accessors to a set of plans
+ // that perform basic operations. The idea is that particular Platform
+ // plugins can override these methods to provide the implementation of these
+ // basic operations appropriate to their environment.
+ //
+ // NB: All the QueueThreadPlanXXX providers return Shared Pointers to
+ // Thread plans. This is useful so that you can modify the plans after
+ // creation in ways specific to that plan type. Also, it is often necessary
+ // for ThreadPlans that utilize other ThreadPlans to implement their task to
+ // keep a shared pointer to the sub-plan. But besides that, the shared
+ // pointers should only be held onto by entities who live no longer than the
+ // thread containing the ThreadPlan.
+ // FIXME: If this becomes a problem, we can make a version that just returns a
+ // pointer,
+ // which it is clearly unsafe to hold onto, and a shared pointer version, and
+ // only allow ThreadPlan and Co. to use the latter. That is made more
+ // annoying to do because there's no elegant way to friend a method to all
+ // sub-classes of a given class.
+ //
+
+ /// Queues the base plan for a thread.
+ /// The version returned by Process does some things that are useful,
+ /// like handle breakpoints and signals, so if you return a plugin specific
+ /// one you probably want to call through to the Process one for anything
+ /// your plugin doesn't explicitly handle.
+ ///
+ /// \param[in] abort_other_plans
+ /// \b true if we discard the currently queued plans and replace them with
+ /// this one.
+ /// Otherwise this plan will go on the end of the plan stack.
+ ///
+ /// \return
+ /// A shared pointer to the newly queued thread plan, or nullptr if the
+ /// plan could not be queued.
+ virtual lldb::ThreadPlanSP QueueFundamentalPlan(bool abort_other_plans);
+
+ /// Queues the plan used to step one instruction from the current PC of \a
+ /// thread.
+ ///
+ /// \param[in] step_over
+ /// \b true if we step over calls to functions, false if we step in.
+ ///
+ /// \param[in] abort_other_plans
+ /// \b true if we discard the currently queued plans and replace them with
+ /// this one.
+ /// Otherwise this plan will go on the end of the plan stack.
+ ///
+ /// \param[in] stop_other_threads
+ /// \b true if we will stop other threads while we single step this one.
+ ///
+ /// \param[out] status
+ /// A status with an error if queuing failed.
+ ///
+ /// \return
+ /// A shared pointer to the newly queued thread plan, or nullptr if the
+ /// plan could not be queued.
+ virtual lldb::ThreadPlanSP QueueThreadPlanForStepSingleInstruction(
+ bool step_over, bool abort_other_plans, bool stop_other_threads,
+ Status &status);
+
+ /// Queues the plan used to step through an address range, stepping over
+ /// function calls.
+ ///
+ /// \param[in] abort_other_plans
+ /// \b true if we discard the currently queued plans and replace them with
+ /// this one.
+ /// Otherwise this plan will go on the end of the plan stack.
+ ///
+ /// \param[in] type
+ /// Type of step to do, only eStepTypeInto and eStepTypeOver are supported
+ /// by this plan.
+ ///
+ /// \param[in] range
+ /// The address range to step through.
+ ///
+ /// \param[in] addr_context
+ /// When dealing with stepping through inlined functions the current PC is
+ /// not enough information to know
+ /// what "step" means. For instance a series of nested inline functions
+ /// might start at the same address.
+ // The \a addr_context provides the current symbol context the step
+ /// is supposed to be out of.
+ // FIXME: Currently unused.
+ ///
+ /// \param[in] stop_other_threads
+ /// \b true if we will stop other threads while we single step this one.
+ ///
+ /// \param[out] status
+ /// A status with an error if queuing failed.
+ ///
+ /// \param[in] step_out_avoids_code_without_debug_info
+ /// If eLazyBoolYes, if the step over steps out it will continue to step
+ /// out till it comes to a frame with debug info.
+ /// If eLazyBoolCalculate, we will consult the default set in the thread.
+ ///
+ /// \return
+ /// A shared pointer to the newly queued thread plan, or nullptr if the
+ /// plan could not be queued.
+ virtual lldb::ThreadPlanSP QueueThreadPlanForStepOverRange(
+ bool abort_other_plans, const AddressRange &range,
+ const SymbolContext &addr_context, lldb::RunMode stop_other_threads,
+ Status &status,
+ LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate);
+
+ // Helper function that takes a LineEntry to step, insted of an AddressRange.
+ // This may combine multiple LineEntries of the same source line number to
+ // step over a longer address range in a single operation.
+ virtual lldb::ThreadPlanSP QueueThreadPlanForStepOverRange(
+ bool abort_other_plans, const LineEntry &line_entry,
+ const SymbolContext &addr_context, lldb::RunMode stop_other_threads,
+ Status &status,
+ LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate);
+
+ /// Queues the plan used to step through an address range, stepping into
+ /// functions.
+ ///
+ /// \param[in] abort_other_plans
+ /// \b true if we discard the currently queued plans and replace them with
+ /// this one.
+ /// Otherwise this plan will go on the end of the plan stack.
+ ///
+ /// \param[in] type
+ /// Type of step to do, only eStepTypeInto and eStepTypeOver are supported
+ /// by this plan.
+ ///
+ /// \param[in] range
+ /// The address range to step through.
+ ///
+ /// \param[in] addr_context
+ /// When dealing with stepping through inlined functions the current PC is
+ /// not enough information to know
+ /// what "step" means. For instance a series of nested inline functions
+ /// might start at the same address.
+ // The \a addr_context provides the current symbol context the step
+ /// is supposed to be out of.
+ // FIXME: Currently unused.
+ ///
+ /// \param[in] step_in_target
+ /// Name if function we are trying to step into. We will step out if we
+ /// don't land in that function.
+ ///
+ /// \param[in] stop_other_threads
+ /// \b true if we will stop other threads while we single step this one.
+ ///
+ /// \param[out] status
+ /// A status with an error if queuing failed.
+ ///
+ /// \param[in] step_in_avoids_code_without_debug_info
+ /// If eLazyBoolYes we will step out if we step into code with no debug
+ /// info.
+ /// If eLazyBoolCalculate we will consult the default set in the thread.
+ ///
+ /// \param[in] step_out_avoids_code_without_debug_info
+ /// If eLazyBoolYes, if the step over steps out it will continue to step
+ /// out till it comes to a frame with debug info.
+ /// If eLazyBoolCalculate, it will consult the default set in the thread.
+ ///
+ /// \return
+ /// A shared pointer to the newly queued thread plan, or nullptr if the
+ /// plan could not be queued.
+ virtual lldb::ThreadPlanSP QueueThreadPlanForStepInRange(
+ bool abort_other_plans, const AddressRange &range,
+ const SymbolContext &addr_context, const char *step_in_target,
+ lldb::RunMode stop_other_threads, Status &status,
+ LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate,
+ LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate);
+
+ // Helper function that takes a LineEntry to step, insted of an AddressRange.
+ // This may combine multiple LineEntries of the same source line number to
+ // step over a longer address range in a single operation.
+ virtual lldb::ThreadPlanSP QueueThreadPlanForStepInRange(
+ bool abort_other_plans, const LineEntry &line_entry,
+ const SymbolContext &addr_context, const char *step_in_target,
+ lldb::RunMode stop_other_threads, Status &status,
+ LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate,
+ LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate);
+
+ /// Queue the plan used to step out of the function at the current PC of
+ /// \a thread.
+ ///
+ /// \param[in] abort_other_plans
+ /// \b true if we discard the currently queued plans and replace them with
+ /// this one.
+ /// Otherwise this plan will go on the end of the plan stack.
+ ///
+ /// \param[in] addr_context
+ /// When dealing with stepping through inlined functions the current PC is
+ /// not enough information to know
+ /// what "step" means. For instance a series of nested inline functions
+ /// might start at the same address.
+ // The \a addr_context provides the current symbol context the step
+ /// is supposed to be out of.
+ // FIXME: Currently unused.
+ ///
+ /// \param[in] first_insn
+ /// \b true if this is the first instruction of a function.
+ ///
+ /// \param[in] stop_other_threads
+ /// \b true if we will stop other threads while we single step this one.
+ ///
+ /// \param[in] stop_vote
+ /// \param[in] run_vote
+ /// See standard meanings for the stop & run votes in ThreadPlan.h.
+ ///
+ /// \param[out] status
+ /// A status with an error if queuing failed.
+ ///
+ /// \param[in] step_out_avoids_code_without_debug_info
+ /// If eLazyBoolYes, if the step over steps out it will continue to step
+ /// out till it comes to a frame with debug info.
+ /// If eLazyBoolCalculate, it will consult the default set in the thread.
+ ///
+ /// \return
+ /// A shared pointer to the newly queued thread plan, or nullptr if the
+ /// plan could not be queued.
+ virtual lldb::ThreadPlanSP QueueThreadPlanForStepOut(
+ bool abort_other_plans, SymbolContext *addr_context, bool first_insn,
+ bool stop_other_threads, Vote stop_vote, Vote run_vote,
+ uint32_t frame_idx, Status &status,
+ LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate);
+
+ /// Queue the plan used to step out of the function at the current PC of
+ /// a thread. This version does not consult the should stop here callback,
+ /// and should only
+ /// be used by other thread plans when they need to retain control of the step
+ /// out.
+ ///
+ /// \param[in] abort_other_plans
+ /// \b true if we discard the currently queued plans and replace them with
+ /// this one.
+ /// Otherwise this plan will go on the end of the plan stack.
+ ///
+ /// \param[in] addr_context
+ /// When dealing with stepping through inlined functions the current PC is
+ /// not enough information to know
+ /// what "step" means. For instance a series of nested inline functions
+ /// might start at the same address.
+ // The \a addr_context provides the current symbol context the step
+ /// is supposed to be out of.
+ // FIXME: Currently unused.
+ ///
+ /// \param[in] first_insn
+ /// \b true if this is the first instruction of a function.
+ ///
+ /// \param[in] stop_other_threads
+ /// \b true if we will stop other threads while we single step this one.
+ ///
+ /// \param[in] stop_vote
+ ///
+ /// \param[in] run_vote
+ /// See standard meanings for the stop & run votes in ThreadPlan.h.
+ ///
+ /// \param[in] frame_idx
+ ///
+ /// \param[out] status
+ /// A status with an error if queuing failed.
+ ///
+ /// \param[in] continue_to_next_branch
+ /// Normally this will enqueue a plan that will put a breakpoint on the
+ /// return address and continue
+ /// to there. If continue_to_next_branch is true, this is an operation not
+ /// involving the user --
+ /// e.g. stepping "next" in a source line and we instruction stepped into
+ /// another function --
+ /// so instead of putting a breakpoint on the return address, advance the
+ /// breakpoint to the
+ /// end of the source line that is doing the call, or until the next flow
+ /// control instruction.
+ /// If the return value from the function call is to be retrieved /
+ /// displayed to the user, you must stop
+ /// on the return address. The return value may be stored in volatile
+ /// registers which are overwritten
+ /// before the next branch instruction.
+ ///
+ /// \return
+ /// A shared pointer to the newly queued thread plan, or nullptr if the
+ /// plan could not be queued.
+ virtual lldb::ThreadPlanSP QueueThreadPlanForStepOutNoShouldStop(
+ bool abort_other_plans, SymbolContext *addr_context, bool first_insn,
+ bool stop_other_threads, Vote stop_vote, Vote run_vote,
+ uint32_t frame_idx, Status &status, bool continue_to_next_branch = false);
+
+ /// Gets the plan used to step through the code that steps from a function
+ /// call site at the current PC into the actual function call.
+ ///
+ /// \param[in] return_stack_id
+ /// The stack id that we will return to (by setting backstop breakpoints on
+ /// the return
+ /// address to that frame) if we fail to step through.
+ ///
+ /// \param[in] abort_other_plans
+ /// \b true if we discard the currently queued plans and replace them with
+ /// this one.
+ /// Otherwise this plan will go on the end of the plan stack.
+ ///
+ /// \param[in] stop_other_threads
+ /// \b true if we will stop other threads while we single step this one.
+ ///
+ /// \param[out] status
+ /// A status with an error if queuing failed.
+ ///
+ /// \return
+ /// A shared pointer to the newly queued thread plan, or nullptr if the
+ /// plan could not be queued.
+ virtual lldb::ThreadPlanSP
+ QueueThreadPlanForStepThrough(StackID &return_stack_id,
+ bool abort_other_plans, bool stop_other_threads,
+ Status &status);
+
+ /// Gets the plan used to continue from the current PC.
+ /// This is a simple plan, mostly useful as a backstop when you are continuing
+ /// for some particular purpose.
+ ///
+ /// \param[in] abort_other_plans
+ /// \b true if we discard the currently queued plans and replace them with
+ /// this one.
+ /// Otherwise this plan will go on the end of the plan stack.
+ ///
+ /// \param[in] target_addr
+ /// The address to which we're running.
+ ///
+ /// \param[in] stop_other_threads
+ /// \b true if we will stop other threads while we single step this one.
+ ///
+ /// \param[out] status
+ /// A status with an error if queuing failed.
+ ///
+ /// \return
+ /// A shared pointer to the newly queued thread plan, or nullptr if the
+ /// plan could not be queued.
+ virtual lldb::ThreadPlanSP
+ QueueThreadPlanForRunToAddress(bool abort_other_plans, Address &target_addr,
+ bool stop_other_threads, Status &status);
+
+ virtual lldb::ThreadPlanSP QueueThreadPlanForStepUntil(
+ bool abort_other_plans, lldb::addr_t *address_list, size_t num_addresses,
+ bool stop_others, uint32_t frame_idx, Status &status);
+
+ virtual lldb::ThreadPlanSP
+ QueueThreadPlanForStepScripted(bool abort_other_plans, const char *class_name,
+ bool stop_other_threads, Status &status);
+
+ // Thread Plan accessors:
+
+ /// Gets the plan which will execute next on the plan stack.
+ ///
+ /// \return
+ /// A pointer to the next executed plan.
+ ThreadPlan *GetCurrentPlan();
+
+ /// Unwinds the thread stack for the innermost expression plan currently
+ /// on the thread plan stack.
+ ///
+ /// \return
+ /// An error if the thread plan could not be unwound.
+
+ Status UnwindInnermostExpression();
+
+ /// Gets the outer-most plan that was popped off the plan stack in the
+ /// most recent stop. Useful for printing the stop reason accurately.
+ ///
+ /// \return
+ /// A pointer to the last completed plan.
+ lldb::ThreadPlanSP GetCompletedPlan();
+
+ /// Gets the outer-most return value from the completed plans
+ ///
+ /// \return
+ /// A ValueObjectSP, either empty if there is no return value,
+ /// or containing the return value.
+ lldb::ValueObjectSP GetReturnValueObject();
+
+ /// Gets the outer-most expression variable from the completed plans
+ ///
+ /// \return
+ /// A ExpressionVariableSP, either empty if there is no
+ /// plan completed an expression during the current stop
+ /// or the expression variable that was made for the completed expression.
+ lldb::ExpressionVariableSP GetExpressionVariable();
+
+ /// Checks whether the given plan is in the completed plans for this
+ /// stop.
+ ///
+ /// \param[in] plan
+ /// Pointer to the plan you're checking.
+ ///
+ /// \return
+ /// Returns true if the input plan is in the completed plan stack,
+ /// false otherwise.
+ bool IsThreadPlanDone(ThreadPlan *plan);
+
+ /// Checks whether the given plan is in the discarded plans for this
+ /// stop.
+ ///
+ /// \param[in] plan
+ /// Pointer to the plan you're checking.
+ ///
+ /// \return
+ /// Returns true if the input plan is in the discarded plan stack,
+ /// false otherwise.
+ bool WasThreadPlanDiscarded(ThreadPlan *plan);
+
+ /// Check if we have completed plan to override breakpoint stop reason
+ ///
+ /// \return
+ /// Returns true if completed plan stack is not empty
+ /// false otherwise.
+ bool CompletedPlanOverridesBreakpoint();
+
+ /// Queues a generic thread plan.
+ ///
+ /// \param[in] plan_sp
+ /// The plan to queue.
+ ///
+ /// \param[in] abort_other_plans
+ /// \b true if we discard the currently queued plans and replace them with
+ /// this one.
+ /// Otherwise this plan will go on the end of the plan stack.
+ ///
+ /// \return
+ /// A pointer to the last completed plan.
+ Status QueueThreadPlan(lldb::ThreadPlanSP &plan_sp, bool abort_other_plans);
+
+ /// Discards the plans queued on the plan stack of the current thread. This
+ /// is
+ /// arbitrated by the "Master" ThreadPlans, using the "OkayToDiscard" call.
+ // But if \a force is true, all thread plans are discarded.
+ void DiscardThreadPlans(bool force);
+
+ /// Discards the plans queued on the plan stack of the current thread up to
+ /// and
+ /// including up_to_plan_sp.
+ //
+ // \param[in] up_to_plan_sp
+ // Discard all plans up to and including this one.
+ void DiscardThreadPlansUpToPlan(lldb::ThreadPlanSP &up_to_plan_sp);
+
+ void DiscardThreadPlansUpToPlan(ThreadPlan *up_to_plan_ptr);
+
+ /// Discards the plans queued on the plan stack of the current thread up to
+ /// and
+ /// including the plan in that matches \a thread_index counting only
+ /// the non-Private plans.
+ ///
+ /// \param[in] up_to_plan_sp
+ /// Discard all plans up to and including this user plan given by this
+ /// index.
+ ///
+ /// \return
+ /// \b true if there was a thread plan with that user index, \b false
+ /// otherwise.
+ bool DiscardUserThreadPlansUpToIndex(uint32_t thread_index);
+
+ /// Prints the current plan stack.
+ ///
+ /// \param[in] s
+ /// The stream to which to dump the plan stack info.
+ ///
+ void DumpThreadPlans(
+ Stream *s,
+ lldb::DescriptionLevel desc_level = lldb::eDescriptionLevelVerbose,
+ bool include_internal = true, bool ignore_boring = false) const;
+
+ virtual bool CheckpointThreadState(ThreadStateCheckpoint &saved_state);
+
+ virtual bool
+ RestoreRegisterStateFromCheckpoint(ThreadStateCheckpoint &saved_state);
+
+ virtual bool
+ RestoreThreadStateFromCheckpoint(ThreadStateCheckpoint &saved_state);
+
+ void EnableTracer(bool value, bool single_step);
+
+ void SetTracer(lldb::ThreadPlanTracerSP &tracer_sp);
+
+ // Get the thread index ID. The index ID that is guaranteed to not be re-used
+ // by a process. They start at 1 and increase with each new thread. This
+ // allows easy command line access by a unique ID that is easier to type than
+ // the actual system thread ID.
+ uint32_t GetIndexID() const;
+
+ // Get the originating thread's index ID.
+ // In the case of an "extended" thread -- a thread which represents the stack
+ // that enqueued/spawned work that is currently executing -- we need to
+ // provide the IndexID of the thread that actually did this work. We don't
+ // want to just masquerade as that thread's IndexID by using it in our own
+ // IndexID because that way leads to madness - but the driver program which
+ // is iterating over extended threads may ask for the OriginatingThreadID to
+ // display that information to the user.
+ // Normal threads will return the same thing as GetIndexID();
+ virtual uint32_t GetExtendedBacktraceOriginatingIndexID() {
+ return GetIndexID();
+ }
+
+ // The API ID is often the same as the Thread::GetID(), but not in all cases.
+ // Thread::GetID() is the user visible thread ID that clients would want to
+ // see. The API thread ID is the thread ID that is used when sending data
+ // to/from the debugging protocol.
+ virtual lldb::user_id_t GetProtocolID() const { return GetID(); }
+
+ // lldb::ExecutionContextScope pure virtual functions
+ lldb::TargetSP CalculateTarget() override;
+
+ lldb::ProcessSP CalculateProcess() override;
+
+ lldb::ThreadSP CalculateThread() override;
+
+ lldb::StackFrameSP CalculateStackFrame() override;
+
+ void CalculateExecutionContext(ExecutionContext &exe_ctx) override;
+
+ lldb::StackFrameSP
+ GetStackFrameSPForStackFramePtr(StackFrame *stack_frame_ptr);
+
+ size_t GetStatus(Stream &strm, uint32_t start_frame, uint32_t num_frames,
+ uint32_t num_frames_with_source, bool stop_format,
+ bool only_stacks = false);
+
+ size_t GetStackFrameStatus(Stream &strm, uint32_t first_frame,
+ uint32_t num_frames, bool show_frame_info,
+ uint32_t num_frames_with_source);
+
+ // We need a way to verify that even though we have a thread in a shared
+ // pointer that the object itself is still valid. Currently this won't be the
+ // case if DestroyThread() was called. DestroyThread is called when a thread
+ // has been removed from the Process' thread list.
+ bool IsValid() const { return !m_destroy_called; }
+
+ // Sets and returns a valid stop info based on the process stop ID and the
+ // current thread plan. If the thread stop ID does not match the process'
+ // stop ID, the private stop reason is not set and an invalid StopInfoSP may
+ // be returned.
+ //
+ // NOTE: This function must be called before the current thread plan is
+ // moved to the completed plan stack (in Thread::ShouldStop()).
+ //
+ // NOTE: If subclasses override this function, ensure they do not overwrite
+ // the m_actual_stop_info if it is valid. The stop info may be a
+ // "checkpointed and restored" stop info, so if it is still around it is
+ // right even if you have not calculated this yourself, or if it disagrees
+ // with what you might have calculated.
+ virtual lldb::StopInfoSP GetPrivateStopInfo();
+
+ // Ask the thread subclass to set its stop info.
+ //
+ // Thread subclasses should call Thread::SetStopInfo(...) with the reason the
+ // thread stopped.
+ //
+ // \return
+ // True if Thread::SetStopInfo(...) was called, false otherwise.
+ virtual bool CalculateStopInfo() = 0;
+
+ // Gets the temporary resume state for a thread.
+ //
+ // This value gets set in each thread by complex debugger logic in
+ // Thread::ShouldResume() and an appropriate thread resume state will get set
+ // in each thread every time the process is resumed prior to calling
+ // Process::DoResume(). The lldb_private::Process subclass should adhere to
+ // the thread resume state request which will be one of:
+ //
+ // eStateRunning - thread will resume when process is resumed
+ // eStateStepping - thread should step 1 instruction and stop when process
+ // is resumed
+ // eStateSuspended - thread should not execute any instructions when
+ // process is resumed
+ lldb::StateType GetTemporaryResumeState() const {
+ return m_temporary_resume_state;
+ }
+
+ void SetStopInfo(const lldb::StopInfoSP &stop_info_sp);
+
+ void ResetStopInfo();
+
+ void SetShouldReportStop(Vote vote);
+
+ /// Sets the extended backtrace token for this thread
+ ///
+ /// Some Thread subclasses may maintain a token to help with providing
+ /// an extended backtrace. The SystemRuntime plugin will set/request this.
+ ///
+ /// \param [in] token
+ virtual void SetExtendedBacktraceToken(uint64_t token) {}
+
+ /// Gets the extended backtrace token for this thread
+ ///
+ /// Some Thread subclasses may maintain a token to help with providing
+ /// an extended backtrace. The SystemRuntime plugin will set/request this.
+ ///
+ /// \return
+ /// The token needed by the SystemRuntime to create an extended backtrace.
+ /// LLDB_INVALID_ADDRESS is returned if no token is available.
+ virtual uint64_t GetExtendedBacktraceToken() { return LLDB_INVALID_ADDRESS; }
+
+ lldb::ValueObjectSP GetCurrentException();
+
+ lldb::ThreadSP GetCurrentExceptionBacktrace();
+
+protected:
+ friend class ThreadPlan;
+ friend class ThreadList;
+ friend class ThreadEventData;
+ friend class StackFrameList;
+ friend class StackFrame;
+ friend class OperatingSystem;
+
+ // This is necessary to make sure thread assets get destroyed while the
+ // thread is still in good shape to call virtual thread methods. This must
+ // be called by classes that derive from Thread in their destructor.
+ virtual void DestroyThread();
+
+ void PushPlan(lldb::ThreadPlanSP &plan_sp);
+
+ void PopPlan();
+
+ void DiscardPlan();
+
+ ThreadPlan *GetPreviousPlan(ThreadPlan *plan);
+
+ typedef std::vector<lldb::ThreadPlanSP> plan_stack;
+
+ virtual lldb_private::Unwind *GetUnwinder();
+
+ // Check to see whether the thread is still at the last breakpoint hit that
+ // stopped it.
+ virtual bool IsStillAtLastBreakpointHit();
+
+ // Some threads are threads that are made up by OperatingSystem plugins that
+ // are threads that exist and are context switched out into memory. The
+ // OperatingSystem plug-in need a ways to know if a thread is "real" or made
+ // up.
+ virtual bool IsOperatingSystemPluginThread() const { return false; }
+
+ // Subclasses that have a way to get an extended info dictionary for this
+ // thread should fill
+ virtual lldb_private::StructuredData::ObjectSP FetchThreadExtendedInfo() {
+ return StructuredData::ObjectSP();
+ }
+
+ lldb::StackFrameListSP GetStackFrameList();
+
+ void SetTemporaryResumeState(lldb::StateType new_state) {
+ m_temporary_resume_state = new_state;
+ }
+
+ void FunctionOptimizationWarning(lldb_private::StackFrame *frame);
+
+ // Classes that inherit from Process can see and modify these
+ lldb::ProcessWP m_process_wp; ///< The process that owns this thread.
+ lldb::StopInfoSP m_stop_info_sp; ///< The private stop reason for this thread
+ uint32_t m_stop_info_stop_id; // This is the stop id for which the StopInfo is
+ // valid. Can use this so you know that
+ // the thread's m_stop_info_sp is current and you don't have to fetch it
+ // again
+ uint32_t m_stop_info_override_stop_id; // The stop ID containing the last time
+ // the stop info was checked against
+ // the stop info override
+ const uint32_t m_index_id; ///< A unique 1 based index assigned to each thread
+ ///for easy UI/command line access.
+ lldb::RegisterContextSP m_reg_context_sp; ///< The register context for this
+ ///thread's current register state.
+ lldb::StateType m_state; ///< The state of our process.
+ mutable std::recursive_mutex
+ m_state_mutex; ///< Multithreaded protection for m_state.
+ plan_stack m_plan_stack; ///< The stack of plans this thread is executing.
+ plan_stack m_completed_plan_stack; ///< Plans that have been completed by this
+ ///stop. They get deleted when the thread
+ ///resumes.
+ plan_stack m_discarded_plan_stack; ///< Plans that have been discarded by this
+ ///stop. They get deleted when the thread
+ ///resumes.
+ mutable std::recursive_mutex
+ m_frame_mutex; ///< Multithreaded protection for m_state.
+ lldb::StackFrameListSP m_curr_frames_sp; ///< The stack frames that get lazily
+ ///populated after a thread stops.
+ lldb::StackFrameListSP m_prev_frames_sp; ///< The previous stack frames from
+ ///the last time this thread stopped.
+ int m_resume_signal; ///< The signal that should be used when continuing this
+ ///thread.
+ lldb::StateType m_resume_state; ///< This state is used to force a thread to
+ ///be suspended from outside the ThreadPlan
+ ///logic.
+ lldb::StateType m_temporary_resume_state; ///< This state records what the
+ ///thread was told to do by the
+ ///thread plan logic for the current
+ ///resume.
+ /// It gets set in Thread::ShouldResume.
+ std::unique_ptr<lldb_private::Unwind> m_unwinder_up;
+ bool m_destroy_called; // This is used internally to make sure derived Thread
+ // classes call DestroyThread.
+ LazyBool m_override_should_notify;
+
+private:
+ bool m_extended_info_fetched; // Have we tried to retrieve the m_extended_info
+ // for this thread?
+ StructuredData::ObjectSP m_extended_info; // The extended info for this thread
+
+private:
+ bool PlanIsBasePlan(ThreadPlan *plan_ptr);
+
+ void BroadcastSelectedFrameChange(StackID &new_frame_id);
+
+ DISALLOW_COPY_AND_ASSIGN(Thread);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Thread_h_
diff --git a/linux-x64/clang/include/lldb/Target/ThreadCollection.h b/linux-x64/clang/include/lldb/Target/ThreadCollection.h
new file mode 100644
index 0000000..29ea827
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/ThreadCollection.h
@@ -0,0 +1,59 @@
+//===-- ThreadCollection.h --------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadCollection_h_
+#define liblldb_ThreadCollection_h_
+
+#include <mutex>
+#include <vector>
+
+#include "lldb/Utility/Iterable.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+class ThreadCollection {
+public:
+ typedef std::vector<lldb::ThreadSP> collection;
+ typedef LockingAdaptedIterable<collection, lldb::ThreadSP, vector_adapter,
+ std::recursive_mutex>
+ ThreadIterable;
+
+ ThreadCollection();
+
+ ThreadCollection(collection threads);
+
+ virtual ~ThreadCollection() {}
+
+ uint32_t GetSize();
+
+ void AddThread(const lldb::ThreadSP &thread_sp);
+
+ void AddThreadSortedByIndexID(const lldb::ThreadSP &thread_sp);
+
+ void InsertThread(const lldb::ThreadSP &thread_sp, uint32_t idx);
+
+ // Note that "idx" is not the same as the "thread_index". It is a zero based
+ // index to accessing the current threads, whereas "thread_index" is a unique
+ // index assigned
+ lldb::ThreadSP GetThreadAtIndex(uint32_t idx);
+
+ virtual ThreadIterable Threads() {
+ return ThreadIterable(m_threads, GetMutex());
+ }
+
+ virtual std::recursive_mutex &GetMutex() const { return m_mutex; }
+
+protected:
+ collection m_threads;
+ mutable std::recursive_mutex m_mutex;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadCollection_h_
diff --git a/linux-x64/clang/include/lldb/Target/ThreadList.h b/linux-x64/clang/include/lldb/Target/ThreadList.h
new file mode 100644
index 0000000..64ddf5a
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/ThreadList.h
@@ -0,0 +1,159 @@
+//===-- ThreadList.h --------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadList_h_
+#define liblldb_ThreadList_h_
+
+#include <mutex>
+#include <vector>
+
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadCollection.h"
+#include "lldb/Utility/Iterable.h"
+#include "lldb/Utility/UserID.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+// This is a thread list with lots of functionality for use only by the process
+// for which this is the thread list. A generic container class with iterator
+// functionality is ThreadCollection.
+class ThreadList : public ThreadCollection {
+ friend class Process;
+
+public:
+ ThreadList(Process *process);
+
+ ThreadList(const ThreadList &rhs);
+
+ ~ThreadList() override;
+
+ const ThreadList &operator=(const ThreadList &rhs);
+
+ uint32_t GetSize(bool can_update = true);
+
+ // Return the selected thread if there is one. Otherwise, return the thread
+ // selected at index 0.
+ lldb::ThreadSP GetSelectedThread();
+
+ // Manage the thread to use for running expressions. This is usually the
+ // Selected thread, but sometimes (e.g. when evaluating breakpoint conditions
+ // & stop hooks) it isn't.
+ class ExpressionExecutionThreadPusher {
+ public:
+ ExpressionExecutionThreadPusher(ThreadList &thread_list, lldb::tid_t tid)
+ : m_thread_list(&thread_list), m_tid(tid) {
+ m_thread_list->PushExpressionExecutionThread(m_tid);
+ }
+
+ ExpressionExecutionThreadPusher(lldb::ThreadSP thread_sp);
+
+ ~ExpressionExecutionThreadPusher() {
+ if (m_thread_list && m_tid != LLDB_INVALID_THREAD_ID)
+ m_thread_list->PopExpressionExecutionThread(m_tid);
+ }
+
+ private:
+ ThreadList *m_thread_list;
+ lldb::tid_t m_tid;
+ };
+
+ lldb::ThreadSP GetExpressionExecutionThread();
+
+protected:
+ void PushExpressionExecutionThread(lldb::tid_t tid);
+
+ void PopExpressionExecutionThread(lldb::tid_t tid);
+
+public:
+ bool SetSelectedThreadByID(lldb::tid_t tid, bool notify = false);
+
+ bool SetSelectedThreadByIndexID(uint32_t index_id, bool notify = false);
+
+ void Clear();
+
+ void Flush();
+
+ void Destroy();
+
+ // Note that "idx" is not the same as the "thread_index". It is a zero based
+ // index to accessing the current threads, whereas "thread_index" is a unique
+ // index assigned
+ lldb::ThreadSP GetThreadAtIndex(uint32_t idx, bool can_update = true);
+
+ lldb::ThreadSP FindThreadByID(lldb::tid_t tid, bool can_update = true);
+
+ lldb::ThreadSP FindThreadByProtocolID(lldb::tid_t tid,
+ bool can_update = true);
+
+ lldb::ThreadSP RemoveThreadByID(lldb::tid_t tid, bool can_update = true);
+
+ lldb::ThreadSP RemoveThreadByProtocolID(lldb::tid_t tid,
+ bool can_update = true);
+
+ lldb::ThreadSP FindThreadByIndexID(uint32_t index_id, bool can_update = true);
+
+ lldb::ThreadSP GetThreadSPForThreadPtr(Thread *thread_ptr);
+
+ lldb::ThreadSP GetBackingThread(const lldb::ThreadSP &real_thread);
+
+ bool ShouldStop(Event *event_ptr);
+
+ Vote ShouldReportStop(Event *event_ptr);
+
+ Vote ShouldReportRun(Event *event_ptr);
+
+ void RefreshStateAfterStop();
+
+ /// The thread list asks tells all the threads it is about to resume.
+ /// If a thread can "resume" without having to resume the target, it
+ /// will return false for WillResume, and then the process will not be
+ /// restarted.
+ ///
+ /// \return
+ /// \b true instructs the process to resume normally,
+ /// \b false means start & stopped events will be generated, but
+ /// the process will not actually run. The thread must then return
+ /// the correct StopInfo when asked.
+ ///
+ bool WillResume();
+
+ void DidResume();
+
+ void DidStop();
+
+ void DiscardThreadPlans();
+
+ uint32_t GetStopID() const;
+
+ void SetStopID(uint32_t stop_id);
+
+ std::recursive_mutex &GetMutex() const override;
+
+ void Update(ThreadList &rhs);
+
+protected:
+ void SetShouldReportStop(Vote vote);
+
+ void NotifySelectedThreadChanged(lldb::tid_t tid);
+
+ // Classes that inherit from Process can see and modify these
+ Process *m_process; ///< The process that manages this thread list.
+ uint32_t
+ m_stop_id; ///< The process stop ID that this thread list is valid for.
+ lldb::tid_t
+ m_selected_tid; ///< For targets that need the notion of a current thread.
+ std::vector<lldb::tid_t> m_expression_tid_stack;
+
+private:
+ ThreadList() = delete;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadList_h_
diff --git a/linux-x64/clang/include/lldb/Target/ThreadPlan.h b/linux-x64/clang/include/lldb/Target/ThreadPlan.h
new file mode 100644
index 0000000..ff87ed2
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/ThreadPlan.h
@@ -0,0 +1,649 @@
+//===-- ThreadPlan.h --------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlan_h_
+#define liblldb_ThreadPlan_h_
+
+#include <mutex>
+#include <string>
+
+#include "lldb/Target/Process.h"
+#include "lldb/Target/StopInfo.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlanTracer.h"
+#include "lldb/Utility/UserID.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+// ThreadPlan:
+// This is the pure virtual base class for thread plans.
+//
+// The thread plans provide the "atoms" of behavior that
+// all the logical process control, either directly from commands or through
+// more complex composite plans will rely on.
+//
+// Plan Stack:
+//
+// The thread maintaining a thread plan stack, and you program the actions of a
+// particular thread
+// by pushing plans onto the plan stack.
+// There is always a "Current" plan, which is the top of the plan stack,
+// though in some cases
+// a plan may defer to plans higher in the stack for some piece of information
+// (let us define that the plan stack grows downwards).
+//
+// The plan stack is never empty, there is always a Base Plan which persists
+// through the life
+// of the running process.
+//
+//
+// Creating Plans:
+//
+// The thread plan is generally created and added to the plan stack through the
+// QueueThreadPlanFor... API
+// in lldb::Thread. Those API's will return the plan that performs the named
+// operation in a manner
+// appropriate for the current process. The plans in lldb/source/Target are
+// generic
+// implementations, but a Process plugin can override them.
+//
+// ValidatePlan is then called. If it returns false, the plan is unshipped.
+// This is a little
+// convenience which keeps us from having to error out of the constructor.
+//
+// Then the plan is added to the plan stack. When the plan is added to the
+// plan stack its DidPush
+// will get called. This is useful if a plan wants to push any additional
+// plans as it is constructed,
+// since you need to make sure you're already on the stack before you push
+// additional plans.
+//
+// Completed Plans:
+//
+// When the target process stops the plans are queried, among other things, for
+// whether their job is done.
+// If it is they are moved from the plan stack to the Completed Plan stack in
+// reverse order from their position
+// on the plan stack (since multiple plans may be done at a given stop.) This
+// is used primarily so that
+// the lldb::Thread::StopInfo for the thread can be set properly. If one plan
+// pushes another to achieve part of
+// its job, but it doesn't want that sub-plan to be the one that sets the
+// StopInfo, then call SetPrivate on the
+// sub-plan when you create it, and the Thread will pass over that plan in
+// reporting the reason for the stop.
+//
+// Discarded plans:
+//
+// Your plan may also get discarded, i.e. moved from the plan stack to the
+// "discarded plan stack". This can
+// happen, for instance, if the plan is calling a function and the function
+// call crashes and you want
+// to unwind the attempt to call. So don't assume that your plan will always
+// successfully stop. Which leads to:
+//
+// Cleaning up after your plans:
+//
+// When the plan is moved from the plan stack its WillPop method is always
+// called, no matter why. Once it is
+// moved off the plan stack it is done, and won't get a chance to run again.
+// So you should
+// undo anything that affects target state in this method. But be sure to
+// leave the plan able to correctly
+// fill the StopInfo, however.
+// N.B. Don't wait to do clean up target state till the destructor, since that
+// will usually get called when
+// the target resumes, and you want to leave the target state correct for new
+// plans in the time between when
+// your plan gets unshipped and the next resume.
+//
+// Thread State Checkpoint:
+//
+// Note that calling functions on target process (ThreadPlanCallFunction) changes
+// current thread state. The function can be called either by direct user demand or
+// internally, for example lldb allocates memory on device to calculate breakpoint
+// condition expression - on Linux it is performed by calling mmap on device.
+// ThreadStateCheckpoint saves Thread state (stop info and completed
+// plan stack) to restore it after completing function call.
+//
+// Over the lifetime of the plan, various methods of the ThreadPlan are then
+// called in response to changes of state in
+// the process we are debugging as follows:
+//
+// Resuming:
+//
+// When the target process is about to be restarted, the plan's WillResume
+// method is called,
+// giving the plan a chance to prepare for the run. If WillResume returns
+// false, then the
+// process is not restarted. Be sure to set an appropriate error value in the
+// Process if
+// you have to do this. Note, ThreadPlans actually implement DoWillResume,
+// WillResume wraps that call.
+//
+// Next the "StopOthers" method of all the threads are polled, and if one
+// thread's Current plan
+// returns "true" then only that thread gets to run. If more than one returns
+// "true" the threads that want to run solo
+// get run one by one round robin fashion. Otherwise all are let to run.
+//
+// Note, the way StopOthers is implemented, the base class implementation just
+// asks the previous plan. So if your plan
+// has no opinion about whether it should run stopping others or not, just
+// don't implement StopOthers, and the parent
+// will be asked.
+//
+// Finally, for each thread that is running, it run state is set to the return
+// of RunState from the
+// thread's Current plan.
+//
+// Responding to a stop:
+//
+// When the target process stops, the plan is called in the following stages:
+//
+// First the thread asks the Current Plan if it can handle this stop by calling
+// PlanExplainsStop.
+// If the Current plan answers "true" then it is asked if the stop should
+// percolate all the way to the
+// user by calling the ShouldStop method. If the current plan doesn't explain
+// the stop, then we query up
+// the plan stack for a plan that does explain the stop. The plan that does
+// explain the stop then needs to
+// figure out what to do about the plans below it in the stack. If the stop is
+// recoverable, then the plan that
+// understands it can just do what it needs to set up to restart, and then
+// continue.
+// Otherwise, the plan that understood the stop should call DiscardPlanStack to
+// clean up the stack below it.
+// Note, plans actually implement DoPlanExplainsStop, the result is cached in
+// PlanExplainsStop so the DoPlanExplainsStop
+// itself will only get called once per stop.
+//
+// Master plans:
+//
+// In the normal case, when we decide to stop, we will collapse the plan stack
+// up to the point of the plan that understood
+// the stop reason. However, if a plan wishes to stay on the stack after an
+// event it didn't directly handle
+// it can designate itself a "Master" plan by responding true to IsMasterPlan,
+// and then if it wants not to be
+// discarded, it can return false to OkayToDiscard, and it and all its dependent
+// plans will be preserved when
+// we resume execution.
+//
+// The other effect of being a master plan is that when the Master plan is done
+// , if it has set "OkayToDiscard" to false,
+// then it will be popped & execution will stop and return to the user.
+// Remember that if OkayToDiscard is false, the
+// plan will be popped and control will be given to the next plan above it on
+// the stack So setting OkayToDiscard to
+// false means the user will regain control when the MasterPlan is completed.
+//
+// Between these two controls this allows things like: a MasterPlan/DontDiscard
+// Step Over to hit a breakpoint, stop and
+// return control to the user, but then when the user continues, the step out
+// succeeds.
+// Even more tricky, when the breakpoint is hit, the user can continue to step
+// in/step over/etc, and finally when they
+// continue, they will finish up the Step Over.
+//
+// FIXME: MasterPlan & OkayToDiscard aren't really orthogonal. MasterPlan
+// designation means that this plan controls
+// it's fate and the fate of plans below it. OkayToDiscard tells whether the
+// MasterPlan wants to stay on the stack. I
+// originally thought "MasterPlan-ness" would need to be a fixed characteristic
+// of a ThreadPlan, in which case you needed
+// the extra control. But that doesn't seem to be true. So we should be able
+// to convert to only MasterPlan status to mean
+// the current "MasterPlan/DontDiscard". Then no plans would be MasterPlans by
+// default, and you would set the ones you
+// wanted to be "user level" in this way.
+//
+//
+// Actually Stopping:
+//
+// If a plan says responds "true" to ShouldStop, then it is asked if it's job
+// is complete by calling
+// MischiefManaged. If that returns true, the plan is popped from the plan
+// stack and added to the
+// Completed Plan Stack. Then the next plan in the stack is asked if it
+// ShouldStop, and it returns "true",
+// it is asked if it is done, and if yes popped, and so on till we reach a plan
+// that is not done.
+//
+// Since you often know in the ShouldStop method whether your plan is complete,
+// as a convenience you can call
+// SetPlanComplete and the ThreadPlan implementation of MischiefManaged will
+// return "true", without your having
+// to redo the calculation when your sub-classes MischiefManaged is called. If
+// you call SetPlanComplete, you can
+// later use IsPlanComplete to determine whether the plan is complete. This is
+// only a convenience for sub-classes,
+// the logic in lldb::Thread will only call MischiefManaged.
+//
+// One slightly tricky point is you have to be careful using SetPlanComplete in
+// PlanExplainsStop because you
+// are not guaranteed that PlanExplainsStop for a plan will get called before
+// ShouldStop gets called. If your sub-plan
+// explained the stop and then popped itself, only your ShouldStop will get
+// called.
+//
+// If ShouldStop for any thread returns "true", then the WillStop method of the
+// Current plan of
+// all threads will be called, the stop event is placed on the Process's public
+// broadcaster, and
+// control returns to the upper layers of the debugger.
+//
+// Reporting the stop:
+//
+// When the process stops, the thread is given a StopReason, in the form of a
+// StopInfo object. If there is a completed
+// plan corresponding to the stop, then the "actual" stop reason can be
+// suppressed, and instead a StopInfoThreadPlan
+// object will be cons'ed up from the top completed plan in the stack.
+// However, if the plan doesn't want to be
+// the stop reason, then it can call SetPlanComplete and pass in "false" for
+// the "success" parameter. In that case,
+// the real stop reason will be used instead. One exapmle of this is the
+// "StepRangeStepIn" thread plan. If it stops
+// because of a crash or breakpoint hit, it wants to unship itself, because it
+// isn't so useful to have step in keep going
+// after a breakpoint hit. But it can't be the reason for the stop or no-one
+// would see that they had hit a breakpoint.
+//
+// Cleaning up the plan stack:
+//
+// One of the complications of MasterPlans is that you may get past the limits
+// of a plan without triggering it to clean
+// itself up. For instance, if you are doing a MasterPlan StepOver, and hit a
+// breakpoint in a called function, then
+// step over enough times to step out of the initial StepOver range, each of
+// the step overs will explain the stop &
+// take themselves off the stack, but control would never be returned to the
+// original StepOver. Eventually, the user
+// will continue, and when that continue stops, the old stale StepOver plan
+// that was left on the stack will get woken
+// up and notice it is done. But that can leave junk on the stack for a while.
+// To avoid that, the plans implement a
+// "IsPlanStale" method, that can check whether it is relevant anymore. On
+// stop, after the regular plan negotiation,
+// the remaining plan stack is consulted and if any plan says it is stale, it
+// and the plans below it are discarded from
+// the stack.
+//
+// Automatically Resuming:
+//
+// If ShouldStop for all threads returns "false", then the target process will
+// resume. This then cycles back to
+// Resuming above.
+//
+// Reporting eStateStopped events when the target is restarted:
+//
+// If a plan decides to auto-continue the target by returning "false" from
+// ShouldStop, then it will be asked
+// whether the Stopped event should still be reported. For instance, if you
+// hit a breakpoint that is a User set
+// breakpoint, but the breakpoint callback said to continue the target process,
+// you might still want to inform
+// the upper layers of lldb that the stop had happened.
+// The way this works is every thread gets to vote on whether to report the
+// stop. If all votes are eVoteNoOpinion,
+// then the thread list will decide what to do (at present it will pretty much
+// always suppress these stopped events.)
+// If there is an eVoteYes, then the event will be reported regardless of the
+// other votes. If there is an eVoteNo
+// and no eVoteYes's, then the event won't be reported.
+//
+// One other little detail here, sometimes a plan will push another plan onto
+// the plan stack to do some part of
+// the first plan's job, and it would be convenient to tell that plan how it
+// should respond to ShouldReportStop.
+// You can do that by setting the stop_vote in the child plan when you create
+// it.
+//
+// Suppressing the initial eStateRunning event:
+//
+// The private process running thread will take care of ensuring that only one
+// "eStateRunning" event will be
+// delivered to the public Process broadcaster per public eStateStopped event.
+// However there are some cases
+// where the public state of this process is eStateStopped, but a thread plan
+// needs to restart the target, but
+// doesn't want the running event to be publicly broadcast. The obvious
+// example of this is running functions
+// by hand as part of expression evaluation. To suppress the running event
+// return eVoteNo from ShouldReportStop,
+// to force a running event to be reported return eVoteYes, in general though
+// you should return eVoteNoOpinion
+// which will allow the ThreadList to figure out the right thing to do.
+// The run_vote argument to the constructor works like stop_vote, and is a way
+// for a plan to instruct a sub-plan
+// on how to respond to ShouldReportStop.
+//
+
+class ThreadPlan : public std::enable_shared_from_this<ThreadPlan>,
+ public UserID {
+public:
+ enum ThreadScope { eAllThreads, eSomeThreads, eThisThread };
+
+ // We use these enums so that we can cast a base thread plan to it's real
+ // type without having to resort to dynamic casting.
+ enum ThreadPlanKind {
+ eKindGeneric,
+ eKindNull,
+ eKindBase,
+ eKindCallFunction,
+ eKindPython,
+ eKindStepInstruction,
+ eKindStepOut,
+ eKindStepOverBreakpoint,
+ eKindStepOverRange,
+ eKindStepInRange,
+ eKindRunToAddress,
+ eKindStepThrough,
+ eKindStepUntil,
+ eKindTestCondition
+
+ };
+
+ // Constructors and Destructors
+ ThreadPlan(ThreadPlanKind kind, const char *name, Thread &thread,
+ Vote stop_vote, Vote run_vote);
+
+ virtual ~ThreadPlan();
+
+ /// Returns the name of this thread plan.
+ ///
+ /// \return
+ /// A const char * pointer to the thread plan's name.
+ const char *GetName() const { return m_name.c_str(); }
+
+ /// Returns the Thread that is using this thread plan.
+ ///
+ /// \return
+ /// A pointer to the thread plan's owning thread.
+ Thread &GetThread() { return m_thread; }
+
+ const Thread &GetThread() const { return m_thread; }
+
+ Target &GetTarget() { return m_thread.GetProcess()->GetTarget(); }
+
+ const Target &GetTarget() const { return m_thread.GetProcess()->GetTarget(); }
+
+ /// Print a description of this thread to the stream \a s.
+ /// \a thread.
+ ///
+ /// \param[in] s
+ /// The stream to which to print the description.
+ ///
+ /// \param[in] level
+ /// The level of description desired. Note that eDescriptionLevelBrief
+ /// will be used in the stop message printed when the plan is complete.
+ virtual void GetDescription(Stream *s, lldb::DescriptionLevel level) = 0;
+
+ /// Returns whether this plan could be successfully created.
+ ///
+ /// \param[in] error
+ /// A stream to which to print some reason why the plan could not be
+ /// created.
+ /// Can be NULL.
+ ///
+ /// \return
+ /// \b true if the plan should be queued, \b false otherwise.
+ virtual bool ValidatePlan(Stream *error) = 0;
+
+ bool TracerExplainsStop() {
+ if (!m_tracer_sp)
+ return false;
+ else
+ return m_tracer_sp->TracerExplainsStop();
+ }
+
+ lldb::StateType RunState();
+
+ bool PlanExplainsStop(Event *event_ptr);
+
+ virtual bool ShouldStop(Event *event_ptr) = 0;
+
+ virtual bool ShouldAutoContinue(Event *event_ptr) { return false; }
+
+ // Whether a "stop class" event should be reported to the "outside world".
+ // In general if a thread plan is active, events should not be reported.
+
+ virtual Vote ShouldReportStop(Event *event_ptr);
+
+ virtual Vote ShouldReportRun(Event *event_ptr);
+
+ virtual void SetStopOthers(bool new_value);
+
+ virtual bool StopOthers();
+
+ // This is the wrapper for DoWillResume that does generic ThreadPlan logic,
+ // then calls DoWillResume.
+ bool WillResume(lldb::StateType resume_state, bool current_plan);
+
+ virtual bool WillStop() = 0;
+
+ bool IsMasterPlan() { return m_is_master_plan; }
+
+ bool SetIsMasterPlan(bool value) {
+ bool old_value = m_is_master_plan;
+ m_is_master_plan = value;
+ return old_value;
+ }
+
+ virtual bool OkayToDiscard();
+
+ void SetOkayToDiscard(bool value) { m_okay_to_discard = value; }
+
+ // The base class MischiefManaged does some cleanup - so you have to call it
+ // in your MischiefManaged derived class.
+ virtual bool MischiefManaged();
+
+ virtual void ThreadDestroyed() {
+ // Any cleanup that a plan might want to do in case the thread goes away in
+ // the middle of the plan being queued on a thread can be done here.
+ }
+
+ bool GetPrivate() { return m_plan_private; }
+
+ void SetPrivate(bool input) { m_plan_private = input; }
+
+ virtual void DidPush();
+
+ virtual void WillPop();
+
+ // This pushes a plan onto the plan stack of the current plan's thread.
+ void PushPlan(lldb::ThreadPlanSP &thread_plan_sp) {
+ m_thread.PushPlan(thread_plan_sp);
+ }
+
+ ThreadPlanKind GetKind() const { return m_kind; }
+
+ bool IsPlanComplete();
+
+ void SetPlanComplete(bool success = true);
+
+ virtual bool IsPlanStale() { return false; }
+
+ bool PlanSucceeded() { return m_plan_succeeded; }
+
+ virtual bool IsBasePlan() { return false; }
+
+ lldb::ThreadPlanTracerSP &GetThreadPlanTracer() { return m_tracer_sp; }
+
+ void SetThreadPlanTracer(lldb::ThreadPlanTracerSP new_tracer_sp) {
+ m_tracer_sp = new_tracer_sp;
+ }
+
+ void DoTraceLog() {
+ if (m_tracer_sp && m_tracer_sp->TracingEnabled())
+ m_tracer_sp->Log();
+ }
+
+ // Some thread plans hide away the actual stop info which caused any
+ // particular stop. For instance the ThreadPlanCallFunction restores the
+ // original stop reason so that stopping and calling a few functions won't
+ // lose the history of the run. This call can be implemented to get you back
+ // to the real stop info.
+ virtual lldb::StopInfoSP GetRealStopInfo() { return m_thread.GetStopInfo(); }
+
+ // If the completion of the thread plan stepped out of a function, the return
+ // value of the function might have been captured by the thread plan
+ // (currently only ThreadPlanStepOut does this.) If so, the ReturnValueObject
+ // can be retrieved from here.
+
+ virtual lldb::ValueObjectSP GetReturnValueObject() {
+ return lldb::ValueObjectSP();
+ }
+
+ // If the thread plan managing the evaluation of a user expression lives
+ // longer than the command that instigated the expression (generally because
+ // the expression evaluation hit a breakpoint, and the user regained control
+ // at that point) a subsequent process control command step/continue/etc.
+ // might complete the expression evaluations. If so, the result of the
+ // expression evaluation will show up here.
+
+ virtual lldb::ExpressionVariableSP GetExpressionVariable() {
+ return lldb::ExpressionVariableSP();
+ }
+
+ // If a thread plan stores the state before it was run, then you might want
+ // to restore the state when it is done. This will do that job. This is
+ // mostly useful for artificial plans like CallFunction plans.
+
+ virtual bool RestoreThreadState() {
+ // Nothing to do in general.
+ return true;
+ }
+
+ virtual bool IsVirtualStep() { return false; }
+
+ virtual bool SetIterationCount(size_t count) {
+ if (m_takes_iteration_count) {
+ // Don't tell me to do something 0 times...
+ if (count == 0)
+ return false;
+ m_iteration_count = count;
+ }
+ return m_takes_iteration_count;
+ }
+
+ virtual size_t GetIterationCount() {
+ if (!m_takes_iteration_count)
+ return 0;
+ else
+ return m_iteration_count;
+ }
+
+protected:
+ // Classes that inherit from ThreadPlan can see and modify these
+
+ virtual bool DoWillResume(lldb::StateType resume_state, bool current_plan) {
+ return true;
+ }
+
+ virtual bool DoPlanExplainsStop(Event *event_ptr) = 0;
+
+ // This gets the previous plan to the current plan (for forwarding requests).
+ // This is mostly a formal requirement, it allows us to make the Thread's
+ // GetPreviousPlan protected, but only friend ThreadPlan to thread.
+
+ ThreadPlan *GetPreviousPlan() { return m_thread.GetPreviousPlan(this); }
+
+ // This forwards the private Thread::GetPrivateStopInfo which is generally
+ // what ThreadPlan's need to know.
+
+ lldb::StopInfoSP GetPrivateStopInfo() {
+ return m_thread.GetPrivateStopInfo();
+ }
+
+ void SetStopInfo(lldb::StopInfoSP stop_reason_sp) {
+ m_thread.SetStopInfo(stop_reason_sp);
+ }
+
+ void CachePlanExplainsStop(bool does_explain) {
+ m_cached_plan_explains_stop = does_explain ? eLazyBoolYes : eLazyBoolNo;
+ }
+
+ LazyBool GetCachedPlanExplainsStop() const {
+ return m_cached_plan_explains_stop;
+ }
+
+ virtual lldb::StateType GetPlanRunState() = 0;
+
+ bool IsUsuallyUnexplainedStopReason(lldb::StopReason);
+
+ Status m_status;
+ Thread &m_thread;
+ Vote m_stop_vote;
+ Vote m_run_vote;
+ bool m_takes_iteration_count;
+ bool m_could_not_resolve_hw_bp;
+ int32_t m_iteration_count = 1;
+
+private:
+ // For ThreadPlan only
+ static lldb::user_id_t GetNextID();
+
+ ThreadPlanKind m_kind;
+ std::string m_name;
+ std::recursive_mutex m_plan_complete_mutex;
+ LazyBool m_cached_plan_explains_stop;
+ bool m_plan_complete;
+ bool m_plan_private;
+ bool m_okay_to_discard;
+ bool m_is_master_plan;
+ bool m_plan_succeeded;
+
+ lldb::ThreadPlanTracerSP m_tracer_sp;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(ThreadPlan);
+};
+
+// ThreadPlanNull:
+// Threads are assumed to always have at least one plan on the plan stack. This
+// is put on the plan stack when a thread is destroyed so that if you
+// accidentally access a thread after it is destroyed you won't crash. But
+// asking questions of the ThreadPlanNull is definitely an error.
+
+class ThreadPlanNull : public ThreadPlan {
+public:
+ ThreadPlanNull(Thread &thread);
+ ~ThreadPlanNull() override;
+
+ void GetDescription(Stream *s, lldb::DescriptionLevel level) override;
+
+ bool ValidatePlan(Stream *error) override;
+
+ bool ShouldStop(Event *event_ptr) override;
+
+ bool MischiefManaged() override;
+
+ bool WillStop() override;
+
+ bool IsBasePlan() override { return true; }
+
+ bool OkayToDiscard() override { return false; }
+
+ const Status &GetStatus() { return m_status; }
+
+protected:
+ bool DoPlanExplainsStop(Event *event_ptr) override;
+
+ lldb::StateType GetPlanRunState() override;
+
+ DISALLOW_COPY_AND_ASSIGN(ThreadPlanNull);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlan_h_
diff --git a/linux-x64/clang/include/lldb/Target/ThreadPlanBase.h b/linux-x64/clang/include/lldb/Target/ThreadPlanBase.h
new file mode 100644
index 0000000..bc92a06
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/ThreadPlanBase.h
@@ -0,0 +1,55 @@
+//===-- ThreadPlanBase.h ----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlanFundamental_h_
+#define liblldb_ThreadPlanFundamental_h_
+
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+
+namespace lldb_private {
+
+// Base thread plans:
+// This is the generic version of the bottom most plan on the plan stack. It
+// should
+// be able to handle generic breakpoint hitting, and signals and exceptions.
+
+class ThreadPlanBase : public ThreadPlan {
+ friend class Process; // RunThreadPlan manages "stopper" base plans.
+public:
+ ~ThreadPlanBase() override;
+
+ void GetDescription(Stream *s, lldb::DescriptionLevel level) override;
+ bool ValidatePlan(Stream *error) override;
+ bool ShouldStop(Event *event_ptr) override;
+ Vote ShouldReportStop(Event *event_ptr) override;
+ bool StopOthers() override;
+ lldb::StateType GetPlanRunState() override;
+ bool WillStop() override;
+ bool MischiefManaged() override;
+
+ bool OkayToDiscard() override { return false; }
+
+ bool IsBasePlan() override { return true; }
+
+protected:
+ bool DoWillResume(lldb::StateType resume_state, bool current_plan) override;
+ bool DoPlanExplainsStop(Event *event_ptr) override;
+ ThreadPlanBase(Thread &thread);
+
+private:
+ friend lldb::ThreadPlanSP
+ Thread::QueueFundamentalPlan(bool abort_other_plans);
+
+ DISALLOW_COPY_AND_ASSIGN(ThreadPlanBase);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlanFundamental_h_
diff --git a/linux-x64/clang/include/lldb/Target/ThreadPlanCallFunction.h b/linux-x64/clang/include/lldb/Target/ThreadPlanCallFunction.h
new file mode 100644
index 0000000..685160a
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/ThreadPlanCallFunction.h
@@ -0,0 +1,154 @@
+//===-- ThreadPlanCallFunction.h --------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlanCallFunction_h_
+#define liblldb_ThreadPlanCallFunction_h_
+
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+#include "lldb/lldb-private.h"
+
+#include "llvm/ADT/ArrayRef.h"
+
+namespace lldb_private {
+
+class ThreadPlanCallFunction : public ThreadPlan {
+ // Create a thread plan to call a function at the address passed in the
+ // "function" argument. If you plan to call GetReturnValueObject, then pass
+ // in the return type, otherwise just pass in an invalid CompilerType.
+public:
+ ThreadPlanCallFunction(Thread &thread, const Address &function,
+ const CompilerType &return_type,
+ llvm::ArrayRef<lldb::addr_t> args,
+ const EvaluateExpressionOptions &options);
+
+ ThreadPlanCallFunction(Thread &thread, const Address &function,
+ const EvaluateExpressionOptions &options);
+
+ ~ThreadPlanCallFunction() override;
+
+ void GetDescription(Stream *s, lldb::DescriptionLevel level) override;
+
+ bool ValidatePlan(Stream *error) override;
+
+ bool ShouldStop(Event *event_ptr) override;
+
+ Vote ShouldReportStop(Event *event_ptr) override;
+
+ bool StopOthers() override;
+
+ lldb::StateType GetPlanRunState() override;
+
+ void DidPush() override;
+
+ bool WillStop() override;
+
+ bool MischiefManaged() override;
+
+ // To get the return value from a function call you must create a
+ // lldb::ValueSP that contains a valid clang type in its context and call
+ // RequestReturnValue. The ValueSP will be stored and when the function is
+ // done executing, the object will check if there is a requested return
+ // value. If there is, the return value will be retrieved using the
+ // ABI::GetReturnValue() for the ABI in the process. Then after the thread
+ // plan is complete, you can call "GetReturnValue()" to retrieve the value
+ // that was extracted.
+
+ lldb::ValueObjectSP GetReturnValueObject() override {
+ return m_return_valobj_sp;
+ }
+
+ // Return the stack pointer that the function received on entry. Any stack
+ // address below this should be considered invalid after the function has
+ // been cleaned up.
+ lldb::addr_t GetFunctionStackPointer() { return m_function_sp; }
+
+ // Classes that derive from FunctionCaller, and implement their own WillPop
+ // methods should call this so that the thread state gets restored if the
+ // plan gets discarded.
+ void WillPop() override;
+
+ // If the thread plan stops mid-course, this will be the stop reason that
+ // interrupted us. Once DoTakedown is called, this will be the real stop
+ // reason at the end of the function call. If it hasn't been set for one or
+ // the other of these reasons, we'll return the PrivateStopReason. This is
+ // needed because we want the CallFunction thread plans not to show up as the
+ // stop reason. But if something bad goes wrong, it is nice to be able to
+ // tell the user what really happened.
+
+ lldb::StopInfoSP GetRealStopInfo() override {
+ if (m_real_stop_info_sp)
+ return m_real_stop_info_sp;
+ else
+ return GetPrivateStopInfo();
+ }
+
+ lldb::addr_t GetStopAddress() { return m_stop_address; }
+
+ bool RestoreThreadState() override;
+
+ void ThreadDestroyed() override { m_takedown_done = true; }
+
+ void SetStopOthers(bool new_value) override;
+
+protected:
+ void ReportRegisterState(const char *message);
+
+ bool DoPlanExplainsStop(Event *event_ptr) override;
+
+ virtual void SetReturnValue();
+
+ bool ConstructorSetup(Thread &thread, ABI *&abi,
+ lldb::addr_t &start_load_addr,
+ lldb::addr_t &function_load_addr);
+
+ virtual void DoTakedown(bool success);
+
+ void SetBreakpoints();
+
+ void ClearBreakpoints();
+
+ bool BreakpointsExplainStop();
+
+ bool m_valid;
+ bool m_stop_other_threads;
+ bool m_unwind_on_error;
+ bool m_ignore_breakpoints;
+ bool m_debug_execution;
+ bool m_trap_exceptions;
+ Address m_function_addr;
+ Address m_start_addr;
+ lldb::addr_t m_function_sp;
+ lldb::ThreadPlanSP m_subplan_sp;
+ LanguageRuntime *m_cxx_language_runtime;
+ LanguageRuntime *m_objc_language_runtime;
+ Thread::ThreadStateCheckpoint m_stored_thread_state;
+ lldb::StopInfoSP
+ m_real_stop_info_sp; // In general we want to hide call function
+ // thread plans, but for reporting purposes, it's
+ // nice to know the real stop reason. This gets set
+ // in DoTakedown.
+ StreamString m_constructor_errors;
+ lldb::ValueObjectSP m_return_valobj_sp; // If this contains a valid pointer,
+ // use the ABI to extract values when
+ // complete
+ bool m_takedown_done; // We want to ensure we only do the takedown once. This
+ // ensures that.
+ bool m_should_clear_objc_exception_bp;
+ bool m_should_clear_cxx_exception_bp;
+ lldb::addr_t m_stop_address; // This is the address we stopped at. Also set
+ // in DoTakedown;
+
+private:
+ CompilerType m_return_type;
+ DISALLOW_COPY_AND_ASSIGN(ThreadPlanCallFunction);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlanCallFunction_h_
diff --git a/linux-x64/clang/include/lldb/Target/ThreadPlanCallFunctionUsingABI.h b/linux-x64/clang/include/lldb/Target/ThreadPlanCallFunctionUsingABI.h
new file mode 100644
index 0000000..c21e4d3
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/ThreadPlanCallFunctionUsingABI.h
@@ -0,0 +1,52 @@
+//===-- ThreadPlanCallFunctionUsingABI.h --------------------------------*- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlanCallFunctionUsingABI_h_
+#define liblldb_ThreadPlanCallFunctionUsingABI_h_
+
+#include "lldb/Target/ABI.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlanCallFunction.h"
+#include "lldb/lldb-private.h"
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/IR/DerivedTypes.h"
+
+namespace lldb_private {
+
+class ThreadPlanCallFunctionUsingABI : public ThreadPlanCallFunction {
+ // Create a thread plan to call a function at the address passed in the
+ // "function" argument, this function is executed using register manipulation
+ // instead of JIT. Class derives from ThreadPlanCallFunction and differs by
+ // calling a alternative
+ // ABI interface ABI::PrepareTrivialCall() which provides more detailed
+ // information.
+public:
+ ThreadPlanCallFunctionUsingABI(Thread &thread,
+ const Address &function_address,
+ llvm::Type &function_prototype,
+ llvm::Type &return_type,
+ llvm::ArrayRef<ABI::CallArgument> args,
+ const EvaluateExpressionOptions &options);
+
+ ~ThreadPlanCallFunctionUsingABI() override;
+
+ void GetDescription(Stream *s, lldb::DescriptionLevel level) override;
+
+protected:
+ void SetReturnValue() override;
+
+private:
+ llvm::Type &m_return_type;
+ DISALLOW_COPY_AND_ASSIGN(ThreadPlanCallFunctionUsingABI);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlanCallFunctionUsingABI_h_
diff --git a/linux-x64/clang/include/lldb/Target/ThreadPlanCallOnFunctionExit.h b/linux-x64/clang/include/lldb/Target/ThreadPlanCallOnFunctionExit.h
new file mode 100644
index 0000000..ad3ee6e
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/ThreadPlanCallOnFunctionExit.h
@@ -0,0 +1,53 @@
+//===-- ThreadPlanCallOnFunctionExit.h --------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ThreadPlanCallOnFunctionExit_h
+#define ThreadPlanCallOnFunctionExit_h
+
+#include "lldb/Target/ThreadPlan.h"
+
+#include <functional>
+
+namespace lldb_private {
+
+// =============================================================================
+/// This thread plan calls a function object when the current function exits.
+// =============================================================================
+
+class ThreadPlanCallOnFunctionExit : public ThreadPlan {
+public:
+ /// Definition for the callback made when the currently executing thread
+ /// finishes executing its function.
+ using Callback = std::function<void()>;
+
+ ThreadPlanCallOnFunctionExit(Thread &thread, const Callback &callback);
+
+ void DidPush() override;
+
+ // ThreadPlan API
+
+ void GetDescription(Stream *s, lldb::DescriptionLevel level) override;
+
+ bool ValidatePlan(Stream *error) override;
+
+ bool ShouldStop(Event *event_ptr) override;
+
+ bool WillStop() override;
+
+protected:
+ bool DoPlanExplainsStop(Event *event_ptr) override;
+
+ lldb::StateType GetPlanRunState() override;
+
+private:
+ Callback m_callback;
+ lldb::ThreadPlanSP m_step_out_threadplan_sp;
+};
+}
+
+#endif /* ThreadPlanCallOnFunctionExit_h */
diff --git a/linux-x64/clang/include/lldb/Target/ThreadPlanCallUserExpression.h b/linux-x64/clang/include/lldb/Target/ThreadPlanCallUserExpression.h
new file mode 100644
index 0000000..6372155
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/ThreadPlanCallUserExpression.h
@@ -0,0 +1,64 @@
+//===-- ThreadPlanCallUserExpression.h --------------------------------*- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlanCallUserExpression_h_
+#define liblldb_ThreadPlanCallUserExpression_h_
+
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+#include "lldb/Target/ThreadPlanCallFunction.h"
+#include "lldb/lldb-private.h"
+
+#include "llvm/ADT/ArrayRef.h"
+
+namespace lldb_private {
+
+class ThreadPlanCallUserExpression : public ThreadPlanCallFunction {
+public:
+ ThreadPlanCallUserExpression(Thread &thread, Address &function,
+ llvm::ArrayRef<lldb::addr_t> args,
+ const EvaluateExpressionOptions &options,
+ lldb::UserExpressionSP &user_expression_sp);
+
+ ~ThreadPlanCallUserExpression() override;
+
+ void GetDescription(Stream *s, lldb::DescriptionLevel level) override;
+
+ void DidPush() override;
+
+ void WillPop() override;
+
+ lldb::StopInfoSP GetRealStopInfo() override;
+
+ bool MischiefManaged() override;
+
+ void TransferExpressionOwnership() { m_manage_materialization = true; }
+
+ lldb::ExpressionVariableSP GetExpressionVariable() override {
+ return m_result_var_sp;
+ }
+
+protected:
+ void DoTakedown(bool success) override;
+private:
+ lldb::UserExpressionSP
+ m_user_expression_sp; // This is currently just used to ensure the
+ // User expression the initiated this ThreadPlan
+ // lives as long as the thread plan does.
+ bool m_manage_materialization = false;
+ lldb::ExpressionVariableSP
+ m_result_var_sp; // If we are left to manage the materialization,
+ // then stuff the result expression variable here.
+
+ DISALLOW_COPY_AND_ASSIGN(ThreadPlanCallUserExpression);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlanCallUserExpression_h_
diff --git a/linux-x64/clang/include/lldb/Target/ThreadPlanPython.h b/linux-x64/clang/include/lldb/Target/ThreadPlanPython.h
new file mode 100644
index 0000000..3825bf6
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/ThreadPlanPython.h
@@ -0,0 +1,66 @@
+//===-- ThreadPlanPython.h --------------------------------------------*- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlan_Python_h_
+#define liblldb_ThreadPlan_Python_h_
+
+#include <string>
+
+#include "lldb/Target/Process.h"
+#include "lldb/Target/StopInfo.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+#include "lldb/Target/ThreadPlanTracer.h"
+#include "lldb/Utility/StructuredData.h"
+#include "lldb/Utility/UserID.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+// ThreadPlanPython:
+//
+
+class ThreadPlanPython : public ThreadPlan {
+public:
+ ThreadPlanPython(Thread &thread, const char *class_name);
+ ~ThreadPlanPython() override;
+
+ void GetDescription(Stream *s, lldb::DescriptionLevel level) override;
+
+ bool ValidatePlan(Stream *error) override;
+
+ bool ShouldStop(Event *event_ptr) override;
+
+ bool MischiefManaged() override;
+
+ bool WillStop() override;
+
+ bool StopOthers() override;
+
+ void DidPush() override;
+
+ bool IsPlanStale() override;
+
+protected:
+ bool DoPlanExplainsStop(Event *event_ptr) override;
+
+ lldb::StateType GetPlanRunState() override;
+
+private:
+ std::string m_class_name;
+ StructuredData::ObjectSP m_implementation_sp;
+ bool m_did_push;
+
+ DISALLOW_COPY_AND_ASSIGN(ThreadPlanPython);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlan_Python_h_
diff --git a/linux-x64/clang/include/lldb/Target/ThreadPlanRunToAddress.h b/linux-x64/clang/include/lldb/Target/ThreadPlanRunToAddress.h
new file mode 100644
index 0000000..d82a9fa
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/ThreadPlanRunToAddress.h
@@ -0,0 +1,67 @@
+//===-- ThreadPlanRunToAddress.h --------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlanRunToAddress_h_
+#define liblldb_ThreadPlanRunToAddress_h_
+
+#include <vector>
+
+#include "lldb/Target/ThreadPlan.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+class ThreadPlanRunToAddress : public ThreadPlan {
+public:
+ ThreadPlanRunToAddress(Thread &thread, Address &address, bool stop_others);
+
+ ThreadPlanRunToAddress(Thread &thread, lldb::addr_t address,
+ bool stop_others);
+
+ ThreadPlanRunToAddress(Thread &thread,
+ const std::vector<lldb::addr_t> &addresses,
+ bool stop_others);
+
+ ~ThreadPlanRunToAddress() override;
+
+ void GetDescription(Stream *s, lldb::DescriptionLevel level) override;
+
+ bool ValidatePlan(Stream *error) override;
+
+ bool ShouldStop(Event *event_ptr) override;
+
+ bool StopOthers() override;
+
+ void SetStopOthers(bool new_value) override;
+
+ lldb::StateType GetPlanRunState() override;
+
+ bool WillStop() override;
+
+ bool MischiefManaged() override;
+
+protected:
+ bool DoPlanExplainsStop(Event *event_ptr) override;
+
+ void SetInitialBreakpoints();
+ bool AtOurAddress();
+
+private:
+ bool m_stop_others;
+ std::vector<lldb::addr_t>
+ m_addresses; // This is the address we are going to run to.
+ // TODO: Would it be useful to have multiple addresses?
+ std::vector<lldb::break_id_t> m_break_ids; // This is the breakpoint we are
+ // using to stop us at m_address.
+
+ DISALLOW_COPY_AND_ASSIGN(ThreadPlanRunToAddress);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlanRunToAddress_h_
diff --git a/linux-x64/clang/include/lldb/Target/ThreadPlanShouldStopHere.h b/linux-x64/clang/include/lldb/Target/ThreadPlanShouldStopHere.h
new file mode 100644
index 0000000..dfcbbb3
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/ThreadPlanShouldStopHere.h
@@ -0,0 +1,138 @@
+//===-- ThreadPlanShouldStopHere.h ------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlanShouldStopHere_h_
+#define liblldb_ThreadPlanShouldStopHere_h_
+
+#include "lldb/Target/ThreadPlan.h"
+
+namespace lldb_private {
+
+// This is an interface that ThreadPlans can adopt to allow flexible
+// modifications of the behavior when a thread plan comes to a place where it
+// would ordinarily stop. If such modification makes sense for your plan,
+// inherit from this class, and when you would be about to stop (in your
+// ShouldStop method), call InvokeShouldStopHereCallback, passing in the frame
+// comparison between where the step operation started and where you arrived.
+// If it returns true, then QueueStepOutFromHere will queue the plan to execute
+// instead of stopping.
+//
+// The classic example of the use of this is ThreadPlanStepInRange not stopping
+// in frames that have no debug information.
+//
+// This class also defines a set of flags to control general aspects of this
+// "ShouldStop" behavior.
+// A class implementing this protocol needs to define a default set of flags,
+// and can provide access to
+// changing that default flag set if it wishes.
+
+class ThreadPlanShouldStopHere {
+public:
+ struct ThreadPlanShouldStopHereCallbacks {
+ ThreadPlanShouldStopHereCallbacks() {
+ should_stop_here_callback = nullptr;
+ step_from_here_callback = nullptr;
+ }
+
+ ThreadPlanShouldStopHereCallbacks(
+ ThreadPlanShouldStopHereCallback should_stop,
+ ThreadPlanStepFromHereCallback step_from_here) {
+ should_stop_here_callback = should_stop;
+ step_from_here_callback = step_from_here;
+ }
+
+ void Clear() {
+ should_stop_here_callback = nullptr;
+ step_from_here_callback = nullptr;
+ }
+
+ ThreadPlanShouldStopHereCallback should_stop_here_callback;
+ ThreadPlanStepFromHereCallback step_from_here_callback;
+ };
+
+ enum {
+ eNone = 0,
+ eAvoidInlines = (1 << 0),
+ eStepInAvoidNoDebug = (1 << 1),
+ eStepOutAvoidNoDebug = (1 << 2)
+ };
+
+ // Constructors and Destructors
+ ThreadPlanShouldStopHere(ThreadPlan *owner);
+
+ ThreadPlanShouldStopHere(ThreadPlan *owner,
+ const ThreadPlanShouldStopHereCallbacks *callbacks,
+ void *baton = nullptr);
+ virtual ~ThreadPlanShouldStopHere();
+
+ // Set the ShouldStopHere callbacks. Pass in null to clear them and have no
+ // special behavior (though you can also call ClearShouldStopHereCallbacks
+ // for that purpose. If you pass in a valid pointer, it will adopt the non-
+ // null fields, and any null fields will be set to the default values.
+
+ void
+ SetShouldStopHereCallbacks(const ThreadPlanShouldStopHereCallbacks *callbacks,
+ void *baton) {
+ if (callbacks) {
+ m_callbacks = *callbacks;
+ if (!m_callbacks.should_stop_here_callback)
+ m_callbacks.should_stop_here_callback =
+ ThreadPlanShouldStopHere::DefaultShouldStopHereCallback;
+ if (!m_callbacks.step_from_here_callback)
+ m_callbacks.step_from_here_callback =
+ ThreadPlanShouldStopHere::DefaultStepFromHereCallback;
+ } else {
+ ClearShouldStopHereCallbacks();
+ }
+ m_baton = baton;
+ }
+
+ void ClearShouldStopHereCallbacks() { m_callbacks.Clear(); }
+
+ bool InvokeShouldStopHereCallback(lldb::FrameComparison operation,
+ Status &status);
+
+ lldb::ThreadPlanSP
+ CheckShouldStopHereAndQueueStepOut(lldb::FrameComparison operation,
+ Status &status);
+
+ lldb_private::Flags &GetFlags() { return m_flags; }
+
+ const lldb_private::Flags &GetFlags() const { return m_flags; }
+
+protected:
+ static bool DefaultShouldStopHereCallback(ThreadPlan *current_plan,
+ Flags &flags,
+ lldb::FrameComparison operation,
+ Status &status, void *baton);
+
+ static lldb::ThreadPlanSP
+ DefaultStepFromHereCallback(ThreadPlan *current_plan, Flags &flags,
+ lldb::FrameComparison operation, Status &status,
+ void *baton);
+
+ virtual lldb::ThreadPlanSP
+ QueueStepOutFromHerePlan(Flags &flags, lldb::FrameComparison operation,
+ Status &status);
+
+ // Implement this, and call it in the plan's constructor to set the default
+ // flags.
+ virtual void SetFlagsToDefault() = 0;
+
+ ThreadPlanShouldStopHereCallbacks m_callbacks;
+ void *m_baton;
+ ThreadPlan *m_owner;
+ lldb_private::Flags m_flags;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(ThreadPlanShouldStopHere);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlanShouldStopHere_h_
diff --git a/linux-x64/clang/include/lldb/Target/ThreadPlanStepInRange.h b/linux-x64/clang/include/lldb/Target/ThreadPlanStepInRange.h
new file mode 100644
index 0000000..a120c98
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/ThreadPlanStepInRange.h
@@ -0,0 +1,107 @@
+//===-- ThreadPlanStepInRange.h ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlanStepInRange_h_
+#define liblldb_ThreadPlanStepInRange_h_
+
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Target/StackID.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlanShouldStopHere.h"
+#include "lldb/Target/ThreadPlanStepRange.h"
+
+namespace lldb_private {
+
+class ThreadPlanStepInRange : public ThreadPlanStepRange,
+ public ThreadPlanShouldStopHere {
+public:
+ ThreadPlanStepInRange(Thread &thread, const AddressRange &range,
+ const SymbolContext &addr_context,
+ lldb::RunMode stop_others,
+ LazyBool step_in_avoids_code_without_debug_info,
+ LazyBool step_out_avoids_code_without_debug_info);
+
+ ThreadPlanStepInRange(Thread &thread, const AddressRange &range,
+ const SymbolContext &addr_context,
+ const char *step_into_function_name,
+ lldb::RunMode stop_others,
+ LazyBool step_in_avoids_code_without_debug_info,
+ LazyBool step_out_avoids_code_without_debug_info);
+
+ ~ThreadPlanStepInRange() override;
+
+ void GetDescription(Stream *s, lldb::DescriptionLevel level) override;
+
+ bool ShouldStop(Event *event_ptr) override;
+
+ void SetAvoidRegexp(const char *name);
+
+ void SetStepInTarget(const char *target) {
+ m_step_into_target.SetCString(target);
+ }
+
+ static void SetDefaultFlagValue(uint32_t new_value);
+
+ bool IsVirtualStep() override;
+
+protected:
+ static bool DefaultShouldStopHereCallback(ThreadPlan *current_plan,
+ Flags &flags,
+ lldb::FrameComparison operation,
+ Status &status, void *baton);
+
+ bool DoWillResume(lldb::StateType resume_state, bool current_plan) override;
+
+ bool DoPlanExplainsStop(Event *event_ptr) override;
+
+ void SetFlagsToDefault() override {
+ GetFlags().Set(ThreadPlanStepInRange::s_default_flag_values);
+ }
+
+ void SetCallbacks() {
+ ThreadPlanShouldStopHere::ThreadPlanShouldStopHereCallbacks callbacks(
+ ThreadPlanStepInRange::DefaultShouldStopHereCallback, nullptr);
+ SetShouldStopHereCallbacks(&callbacks, nullptr);
+ }
+
+ bool FrameMatchesAvoidCriteria();
+
+private:
+ friend lldb::ThreadPlanSP Thread::QueueThreadPlanForStepOverRange(
+ bool abort_other_plans, const AddressRange &range,
+ const SymbolContext &addr_context, lldb::RunMode stop_others,
+ Status &status, LazyBool avoid_code_without_debug_info);
+ friend lldb::ThreadPlanSP Thread::QueueThreadPlanForStepInRange(
+ bool abort_other_plans, const AddressRange &range,
+ const SymbolContext &addr_context, const char *step_in_target,
+ lldb::RunMode stop_others, Status &status,
+ LazyBool step_in_avoids_code_without_debug_info,
+ LazyBool step_out_avoids_code_without_debug_info);
+
+ void SetupAvoidNoDebug(LazyBool step_in_avoids_code_without_debug_info,
+ LazyBool step_out_avoids_code_without_debug_info);
+ // Need an appropriate marker for the current stack so we can tell step out
+ // from step in.
+
+ static uint32_t s_default_flag_values; // These are the default flag values
+ // for the ThreadPlanStepThrough.
+ lldb::ThreadPlanSP m_sub_plan_sp; // Keep track of the last plan we were
+ // running. If it fails, we should stop.
+ std::unique_ptr<RegularExpression> m_avoid_regexp_up;
+ bool m_step_past_prologue; // FIXME: For now hard-coded to true, we could put
+ // a switch in for this if there's
+ // demand for that.
+ bool m_virtual_step; // true if we've just done a "virtual step", i.e. just
+ // moved the inline stack depth.
+ ConstString m_step_into_target;
+ DISALLOW_COPY_AND_ASSIGN(ThreadPlanStepInRange);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlanStepInRange_h_
diff --git a/linux-x64/clang/include/lldb/Target/ThreadPlanStepInstruction.h b/linux-x64/clang/include/lldb/Target/ThreadPlanStepInstruction.h
new file mode 100644
index 0000000..127de41
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/ThreadPlanStepInstruction.h
@@ -0,0 +1,57 @@
+//===-- ThreadPlanStepInstruction.h -----------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlanStepInstruction_h_
+#define liblldb_ThreadPlanStepInstruction_h_
+
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+class ThreadPlanStepInstruction : public ThreadPlan {
+public:
+ ThreadPlanStepInstruction(Thread &thread, bool step_over, bool stop_others,
+ Vote stop_vote, Vote run_vote);
+
+ ~ThreadPlanStepInstruction() override;
+
+ void GetDescription(Stream *s, lldb::DescriptionLevel level) override;
+ bool ValidatePlan(Stream *error) override;
+ bool ShouldStop(Event *event_ptr) override;
+ bool StopOthers() override;
+ lldb::StateType GetPlanRunState() override;
+ bool WillStop() override;
+ bool MischiefManaged() override;
+ bool IsPlanStale() override;
+
+protected:
+ bool DoPlanExplainsStop(Event *event_ptr) override;
+
+ void SetUpState();
+
+private:
+ friend lldb::ThreadPlanSP Thread::QueueThreadPlanForStepSingleInstruction(
+ bool step_over, bool abort_other_plans, bool stop_other_threads,
+ Status &status);
+
+ lldb::addr_t m_instruction_addr;
+ bool m_stop_other_threads;
+ bool m_step_over;
+ // These two are used only for the step over case.
+ bool m_start_has_symbol;
+ StackID m_stack_id;
+ StackID m_parent_frame_id;
+
+ DISALLOW_COPY_AND_ASSIGN(ThreadPlanStepInstruction);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlanStepInstruction_h_
diff --git a/linux-x64/clang/include/lldb/Target/ThreadPlanStepOut.h b/linux-x64/clang/include/lldb/Target/ThreadPlanStepOut.h
new file mode 100644
index 0000000..00984db
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/ThreadPlanStepOut.h
@@ -0,0 +1,92 @@
+//===-- ThreadPlanStepOut.h -------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlanStepOut_h_
+#define liblldb_ThreadPlanStepOut_h_
+
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+#include "lldb/Target/ThreadPlanShouldStopHere.h"
+
+namespace lldb_private {
+
+class ThreadPlanStepOut : public ThreadPlan, public ThreadPlanShouldStopHere {
+public:
+ ThreadPlanStepOut(Thread &thread, SymbolContext *addr_context,
+ bool first_insn, bool stop_others, Vote stop_vote,
+ Vote run_vote, uint32_t frame_idx,
+ LazyBool step_out_avoids_code_without_debug_info,
+ bool continue_to_next_branch = false,
+ bool gather_return_value = true);
+
+ ~ThreadPlanStepOut() override;
+
+ void GetDescription(Stream *s, lldb::DescriptionLevel level) override;
+ bool ValidatePlan(Stream *error) override;
+ bool ShouldStop(Event *event_ptr) override;
+ bool StopOthers() override;
+ lldb::StateType GetPlanRunState() override;
+ bool WillStop() override;
+ bool MischiefManaged() override;
+ void DidPush() override;
+ bool IsPlanStale() override;
+
+ lldb::ValueObjectSP GetReturnValueObject() override {
+ return m_return_valobj_sp;
+ }
+
+protected:
+ void SetFlagsToDefault() override {
+ GetFlags().Set(ThreadPlanStepOut::s_default_flag_values);
+ }
+
+ bool DoPlanExplainsStop(Event *event_ptr) override;
+ bool DoWillResume(lldb::StateType resume_state, bool current_plan) override;
+ bool QueueInlinedStepPlan(bool queue_now);
+
+private:
+ static uint32_t s_default_flag_values; // These are the default flag values
+ // for the ThreadPlanStepThrough.
+
+ lldb::addr_t m_step_from_insn;
+ StackID m_step_out_to_id;
+ StackID m_immediate_step_from_id;
+ lldb::break_id_t m_return_bp_id;
+ lldb::addr_t m_return_addr;
+ bool m_stop_others;
+ lldb::ThreadPlanSP m_step_out_to_inline_plan_sp; // This plan implements step
+ // out to the real function
+ // containing
+ // an inlined frame so we can then step out of that.
+ lldb::ThreadPlanSP m_step_through_inline_plan_sp; // This plan then steps past
+ // the inlined frame(s).
+ lldb::ThreadPlanSP m_step_out_further_plan_sp; // This plan keeps stepping out
+ // if ShouldStopHere told us
+ // to.
+ Function *m_immediate_step_from_function;
+ std::vector<lldb::StackFrameSP> m_stepped_past_frames;
+ lldb::ValueObjectSP m_return_valobj_sp;
+ bool m_calculate_return_value;
+
+ friend lldb::ThreadPlanSP Thread::QueueThreadPlanForStepOut(
+ bool abort_other_plans, SymbolContext *addr_context, bool first_insn,
+ bool stop_others, Vote stop_vote, Vote run_vote, uint32_t frame_idx,
+ Status &status, LazyBool step_out_avoids_code_without_debug_info);
+
+ void SetupAvoidNoDebug(LazyBool step_out_avoids_code_without_debug_info);
+ // Need an appropriate marker for the current stack so we can tell step out
+ // from step in.
+
+ void CalculateReturnValue();
+
+ DISALLOW_COPY_AND_ASSIGN(ThreadPlanStepOut);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlanStepOut_h_
diff --git a/linux-x64/clang/include/lldb/Target/ThreadPlanStepOverBreakpoint.h b/linux-x64/clang/include/lldb/Target/ThreadPlanStepOverBreakpoint.h
new file mode 100644
index 0000000..7df7049
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/ThreadPlanStepOverBreakpoint.h
@@ -0,0 +1,55 @@
+//===-- ThreadPlanStepOverBreakpoint.h --------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlanStepOverBreakpoint_h_
+#define liblldb_ThreadPlanStepOverBreakpoint_h_
+
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+
+namespace lldb_private {
+
+class ThreadPlanStepOverBreakpoint : public ThreadPlan {
+public:
+ ThreadPlanStepOverBreakpoint(Thread &thread);
+
+ ~ThreadPlanStepOverBreakpoint() override;
+
+ void GetDescription(Stream *s, lldb::DescriptionLevel level) override;
+ bool ValidatePlan(Stream *error) override;
+ bool ShouldStop(Event *event_ptr) override;
+ bool StopOthers() override;
+ lldb::StateType GetPlanRunState() override;
+ bool WillStop() override;
+ void WillPop() override;
+ bool MischiefManaged() override;
+ void ThreadDestroyed() override;
+ void SetAutoContinue(bool do_it);
+ bool ShouldAutoContinue(Event *event_ptr) override;
+ bool IsPlanStale() override;
+
+ lldb::addr_t GetBreakpointLoadAddress() const { return m_breakpoint_addr; }
+
+protected:
+ bool DoPlanExplainsStop(Event *event_ptr) override;
+ bool DoWillResume(lldb::StateType resume_state, bool current_plan) override;
+
+ void ReenableBreakpointSite();
+
+private:
+ lldb::addr_t m_breakpoint_addr;
+ lldb::user_id_t m_breakpoint_site_id;
+ bool m_auto_continue;
+ bool m_reenabled_breakpoint_site;
+
+ DISALLOW_COPY_AND_ASSIGN(ThreadPlanStepOverBreakpoint);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlanStepOverBreakpoint_h_
diff --git a/linux-x64/clang/include/lldb/Target/ThreadPlanStepOverRange.h b/linux-x64/clang/include/lldb/Target/ThreadPlanStepOverRange.h
new file mode 100644
index 0000000..30763e3
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/ThreadPlanStepOverRange.h
@@ -0,0 +1,53 @@
+//===-- ThreadPlanStepOverRange.h -------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlanStepOverRange_h_
+#define liblldb_ThreadPlanStepOverRange_h_
+
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Target/StackID.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlanStepRange.h"
+
+namespace lldb_private {
+
+class ThreadPlanStepOverRange : public ThreadPlanStepRange,
+ ThreadPlanShouldStopHere {
+public:
+ ThreadPlanStepOverRange(Thread &thread, const AddressRange &range,
+ const SymbolContext &addr_context,
+ lldb::RunMode stop_others,
+ LazyBool step_out_avoids_no_debug);
+
+ ~ThreadPlanStepOverRange() override;
+
+ void GetDescription(Stream *s, lldb::DescriptionLevel level) override;
+ bool ShouldStop(Event *event_ptr) override;
+
+protected:
+ bool DoPlanExplainsStop(Event *event_ptr) override;
+ bool DoWillResume(lldb::StateType resume_state, bool current_plan) override;
+
+ void SetFlagsToDefault() override {
+ GetFlags().Set(ThreadPlanStepOverRange::s_default_flag_values);
+ }
+
+private:
+ static uint32_t s_default_flag_values;
+
+ void SetupAvoidNoDebug(LazyBool step_out_avoids_code_without_debug_info);
+ bool IsEquivalentContext(const SymbolContext &context);
+
+ bool m_first_resume;
+
+ DISALLOW_COPY_AND_ASSIGN(ThreadPlanStepOverRange);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlanStepOverRange_h_
diff --git a/linux-x64/clang/include/lldb/Target/ThreadPlanStepRange.h b/linux-x64/clang/include/lldb/Target/ThreadPlanStepRange.h
new file mode 100644
index 0000000..93d54ad
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/ThreadPlanStepRange.h
@@ -0,0 +1,88 @@
+//===-- ThreadPlanStepRange.h -----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlanStepRange_h_
+#define liblldb_ThreadPlanStepRange_h_
+
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Target/StackID.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+#include "lldb/Target/ThreadPlanShouldStopHere.h"
+
+namespace lldb_private {
+
+class ThreadPlanStepRange : public ThreadPlan {
+public:
+ ThreadPlanStepRange(ThreadPlanKind kind, const char *name, Thread &thread,
+ const AddressRange &range,
+ const SymbolContext &addr_context,
+ lldb::RunMode stop_others,
+ bool given_ranges_only = false);
+
+ ~ThreadPlanStepRange() override;
+
+ void GetDescription(Stream *s, lldb::DescriptionLevel level) override = 0;
+ bool ValidatePlan(Stream *error) override;
+ bool ShouldStop(Event *event_ptr) override = 0;
+ Vote ShouldReportStop(Event *event_ptr) override;
+ bool StopOthers() override;
+ lldb::StateType GetPlanRunState() override;
+ bool WillStop() override;
+ bool MischiefManaged() override;
+ void DidPush() override;
+ bool IsPlanStale() override;
+
+ void AddRange(const AddressRange &new_range);
+
+protected:
+ bool InRange();
+ lldb::FrameComparison CompareCurrentFrameToStartFrame();
+ bool InSymbol();
+ void DumpRanges(Stream *s);
+
+ Disassembler *GetDisassembler();
+
+ InstructionList *GetInstructionsForAddress(lldb::addr_t addr,
+ size_t &range_index,
+ size_t &insn_offset);
+
+ // Pushes a plan to proceed through the next section of instructions in the
+ // range - usually just a RunToAddress plan to run to the next branch.
+ // Returns true if it pushed such a plan. If there was no available 'quick
+ // run' plan, then just single step.
+ bool SetNextBranchBreakpoint();
+
+ void ClearNextBranchBreakpoint();
+
+ bool NextRangeBreakpointExplainsStop(lldb::StopInfoSP stop_info_sp);
+
+ SymbolContext m_addr_context;
+ std::vector<AddressRange> m_address_ranges;
+ lldb::RunMode m_stop_others;
+ StackID m_stack_id; // Use the stack ID so we can tell step out from step in.
+ StackID m_parent_stack_id; // Use the parent stack ID so we can identify tail
+ // calls and the like.
+ bool m_no_more_plans; // Need this one so we can tell if we stepped into a
+ // call,
+ // but can't continue, in which case we are done.
+ bool m_first_run_event; // We want to broadcast only one running event, our
+ // first.
+ lldb::BreakpointSP m_next_branch_bp_sp;
+ bool m_use_fast_step;
+ bool m_given_ranges_only;
+
+private:
+ std::vector<lldb::DisassemblerSP> m_instruction_ranges;
+
+ DISALLOW_COPY_AND_ASSIGN(ThreadPlanStepRange);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlanStepRange_h_
diff --git a/linux-x64/clang/include/lldb/Target/ThreadPlanStepThrough.h b/linux-x64/clang/include/lldb/Target/ThreadPlanStepThrough.h
new file mode 100644
index 0000000..0d06212
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/ThreadPlanStepThrough.h
@@ -0,0 +1,61 @@
+//===-- ThreadPlanStepThrough.h ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlanStepThrough_h_
+#define liblldb_ThreadPlanStepThrough_h_
+
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+
+namespace lldb_private {
+
+class ThreadPlanStepThrough : public ThreadPlan {
+public:
+ ~ThreadPlanStepThrough() override;
+
+ void GetDescription(Stream *s, lldb::DescriptionLevel level) override;
+ bool ValidatePlan(Stream *error) override;
+ bool ShouldStop(Event *event_ptr) override;
+ bool StopOthers() override;
+ lldb::StateType GetPlanRunState() override;
+ bool WillStop() override;
+ bool MischiefManaged() override;
+ void DidPush() override;
+
+protected:
+ bool DoPlanExplainsStop(Event *event_ptr) override;
+ bool DoWillResume(lldb::StateType resume_state, bool current_plan) override;
+
+ ThreadPlanStepThrough(Thread &thread, StackID &return_stack_id,
+ bool stop_others);
+
+ void LookForPlanToStepThroughFromCurrentPC();
+
+ bool HitOurBackstopBreakpoint();
+
+private:
+ friend lldb::ThreadPlanSP
+ Thread::QueueThreadPlanForStepThrough(StackID &return_stack_id,
+ bool abort_other_plans,
+ bool stop_others, Status &status);
+
+ void ClearBackstopBreakpoint();
+
+ lldb::ThreadPlanSP m_sub_plan_sp;
+ lldb::addr_t m_start_address;
+ lldb::break_id_t m_backstop_bkpt_id;
+ lldb::addr_t m_backstop_addr;
+ StackID m_return_stack_id;
+ bool m_stop_others;
+
+ DISALLOW_COPY_AND_ASSIGN(ThreadPlanStepThrough);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlanStepThrough_h_
diff --git a/linux-x64/clang/include/lldb/Target/ThreadPlanStepUntil.h b/linux-x64/clang/include/lldb/Target/ThreadPlanStepUntil.h
new file mode 100644
index 0000000..9a5934a
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/ThreadPlanStepUntil.h
@@ -0,0 +1,67 @@
+//===-- ThreadPlanStepUntil.h -----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlanStepUntil_h_
+#define liblldb_ThreadPlanStepUntil_h_
+
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+
+namespace lldb_private {
+
+class ThreadPlanStepUntil : public ThreadPlan {
+public:
+ ~ThreadPlanStepUntil() override;
+
+ void GetDescription(Stream *s, lldb::DescriptionLevel level) override;
+ bool ValidatePlan(Stream *error) override;
+ bool ShouldStop(Event *event_ptr) override;
+ bool StopOthers() override;
+ lldb::StateType GetPlanRunState() override;
+ bool WillStop() override;
+ bool MischiefManaged() override;
+
+protected:
+ bool DoWillResume(lldb::StateType resume_state, bool current_plan) override;
+ bool DoPlanExplainsStop(Event *event_ptr) override;
+
+ ThreadPlanStepUntil(Thread &thread, lldb::addr_t *address_list,
+ size_t num_addresses, bool stop_others,
+ uint32_t frame_idx = 0);
+
+ void AnalyzeStop();
+
+private:
+ StackID m_stack_id;
+ lldb::addr_t m_step_from_insn;
+ lldb::break_id_t m_return_bp_id;
+ lldb::addr_t m_return_addr;
+ bool m_stepped_out;
+ bool m_should_stop;
+ bool m_ran_analyze;
+ bool m_explains_stop;
+
+ typedef std::map<lldb::addr_t, lldb::break_id_t> until_collection;
+ until_collection m_until_points;
+ bool m_stop_others;
+
+ void Clear();
+
+ friend lldb::ThreadPlanSP Thread::QueueThreadPlanForStepUntil(
+ bool abort_other_plans, lldb::addr_t *address_list, size_t num_addresses,
+ bool stop_others, uint32_t frame_idx, Status &status);
+
+ // Need an appropriate marker for the current stack so we can tell step out
+ // from step in.
+
+ DISALLOW_COPY_AND_ASSIGN(ThreadPlanStepUntil);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlanStepUntil_h_
diff --git a/linux-x64/clang/include/lldb/Target/ThreadPlanTracer.h b/linux-x64/clang/include/lldb/Target/ThreadPlanTracer.h
new file mode 100644
index 0000000..80b0807
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/ThreadPlanTracer.h
@@ -0,0 +1,99 @@
+//===-- ThreadPlanTracer.h --------------------------------------------*- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlanTracer_h_
+#define liblldb_ThreadPlanTracer_h_
+
+#include "lldb/Symbol/TaggedASTType.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+class ThreadPlanTracer {
+ friend class ThreadPlan;
+
+public:
+ enum ThreadPlanTracerStyle {
+ eLocation = 0,
+ eStateChange,
+ eCheckFrames,
+ ePython
+ };
+
+ ThreadPlanTracer(Thread &thread, lldb::StreamSP &stream_sp);
+ ThreadPlanTracer(Thread &thread);
+
+ virtual ~ThreadPlanTracer() = default;
+
+ virtual void TracingStarted() {}
+
+ virtual void TracingEnded() {}
+
+ bool EnableTracing(bool value) {
+ bool old_value = m_enabled;
+ m_enabled = value;
+ if (old_value == false && value == true)
+ TracingStarted();
+ else if (old_value == true && value == false)
+ TracingEnded();
+
+ return old_value;
+ }
+
+ bool TracingEnabled() { return m_enabled; }
+
+ bool EnableSingleStep(bool value) {
+ bool old_value = m_single_step;
+ m_single_step = value;
+ return old_value;
+ }
+
+ bool SingleStepEnabled() { return m_single_step; }
+
+protected:
+ Thread &m_thread;
+
+ Stream *GetLogStream();
+
+ virtual void Log();
+
+private:
+ bool TracerExplainsStop();
+
+ bool m_single_step;
+ bool m_enabled;
+ lldb::StreamSP m_stream_sp;
+};
+
+class ThreadPlanAssemblyTracer : public ThreadPlanTracer {
+public:
+ ThreadPlanAssemblyTracer(Thread &thread, lldb::StreamSP &stream_sp);
+ ThreadPlanAssemblyTracer(Thread &thread);
+ ~ThreadPlanAssemblyTracer() override;
+
+ void TracingStarted() override;
+ void TracingEnded() override;
+ void Log() override;
+
+private:
+ Disassembler *GetDisassembler();
+
+ TypeFromUser GetIntPointerType();
+
+ lldb::DisassemblerSP m_disassembler_sp;
+ TypeFromUser m_intptr_type;
+ std::vector<RegisterValue> m_register_values;
+ lldb::DataBufferSP m_buffer_sp;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlanTracer_h_
diff --git a/linux-x64/clang/include/lldb/Target/ThreadSpec.h b/linux-x64/clang/include/lldb/Target/ThreadSpec.h
new file mode 100644
index 0000000..05e7dcd
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/ThreadSpec.h
@@ -0,0 +1,129 @@
+//===-- ThreadSpec.h --------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadSpec_h_
+#define liblldb_ThreadSpec_h_
+
+#include "lldb/Utility/StructuredData.h"
+#include "lldb/lldb-private.h"
+#include <string>
+
+namespace lldb_private {
+
+// Note: For now the thread spec has only fixed elements -
+// Thread ID
+// Thread Index
+// Thread Name
+// Thread Queue Name
+//
+// But if we need more generality, we can hang a key/value map off of this
+// structure.
+// That's why the thread matches spec test is done as a virtual method in
+// Thread::MatchesSpec,
+// since it is the native thread that would know how to interpret the keys.
+// I was going to do the Queue Name this way out of sheer orneriness, but that
+// seems a
+// sufficiently general concept, so I put it in here on its own.
+
+class ThreadSpec {
+public:
+ ThreadSpec();
+
+ static std::unique_ptr<ThreadSpec>
+ CreateFromStructuredData(const StructuredData::Dictionary &data_dict,
+ Status &error);
+
+ StructuredData::ObjectSP SerializeToStructuredData();
+
+ static const char *GetSerializationKey() { return "ThreadSpec"; }
+
+ void SetIndex(uint32_t index) { m_index = index; }
+
+ void SetTID(lldb::tid_t tid) { m_tid = tid; }
+
+ void SetName(llvm::StringRef name) { m_name = name; }
+
+ void SetQueueName(llvm::StringRef queue_name) { m_queue_name = queue_name; }
+
+ uint32_t GetIndex() const { return m_index; }
+
+ lldb::tid_t GetTID() const { return m_tid; }
+
+ const char *GetName() const;
+
+ const char *GetQueueName() const;
+
+ bool TIDMatches(lldb::tid_t thread_id) const {
+ if (m_tid == LLDB_INVALID_THREAD_ID || thread_id == LLDB_INVALID_THREAD_ID)
+ return true;
+ else
+ return thread_id == m_tid;
+ }
+
+ bool TIDMatches(Thread &thread) const;
+
+ bool IndexMatches(uint32_t index) const {
+ if (m_index == UINT32_MAX || index == UINT32_MAX)
+ return true;
+ else
+ return index == m_index;
+ }
+
+ bool IndexMatches(Thread &thread) const;
+
+ bool NameMatches(const char *name) const {
+ if (m_name.empty())
+ return true;
+ else if (name == nullptr)
+ return false;
+ else
+ return m_name == name;
+ }
+
+ bool NameMatches(Thread &thread) const;
+
+ bool QueueNameMatches(const char *queue_name) const {
+ if (m_queue_name.empty())
+ return true;
+ else if (queue_name == nullptr)
+ return false;
+ else
+ return m_queue_name == queue_name;
+ }
+
+ bool QueueNameMatches(Thread &thread) const;
+
+ bool ThreadPassesBasicTests(Thread &thread) const;
+
+ bool HasSpecification() const;
+
+ void GetDescription(Stream *s, lldb::DescriptionLevel level) const;
+
+private:
+ enum class OptionNames {
+ ThreadIndex = 0,
+ ThreadID,
+ ThreadName,
+ QueueName,
+ LastOptionName
+ };
+ static const char *g_option_names[(size_t)OptionNames::LastOptionName];
+
+ static const char *GetKey(OptionNames enum_value) {
+ return g_option_names[(size_t) enum_value];
+ }
+
+ uint32_t m_index;
+ lldb::tid_t m_tid;
+ std::string m_name;
+ std::string m_queue_name;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadSpec_h_
diff --git a/linux-x64/clang/include/lldb/Target/UnixSignals.h b/linux-x64/clang/include/lldb/Target/UnixSignals.h
new file mode 100644
index 0000000..120ffdd
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/UnixSignals.h
@@ -0,0 +1,129 @@
+//===-- UnixSignals.h -------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_UnixSignals_h_
+#define lldb_UnixSignals_h_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "lldb/Utility/ConstString.h"
+#include "lldb/lldb-private.h"
+#include "llvm/ADT/Optional.h"
+
+namespace lldb_private {
+
+class UnixSignals {
+public:
+ static lldb::UnixSignalsSP Create(const ArchSpec &arch);
+ static lldb::UnixSignalsSP CreateForHost();
+
+ // Constructors and Destructors
+ UnixSignals();
+
+ virtual ~UnixSignals();
+
+ const char *GetSignalAsCString(int32_t signo) const;
+
+ bool SignalIsValid(int32_t signo) const;
+
+ int32_t GetSignalNumberFromName(const char *name) const;
+
+ const char *GetSignalInfo(int32_t signo, bool &should_suppress,
+ bool &should_stop, bool &should_notify) const;
+
+ bool GetShouldSuppress(int32_t signo) const;
+
+ bool SetShouldSuppress(int32_t signo, bool value);
+
+ bool SetShouldSuppress(const char *signal_name, bool value);
+
+ bool GetShouldStop(int32_t signo) const;
+
+ bool SetShouldStop(int32_t signo, bool value);
+ bool SetShouldStop(const char *signal_name, bool value);
+
+ bool GetShouldNotify(int32_t signo) const;
+
+ bool SetShouldNotify(int32_t signo, bool value);
+
+ bool SetShouldNotify(const char *signal_name, bool value);
+
+ // These provide an iterator through the signals available on this system.
+ // Call GetFirstSignalNumber to get the first entry, then iterate on
+ // GetNextSignalNumber till you get back LLDB_INVALID_SIGNAL_NUMBER.
+ int32_t GetFirstSignalNumber() const;
+
+ int32_t GetNextSignalNumber(int32_t current_signal) const;
+
+ int32_t GetNumSignals() const;
+
+ int32_t GetSignalAtIndex(int32_t index) const;
+
+ ConstString GetShortName(ConstString name) const;
+
+ // We assume that the elements of this object are constant once it is
+ // constructed, since a process should never need to add or remove symbols as
+ // it runs. So don't call these functions anywhere but the constructor of
+ // your subclass of UnixSignals or in your Process Plugin's GetUnixSignals
+ // method before you return the UnixSignal object.
+
+ void AddSignal(int signo, const char *name, bool default_suppress,
+ bool default_stop, bool default_notify,
+ const char *description, const char *alias = nullptr);
+
+ void RemoveSignal(int signo);
+
+ // Returns a current version of the data stored in this class. Version gets
+ // incremented each time Set... method is called.
+ uint64_t GetVersion() const;
+
+ // Returns a vector of signals that meet criteria provided in arguments. Each
+ // should_[suppress|stop|notify] flag can be None - no filtering by this
+ // flag true - only signals that have it set to true are returned false -
+ // only signals that have it set to true are returned
+ std::vector<int32_t> GetFilteredSignals(llvm::Optional<bool> should_suppress,
+ llvm::Optional<bool> should_stop,
+ llvm::Optional<bool> should_notify);
+
+protected:
+ // Classes that inherit from UnixSignals can see and modify these
+
+ struct Signal {
+ ConstString m_name;
+ ConstString m_alias;
+ std::string m_description;
+ bool m_suppress : 1, m_stop : 1, m_notify : 1;
+
+ Signal(const char *name, bool default_suppress, bool default_stop,
+ bool default_notify, const char *description, const char *alias);
+
+ ~Signal() {}
+ };
+
+ virtual void Reset();
+
+ typedef std::map<int32_t, Signal> collection;
+
+ collection m_signals;
+
+ // This version gets incremented every time something is changing in this
+ // class, including when we call AddSignal from the constructor. So after the
+ // object is constructed m_version is going to be > 0 if it has at least one
+ // signal registered in it.
+ uint64_t m_version = 0;
+
+ // GDBRemote signals need to be copyable.
+ UnixSignals(const UnixSignals &rhs);
+
+ const UnixSignals &operator=(const UnixSignals &rhs) = delete;
+};
+
+} // Namespace lldb
+#endif // lldb_UnixSignals_h_
diff --git a/linux-x64/clang/include/lldb/Target/Unwind.h b/linux-x64/clang/include/lldb/Target/Unwind.h
new file mode 100644
index 0000000..a648e06
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/Unwind.h
@@ -0,0 +1,83 @@
+//===-- Unwind.h ------------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Unwind_h_
+#define liblldb_Unwind_h_
+
+#include <mutex>
+
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+class Unwind {
+protected:
+ // Classes that inherit from Unwind can see and modify these
+ Unwind(Thread &thread) : m_thread(thread), m_unwind_mutex() {}
+
+public:
+ virtual ~Unwind() {}
+
+ void Clear() {
+ std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex);
+ DoClear();
+ }
+
+ uint32_t GetFrameCount() {
+ std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex);
+ return DoGetFrameCount();
+ }
+
+ uint32_t GetFramesUpTo(uint32_t end_idx) {
+ lldb::addr_t cfa;
+ lldb::addr_t pc;
+ uint32_t idx;
+
+ for (idx = 0; idx < end_idx; idx++) {
+ if (!DoGetFrameInfoAtIndex(idx, cfa, pc)) {
+ break;
+ }
+ }
+ return idx;
+ }
+
+ bool GetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
+ lldb::addr_t &pc) {
+ std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex);
+ return DoGetFrameInfoAtIndex(frame_idx, cfa, pc);
+ }
+
+ lldb::RegisterContextSP CreateRegisterContextForFrame(StackFrame *frame) {
+ std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex);
+ return DoCreateRegisterContextForFrame(frame);
+ }
+
+ Thread &GetThread() { return m_thread; }
+
+protected:
+ // Classes that inherit from Unwind can see and modify these
+ virtual void DoClear() = 0;
+
+ virtual uint32_t DoGetFrameCount() = 0;
+
+ virtual bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
+ lldb::addr_t &pc) = 0;
+
+ virtual lldb::RegisterContextSP
+ DoCreateRegisterContextForFrame(StackFrame *frame) = 0;
+
+ Thread &m_thread;
+ std::recursive_mutex m_unwind_mutex;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(Unwind);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Unwind_h_
diff --git a/linux-x64/clang/include/lldb/Target/UnwindAssembly.h b/linux-x64/clang/include/lldb/Target/UnwindAssembly.h
new file mode 100644
index 0000000..a70aef6
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Target/UnwindAssembly.h
@@ -0,0 +1,53 @@
+//===-- UnwindAssembly.h --------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef utility_UnwindAssembly_h_
+#define utility_UnwindAssembly_h_
+
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+class UnwindAssembly : public std::enable_shared_from_this<UnwindAssembly>,
+ public PluginInterface {
+public:
+ static lldb::UnwindAssemblySP FindPlugin(const ArchSpec &arch);
+
+ ~UnwindAssembly() override;
+
+ virtual bool
+ GetNonCallSiteUnwindPlanFromAssembly(AddressRange &func, Thread &thread,
+ UnwindPlan &unwind_plan) = 0;
+
+ virtual bool AugmentUnwindPlanFromCallSite(AddressRange &func, Thread &thread,
+ UnwindPlan &unwind_plan) = 0;
+
+ virtual bool GetFastUnwindPlan(AddressRange &func, Thread &thread,
+ UnwindPlan &unwind_plan) = 0;
+
+ // thread may be NULL in which case we only use the Target (e.g. if this is
+ // called pre-process-launch).
+ virtual bool
+ FirstNonPrologueInsn(AddressRange &func,
+ const lldb_private::ExecutionContext &exe_ctx,
+ Address &first_non_prologue_insn) = 0;
+
+protected:
+ UnwindAssembly(const ArchSpec &arch);
+ ArchSpec m_arch;
+
+private:
+ UnwindAssembly() = delete;
+ DISALLOW_COPY_AND_ASSIGN(UnwindAssembly);
+};
+
+} // namespace lldb_private
+
+#endif // utility_UnwindAssembly_h_