diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2021-06-13 19:31:46 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2021-07-31 18:56:55 +0000 |
commit | af732203b8f7f006927528db5497f5cbc4c4742a (patch) | |
tree | 596f112de3b76118552871dbb6114bb7e3e17f40 /contrib/llvm-project/lldb/include/lldb | |
parent | 83dea422ac8d4a8323e64203c2eadaa813768717 (diff) | |
download | src-af732203b8f7f006927528db5497f5cbc4c4742a.tar.gz src-af732203b8f7f006927528db5497f5cbc4c4742a.zip |
Merge llvm-project 12.0.1 release and follow-up fixes
Merge llvm-project main llvmorg-12-init-17869-g8e464dd76bef
This updates llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and
openmp to llvmorg-12-init-17869-g8e464dd76bef, the last commit before the
upstream release/12.x branch was created.
PR: 255570
(cherry picked from commit e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
Merge llvm-project 12.0.0 release
This updates llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and
openmp to llvmorg-12.0.0-0-gd28af7c654d8, a.k.a. 12.0.0 release.
PR: 255570
(cherry picked from commit d409305fa3838fb39b38c26fc085fb729b8766d5)
Disable strict-fp for powerpcspe, as it does not work properly yet
Merge commit 5c18d1136665 from llvm git (by Qiu Chaofan)
[SPE] Disable strict-fp for SPE by default
As discussed in PR50385, strict-fp on PowerPC SPE has not been
handled well. This patch disables it by default for SPE.
Reviewed By: nemanjai, vit9696, jhibbits
Differential Revision: https://reviews.llvm.org/D103235
PR: 255570
(cherry picked from commit 715df83abc049b23d9acddc81f2480bd4c056d64)
Apply upstream libc++ fix to allow building with devel/xxx-xtoolchain-gcc
Merge commit 52e9d80d5db2 from llvm git (by Jason Liu):
[libc++] add `inline` for __open's definition in ifstream and ofstream
Summary:
When building with gcc on AIX, it seems that gcc does not like the
`always_inline` without the `inline` keyword.
So adding the inline keywords in for __open in ifstream and ofstream.
That will also make it consistent with __open in basic_filebuf
(it seems we added `inline` there before for gcc build as well).
Differential Revision: https://reviews.llvm.org/D99422
PR: 255570
(cherry picked from commit d099db25464b826c5724cf2fb5b22292bbe15f6e)
Undefine HAVE_(DE)REGISTER_FRAME in llvm's config.h on arm
Otherwise, the lli tool (enable by WITH_CLANG_EXTRAS) won't link on arm,
stating that __register_frame is undefined. This function is normally
provided by libunwind, but explicitly not for the ARM Exception ABI.
Reported by: oh
PR: 255570
(cherry picked from commit f336b45e943c7f9a90ffcea1a6c4c7039e54c73c)
Merge llvm-project 12.0.1 rc2
This updates llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and
openmp to llvmorg-12.0.1-rc2-0-ge7dac564cd0e, a.k.a. 12.0.1 rc2.
PR: 255570
(cherry picked from commit 23408297fbf3089f0388a8873b02fa75ab3f5bb9)
Revert libunwind change to fix backtrace segfault on aarch64
Revert commit 22b615a96593 from llvm git (by Daniel Kiss):
[libunwind] Support for leaf function unwinding.
Unwinding leaf function is useful in cases when the backtrace finds a
leaf function for example when it caused a signal.
This patch also add the support for the DW_CFA_undefined because it marks
the end of the frames.
Ryan Prichard provided code for the tests.
Reviewed By: #libunwind, mstorsjo
Differential Revision: https://reviews.llvm.org/D83573
Reland with limit the test to the x86_64-linux target.
Bisection has shown that this particular upstream commit causes programs
using backtrace(3) on aarch64 to segfault. This affects the lang/rust
port, for instance. Until we can upstream to fix this problem, revert
the commit for now.
Reported by: mikael
PR: 256864
(cherry picked from commit 5866c369e4fd917c0d456f0f10b92ee354b82279)
Merge llvm-project 12.0.1 release
This updates llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and
openmp to llvmorg-12.0.1-0-gfed41342a82f, a.k.a. 12.0.1 release.
PR: 255570
(cherry picked from commit 4652422eb477731f284b1345afeefef7f269da50)
compilert-rt: build out-of-line LSE atomics helpers for aarch64
Both clang >= 12 and gcc >= 10.1 now default to -moutline-atomics for
aarch64. This requires a bunch of helper functions in libcompiler_rt.a,
to avoid link errors like "undefined symbol: __aarch64_ldadd8_acq_rel".
(Note: of course you can use -mno-outline-atomics as a workaround too,
but this would negate the potential performance benefit of the faster
LSE instructions.)
Bump __FreeBSD_version so ports maintainers can easily detect this.
PR: 257392
(cherry picked from commit cc55ee8009a550810d38777fd6ace9abf3a2f6b4)
Diffstat (limited to 'contrib/llvm-project/lldb/include/lldb')
150 files changed, 2867 insertions, 1745 deletions
diff --git a/contrib/llvm-project/lldb/include/lldb/API/LLDB.h b/contrib/llvm-project/lldb/include/lldb/API/LLDB.h index 83c38d3b6166..f7390cfabf01 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/LLDB.h +++ b/contrib/llvm-project/lldb/include/lldb/API/LLDB.h @@ -17,6 +17,7 @@ #include "lldb/API/SBBreakpointName.h" #include "lldb/API/SBBroadcaster.h" #include "lldb/API/SBCommandInterpreter.h" +#include "lldb/API/SBCommandInterpreterRunOptions.h" #include "lldb/API/SBCommandReturnObject.h" #include "lldb/API/SBCommunication.h" #include "lldb/API/SBCompileUnit.h" diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBAddress.h b/contrib/llvm-project/lldb/include/lldb/API/SBAddress.h index cf7555dc2ee8..5a792a24cf6e 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBAddress.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBAddress.h @@ -115,9 +115,9 @@ protected: const lldb_private::Address &ref() const; - SBAddress(const lldb_private::Address *lldb_object_ptr); + SBAddress(const lldb_private::Address &address); - void SetAddress(const lldb_private::Address *lldb_object_ptr); + void SetAddress(const lldb_private::Address &address); private: std::unique_ptr<lldb_private::Address> m_opaque_up; diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBBreakpoint.h b/contrib/llvm-project/lldb/include/lldb/API/SBBreakpoint.h index c9a52fcacf1a..e13dbc5c3516 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBBreakpoint.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBBreakpoint.h @@ -42,6 +42,8 @@ public: void ClearAllBreakpointSites(); + lldb::SBTarget GetTarget() const; + lldb::SBBreakpointLocation FindLocationByAddress(lldb::addr_t vm_addr); lldb::break_id_t FindLocationIDByAddress(lldb::addr_t vm_addr); @@ -140,7 +142,9 @@ public: // Can only be called from a ScriptedBreakpointResolver... SBError AddLocation(SBAddress &address); - + + SBStructuredData SerializeToStructuredData(); + private: friend class SBBreakpointList; friend class SBBreakpointLocation; diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBCommandInterpreter.h b/contrib/llvm-project/lldb/include/lldb/API/SBCommandInterpreter.h index a70e060bec99..2364a8dae88c 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBCommandInterpreter.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBCommandInterpreter.h @@ -146,6 +146,8 @@ public: const char *auto_repeat_command); void SourceInitFileInHomeDirectory(lldb::SBCommandReturnObject &result); + void SourceInitFileInHomeDirectory(lldb::SBCommandReturnObject &result, + bool is_repl); void SourceInitFileInCurrentWorkingDirectory(lldb::SBCommandReturnObject &result); diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBCommandInterpreterRunOptions.h b/contrib/llvm-project/lldb/include/lldb/API/SBCommandInterpreterRunOptions.h index 82d6feedc02e..3c00513faaa7 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBCommandInterpreterRunOptions.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBCommandInterpreterRunOptions.h @@ -26,8 +26,12 @@ class LLDB_API SBCommandInterpreterRunOptions { public: SBCommandInterpreterRunOptions(); + SBCommandInterpreterRunOptions(const SBCommandInterpreterRunOptions &rhs); ~SBCommandInterpreterRunOptions(); + SBCommandInterpreterRunOptions & + operator=(const SBCommandInterpreterRunOptions &rhs); + bool GetStopOnContinue() const; void SetStopOnContinue(bool); diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBModule.h b/contrib/llvm-project/lldb/include/lldb/API/SBModule.h index 859eaffe89a0..dd783fe4107d 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBModule.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBModule.h @@ -291,12 +291,16 @@ public: /// Get the number of global modules. static uint32_t GetNumberAllocatedModules(); + /// Remove any global modules which are no longer needed. + static void GarbageCollectAllocatedModules(); + private: friend class SBAddress; friend class SBFrame; friend class SBSection; friend class SBSymbolContext; friend class SBTarget; + friend class SBType; explicit SBModule(const lldb::ModuleSP &module_sp); diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBPlatform.h b/contrib/llvm-project/lldb/include/lldb/API/SBPlatform.h index 4d251b129954..98291f18247d 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBPlatform.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBPlatform.h @@ -51,6 +51,7 @@ protected: class LLDB_API SBPlatformShellCommand { public: + SBPlatformShellCommand(const char *shell, const char *shell_command); SBPlatformShellCommand(const char *shell_command); SBPlatformShellCommand(const SBPlatformShellCommand &rhs); @@ -61,6 +62,10 @@ public: void Clear(); + const char *GetShell(); + + void SetShell(const char *shell); + const char *GetCommand(); void SetCommand(const char *shell_command); diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBReproducer.h b/contrib/llvm-project/lldb/include/lldb/API/SBReproducer.h index 78044e9acbc3..ecf28d6f0e11 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBReproducer.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBReproducer.h @@ -11,8 +11,32 @@ #include "lldb/API/SBDefines.h" +namespace lldb_private { +namespace repro { +struct ReplayOptions; +} +} // namespace lldb_private + namespace lldb { +class LLDB_API SBReplayOptions { +public: + SBReplayOptions(); + SBReplayOptions(const SBReplayOptions &rhs); + ~SBReplayOptions(); + + SBReplayOptions &operator=(const SBReplayOptions &rhs); + + void SetVerify(bool verify); + bool GetVerify() const; + + void SetCheckVersion(bool check); + bool GetCheckVersion() const; + +private: + std::unique_ptr<lldb_private::repro::ReplayOptions> m_opaque_up; +}; + /// The SBReproducer class is special because it bootstraps the capture and /// replay of SB API calls. As a result we cannot rely on any other SB objects /// in the interface or implementation of this class. @@ -22,7 +46,9 @@ public: static const char *Capture(const char *path); static const char *Replay(const char *path); static const char *Replay(const char *path, bool skip_version_check); + static const char *Replay(const char *path, const SBReplayOptions &options); static const char *PassiveReplay(const char *path); + static const char *Finalize(const char *path); static const char *GetPath(); static bool SetAutoGenerate(bool b); static bool Generate(); diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBTarget.h b/contrib/llvm-project/lldb/include/lldb/API/SBTarget.h index fad842c9cb1c..30f4005dfc0f 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBTarget.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBTarget.h @@ -560,6 +560,12 @@ public: uint32_t column, lldb::addr_t offset, SBFileSpecList &module_list); + lldb::SBBreakpoint + BreakpointCreateByLocation(const lldb::SBFileSpec &file_spec, uint32_t line, + uint32_t column, lldb::addr_t offset, + SBFileSpecList &module_list, + bool move_to_nearest_code); + lldb::SBBreakpoint BreakpointCreateByName(const char *symbol_name, const char *module_name = nullptr); diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBThreadPlan.h b/contrib/llvm-project/lldb/include/lldb/API/SBThreadPlan.h index 8f16f4f5c4d2..0dc48437a668 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBThreadPlan.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBThreadPlan.h @@ -77,6 +77,10 @@ public: bool IsValid(); + bool GetStopOthers(); + + void SetStopOthers(bool stop_others); + // This section allows an SBThreadPlan to push another of the common types of // plans... SBThreadPlan QueueThreadPlanForStepOverRange(SBAddress &start_address, @@ -117,10 +121,11 @@ private: friend class lldb_private::QueueImpl; friend class SBQueueItem; - lldb_private::ThreadPlan *get(); + lldb::ThreadPlanSP GetSP() const { return m_opaque_wp.lock(); } + lldb_private::ThreadPlan *get() const { return GetSP().get(); } void SetThreadPlan(const lldb::ThreadPlanSP &lldb_object_sp); - lldb::ThreadPlanSP m_opaque_sp; + lldb::ThreadPlanWP m_opaque_wp; }; } // namespace lldb diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBType.h b/contrib/llvm-project/lldb/include/lldb/API/SBType.h index b0af43351192..529b4d0eeffc 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBType.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBType.h @@ -131,6 +131,8 @@ public: bool IsAnonymousType(); + bool IsScopedEnumerationType(); + lldb::SBType GetPointerType(); lldb::SBType GetPointeeType(); @@ -150,6 +152,9 @@ public: lldb::SBType GetVectorElementType(); lldb::SBType GetCanonicalType(); + + lldb::SBType GetEnumerationIntegerType(); + // Get the "lldb::BasicType" enumeration for a type. If a type is not a basic // type eBasicTypeInvalid will be returned lldb::BasicType GetBasicType(); @@ -185,6 +190,8 @@ public: lldb::SBTypeMemberFunction GetMemberFunctionAtIndex(uint32_t idx); + lldb::SBModule GetModule(); + const char *GetName(); const char *GetDisplayTypeName(); diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/Breakpoint.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/Breakpoint.h index d29d21070fd7..ddb70b719d6e 100644 --- a/contrib/llvm-project/lldb/include/lldb/Breakpoint/Breakpoint.h +++ b/contrib/llvm-project/lldb/include/lldb/Breakpoint/Breakpoint.h @@ -20,6 +20,7 @@ #include "lldb/Breakpoint/BreakpointName.h" #include "lldb/Breakpoint/BreakpointOptions.h" #include "lldb/Breakpoint/Stoppoint.h" +#include "lldb/Breakpoint/StoppointHitCounter.h" #include "lldb/Core/SearchFilter.h" #include "lldb/Utility/Event.h" #include "lldb/Utility/StringList.h" @@ -544,7 +545,7 @@ public: /// if the condition says to stop and false otherwise. /// void SetPrecondition(lldb::BreakpointPreconditionSP precondition_sp) { - m_precondition_sp = precondition_sp; + m_precondition_sp = std::move(precondition_sp); } bool EvaluatePrecondition(StoppointCallbackContext &context); @@ -624,13 +625,6 @@ protected: bool IgnoreCountShouldStop(); - void IncrementHitCount() { m_hit_count++; } - - void DecrementHitCount() { - assert(m_hit_count > 0); - m_hit_count--; - } - private: // To call from CopyFromBreakpoint. Breakpoint(Target &new_target, const Breakpoint &bp_to_copy_from); @@ -660,10 +654,12 @@ private: m_locations; // The list of locations currently found for this breakpoint. std::string m_kind_description; bool m_resolve_indirect_symbols; - uint32_t m_hit_count; // Number of times this breakpoint/watchpoint has been - // hit. This is kept - // separately from the locations hit counts, since locations can go away when - // their backing library gets unloaded, and we would lose hit counts. + + /// Number of times this breakpoint has been hit. This is kept separately + /// from the locations hit counts, since locations can go away when their + /// backing library gets unloaded, and we would lose hit counts. + StoppointHitCounter m_hit_counter; + BreakpointName::Permissions m_permissions; void SendBreakpointChangedEvent(lldb::BreakpointEventType eventKind); diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointLocation.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointLocation.h index 3fc571eaa292..4e1c57a40435 100644 --- a/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointLocation.h +++ b/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointLocation.h @@ -13,7 +13,7 @@ #include <mutex> #include "lldb/Breakpoint/BreakpointOptions.h" -#include "lldb/Breakpoint/StoppointLocation.h" +#include "lldb/Breakpoint/StoppointHitCounter.h" #include "lldb/Core/Address.h" #include "lldb/Utility/UserID.h" #include "lldb/lldb-private.h" @@ -35,15 +35,14 @@ namespace lldb_private { /// be useful if you've set options on the locations. class BreakpointLocation - : public std::enable_shared_from_this<BreakpointLocation>, - public StoppointLocation { + : public std::enable_shared_from_this<BreakpointLocation> { public: - ~BreakpointLocation() override; + ~BreakpointLocation(); /// Gets the load address for this breakpoint location \return /// Returns breakpoint location load address, \b /// LLDB_INVALID_ADDRESS if not yet set. - lldb::addr_t GetLoadAddress() const override; + lldb::addr_t GetLoadAddress() const; /// Gets the Address for this breakpoint location \return /// Returns breakpoint location Address. @@ -63,7 +62,7 @@ public: /// \return /// \b true if this breakpoint location thinks we should stop, /// \b false otherwise. - bool ShouldStop(StoppointCallbackContext *context) override; + bool ShouldStop(StoppointCallbackContext *context); // The next section deals with various breakpoint options. @@ -85,11 +84,14 @@ public: /// \b true if the breakpoint is set to auto-continue, \b false if not. bool IsAutoContinue() const; + /// Return the current Hit Count. + uint32_t GetHitCount() const { return m_hit_counter.GetValue(); } + /// Return the current Ignore Count. /// /// \return /// The number of breakpoint hits to be ignored. - uint32_t GetIgnoreCount(); + uint32_t GetIgnoreCount() const; /// Set the breakpoint to ignore the next \a count breakpoint hits. /// @@ -192,7 +194,7 @@ public: void GetDescription(Stream *s, lldb::DescriptionLevel level); /// Standard "Dump" method. At present it does nothing. - void Dump(Stream *s) const override; + void Dump(Stream *s) const; /// Use this to set location specific breakpoint options. /// @@ -268,6 +270,9 @@ public: /// \b true or \b false as given in the description above. bool EquivalentToLocation(BreakpointLocation &location); + /// Returns the breakpoint location ID. + lldb::break_id_t GetID() const { return m_loc_id; } + protected: friend class BreakpointSite; friend class BreakpointLocationList; @@ -338,6 +343,9 @@ private: /// multiple processes. size_t m_condition_hash; ///< For testing whether the condition source code ///changed. + lldb::break_id_t m_loc_id; ///< Breakpoint location ID. + StoppointHitCounter m_hit_counter; ///< Number of times this breakpoint + /// location has been hit. void SetShouldResolveIndirectFunctions(bool do_resolve) { m_should_resolve_indirect_functions = do_resolve; diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointOptions.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointOptions.h index 615b4eb77be4..85b8e025a8e5 100644 --- a/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointOptions.h +++ b/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointOptions.h @@ -51,7 +51,7 @@ public: : user_source(user_source), script_source(), interpreter(interp), stop_on_error(true) {} - ~CommandData() = default; + virtual ~CommandData() = default; static const char *GetSerializationKey() { return "BKPTCMDData"; } diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointSite.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointSite.h index 5ce17f511db4..fc32c04ffe35 100644 --- a/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointSite.h +++ b/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointSite.h @@ -14,7 +14,8 @@ #include "lldb/Breakpoint/BreakpointLocationCollection.h" -#include "lldb/Breakpoint/StoppointLocation.h" +#include "lldb/Breakpoint/StoppointSite.h" +#include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/UserID.h" #include "lldb/lldb-forward.h" @@ -32,7 +33,7 @@ namespace lldb_private { /// by the process. class BreakpointSite : public std::enable_shared_from_this<BreakpointSite>, - public StoppointLocation { + public StoppointSite { public: enum Type { eSoftware, // Breakpoint opcode has been written to memory and @@ -60,8 +61,6 @@ public: /// Sets the trap opcode bool SetTrapOpcode(const uint8_t *trap_opcode, uint32_t trap_opcode_size); - void SetHardwareIndex(uint32_t index) override; - /// Gets the original instruction bytes that were overwritten by the trap uint8_t *GetSavedOpcodeBytes(); @@ -184,6 +183,12 @@ public: /// \b false otherwise. bool IsInternal() const; + bool IsHardware() const override { + lldbassert(BreakpointSite::Type::eHardware == GetType() || + !HardwareRequired()); + return BreakpointSite::Type::eHardware == GetType(); + } + BreakpointSite::Type GetType() const { return m_type; } void SetType(BreakpointSite::Type type) { m_type = type; } diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/StoppointHitCounter.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/StoppointHitCounter.h new file mode 100644 index 000000000000..26f816da6430 --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Breakpoint/StoppointHitCounter.h @@ -0,0 +1,43 @@ +//===-- StoppointHitCounter.h -----------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_BREAKPOINT_STOPPOINT_HIT_COUNTER_H +#define LLDB_BREAKPOINT_STOPPOINT_HIT_COUNTER_H + +#include <assert.h> +#include <cstdint> +#include <limits> + +#include "lldb/Utility/LLDBAssert.h" + +namespace lldb_private { + +class StoppointHitCounter { +public: + uint32_t GetValue() const { return m_hit_count; } + + void Increment(uint32_t difference = 1) { + lldbassert(std::numeric_limits<uint32_t>::max() - m_hit_count >= difference); + m_hit_count += difference; + } + + void Decrement(uint32_t difference = 1) { + lldbassert(m_hit_count >= difference); + m_hit_count -= difference; + } + + void Reset() { m_hit_count = 0; } + +private: + /// Number of times this breakpoint/watchpoint has been hit. + uint32_t m_hit_count = 0; +}; + +} // namespace lldb_private + +#endif // LLDB_BREAKPOINT_STOPPOINT_HIT_COUNTER_H diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/StoppointLocation.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/StoppointLocation.h deleted file mode 100644 index 4d6ca044ccc4..000000000000 --- a/contrib/llvm-project/lldb/include/lldb/Breakpoint/StoppointLocation.h +++ /dev/null @@ -1,87 +0,0 @@ -//===-- StoppointLocation.h -------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_BREAKPOINT_STOPPOINTLOCATION_H -#define LLDB_BREAKPOINT_STOPPOINTLOCATION_H - -#include "lldb/Utility/UserID.h" -#include "lldb/lldb-private.h" -// #include "lldb/Breakpoint/BreakpointOptions.h" - -namespace lldb_private { - -class StoppointLocation { -public: - // Constructors and Destructors - StoppointLocation(lldb::break_id_t bid, lldb::addr_t m_addr, bool hardware); - - StoppointLocation(lldb::break_id_t bid, lldb::addr_t m_addr, - uint32_t byte_size, bool hardware); - - virtual ~StoppointLocation(); - - // Operators - - // Methods - virtual lldb::addr_t GetLoadAddress() const { return m_addr; } - - virtual void SetLoadAddress(lldb::addr_t addr) { m_addr = addr; } - - uint32_t GetByteSize() const { return m_byte_size; } - - uint32_t GetHitCount() const { return m_hit_count; } - - uint32_t GetHardwareIndex() const { return m_hardware_index; } - - bool HardwareRequired() const { return m_hardware; } - - virtual bool IsHardware() const { - return m_hardware_index != LLDB_INVALID_INDEX32; - } - - virtual bool ShouldStop(StoppointCallbackContext *context) { return true; } - - virtual void Dump(Stream *stream) const {} - - virtual void SetHardwareIndex(uint32_t index) { m_hardware_index = index; } - - lldb::break_id_t GetID() const { return m_loc_id; } - -protected: - // Classes that inherit from StoppointLocation can see and modify these - lldb::break_id_t m_loc_id; // Stoppoint location ID - lldb::addr_t - m_addr; // The load address of this stop point. The base Stoppoint doesn't - // store a full Address since that's not needed for the breakpoint sites. - bool m_hardware; // True if this point has been is required to use hardware - // (which may fail due to lack of resources) - uint32_t m_hardware_index; // The hardware resource index for this - // breakpoint/watchpoint - uint32_t m_byte_size; // The size in bytes of stop location. e.g. the length - // of the trap opcode for - // software breakpoints, or the optional length in bytes for hardware - // breakpoints, or the length of the watchpoint. - uint32_t - m_hit_count; // Number of times this breakpoint/watchpoint has been hit - - // If you override this, be sure to call the base class to increment the - // internal counter. - void IncrementHitCount() { ++m_hit_count; } - - void DecrementHitCount(); - -private: - // For StoppointLocation only - StoppointLocation(const StoppointLocation &) = delete; - const StoppointLocation &operator=(const StoppointLocation &) = delete; - StoppointLocation() = delete; -}; - -} // namespace lldb_private - -#endif // LLDB_BREAKPOINT_STOPPOINTLOCATION_H diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/StoppointSite.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/StoppointSite.h new file mode 100644 index 000000000000..7e5e33486345 --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Breakpoint/StoppointSite.h @@ -0,0 +1,81 @@ +//===-- StoppointSite.h -----------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_BREAKPOINT_STOPPOINTSITE_H +#define LLDB_BREAKPOINT_STOPPOINTSITE_H + +#include "lldb/Breakpoint/StoppointHitCounter.h" +#include "lldb/Utility/UserID.h" +#include "lldb/lldb-private.h" + +namespace lldb_private { + +class StoppointSite { +public: + StoppointSite(lldb::break_id_t bid, lldb::addr_t m_addr, bool hardware); + + StoppointSite(lldb::break_id_t bid, lldb::addr_t m_addr, + uint32_t byte_size, bool hardware); + + virtual ~StoppointSite() = default; + + virtual lldb::addr_t GetLoadAddress() const { return m_addr; } + + virtual void SetLoadAddress(lldb::addr_t addr) { m_addr = addr; } + + uint32_t GetByteSize() const { return m_byte_size; } + + uint32_t GetHitCount() const { return m_hit_counter.GetValue(); } + + void ResetHitCount() { m_hit_counter.Reset(); } + + bool HardwareRequired() const { return m_is_hardware_required; } + + virtual bool IsHardware() const = 0; + + uint32_t GetHardwareIndex() const { return m_hardware_index; } + + void SetHardwareIndex(uint32_t index) { m_hardware_index = index; } + + virtual bool ShouldStop(StoppointCallbackContext* context) = 0; + + virtual void Dump(Stream* stream) const = 0; + + lldb::break_id_t GetID() const { return m_id; } + +protected: + /// Stoppoint site ID. + lldb::break_id_t m_id; + + /// The load address of this stop point. + lldb::addr_t m_addr; + + /// True if this point is required to use hardware (which may fail due to + /// the lack of resources). + bool m_is_hardware_required; + + /// The hardware resource index for this breakpoint/watchpoint. + uint32_t m_hardware_index; + + /// The size in bytes of stoppoint, e.g. the length of the trap opcode for + /// software breakpoints, or the optional length in bytes for hardware + /// breakpoints, or the length of the watchpoint. + uint32_t m_byte_size; + + /// Number of times this breakpoint/watchpoint has been hit. + StoppointHitCounter m_hit_counter; + +private: + StoppointSite(const StoppointSite &) = delete; + const StoppointSite &operator=(const StoppointSite &) = delete; + StoppointSite() = delete; +}; + +} // namespace lldb_private + +#endif // LLDB_BREAKPOINT_STOPPOINTSITE_H diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/Watchpoint.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/Watchpoint.h index bce15f0a85dd..41b723a66b6a 100644 --- a/contrib/llvm-project/lldb/include/lldb/Breakpoint/Watchpoint.h +++ b/contrib/llvm-project/lldb/include/lldb/Breakpoint/Watchpoint.h @@ -12,7 +12,7 @@ #include <memory> #include <string> -#include "lldb/Breakpoint/StoppointLocation.h" +#include "lldb/Breakpoint/StoppointSite.h" #include "lldb/Breakpoint/WatchpointOptions.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Target/Target.h" @@ -22,7 +22,7 @@ namespace lldb_private { class Watchpoint : public std::enable_shared_from_this<Watchpoint>, - public StoppointLocation { + public StoppointSite { public: class WatchpointEventData : public EventData { public: @@ -158,8 +158,6 @@ private: friend class Target; friend class WatchpointList; - void ResetHitCount() { m_hit_count = 0; } - void ResetHistoricValues() { m_old_value_sp.reset(); m_new_value_sp.reset(); @@ -199,7 +197,7 @@ private: std::unique_ptr<UserExpression> m_condition_up; // The condition to test. - void SetID(lldb::watch_id_t id) { m_loc_id = id; } + void SetID(lldb::watch_id_t id) { m_id = id; } void SendWatchpointChangedEvent(lldb::WatchpointEventType eventKind); diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Architecture.h b/contrib/llvm-project/lldb/include/lldb/Core/Architecture.h index d8dbbb4f540f..2ea8bd31ebf4 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/Architecture.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/Architecture.h @@ -15,9 +15,6 @@ namespace lldb_private { class Architecture : public PluginInterface { public: - Architecture() = default; - ~Architecture() override = default; - /// This is currently intended to handle cases where a /// program stops at an instruction that won't get executed and it /// allows the stop reason, like "breakpoint hit", to be replaced @@ -100,10 +97,6 @@ public: Target &target) const { return addr; } - -private: - Architecture(const Architecture &) = delete; - void operator=(const Architecture &) = delete; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Communication.h b/contrib/llvm-project/lldb/include/lldb/Core/Communication.h index 6b65974f9522..354c4bbcc283 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/Communication.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/Communication.h @@ -285,7 +285,7 @@ public: /// void SynchronizeWithReadThread(); - static const char *ConnectionStatusAsCString(lldb::ConnectionStatus status); + static std::string ConnectionStatusAsString(lldb::ConnectionStatus status); bool GetCloseOnEOF() const { return m_close_on_eof; } diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Debugger.h b/contrib/llvm-project/lldb/include/lldb/Core/Debugger.h index 7bea0dbae082..68daae1a3710 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/Debugger.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/Debugger.h @@ -273,6 +273,8 @@ public: bool SetUseColor(bool use_color); + bool GetUseAutosuggestion() const; + bool GetUseSourceCache() const; bool SetUseSourceCache(bool use_source_cache); @@ -332,8 +334,8 @@ public: // This is for use in the command interpreter, when you either want the // selected target, or if no target is present you want to prime the dummy // target with entities that will be copied over to new targets. - Target *GetSelectedOrDummyTarget(bool prefer_dummy = false); - Target *GetDummyTarget() { return m_dummy_target_sp.get(); } + Target &GetSelectedOrDummyTarget(bool prefer_dummy = false); + Target &GetDummyTarget() { return *m_dummy_target_sp; } lldb::BroadcasterManagerSP GetBroadcasterManager() { return m_broadcaster_manager_sp; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Disassembler.h b/contrib/llvm-project/lldb/include/lldb/Core/Disassembler.h index 926a74b933ef..9a694de0f60a 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/Disassembler.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/Disassembler.h @@ -48,6 +48,7 @@ class DataExtractor; class Debugger; class Disassembler; class Module; +class StackFrame; class Stream; class SymbolContext; class SymbolContextList; @@ -270,6 +271,13 @@ public: lldb::InstructionSP GetInstructionAtIndex(size_t idx) const; + /// Get the instruction at the given address. + /// + /// \return + /// A valid \a InstructionSP if the address could be found, or null + /// otherwise. + lldb::InstructionSP GetInstructionAtAddress(const Address &addr); + //------------------------------------------------------------------ /// Get the index of the next branch instruction. /// @@ -279,9 +287,6 @@ public: /// @param[in] start /// The instruction index of the first instruction to check. /// - /// @param[in] target - /// A LLDB target object that is used to resolve addresses. - /// /// @param[in] ignore_calls /// It true, then fine the first branch instruction that isn't /// a function call (a branch that calls and returns to the next @@ -298,7 +303,6 @@ public: /// found. //------------------------------------------------------------------ uint32_t GetIndexOfNextBranchInstruction(uint32_t start, - Target &target, bool ignore_calls, bool *found_calls) const; @@ -408,11 +412,8 @@ public: uint32_t num_mixed_context_lines, uint32_t options, Stream &strm); - static bool - Disassemble(Debugger &debugger, const ArchSpec &arch, const char *plugin_name, - const char *flavor, const ExecutionContext &exe_ctx, - uint32_t num_instructions, bool mixed_source_and_assembly, - uint32_t num_mixed_context_lines, uint32_t options, Stream &strm); + static bool Disassemble(Debugger &debugger, const ArchSpec &arch, + StackFrame &frame, Stream &strm); // Constructors and Destructors Disassembler(const ArchSpec &arch, const char *flavor); diff --git a/contrib/llvm-project/lldb/include/lldb/Core/IOHandler.h b/contrib/llvm-project/lldb/include/lldb/Core/IOHandler.h index 51592afbbabe..2e8f3225fd5f 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/IOHandler.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/IOHandler.h @@ -15,7 +15,6 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Flags.h" #include "lldb/Utility/Predicate.h" -#include "lldb/Utility/Reproducer.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StringList.h" #include "lldb/lldb-defines.h" @@ -32,6 +31,9 @@ namespace lldb_private { class Debugger; +namespace repro { +class DataRecorder; +} } namespace curses { @@ -126,11 +128,11 @@ public: FILE *GetErrorFILE(); - lldb::FileSP &GetInputFileSP(); + lldb::FileSP GetInputFileSP(); - lldb::StreamFileSP &GetOutputStreamFileSP(); + lldb::StreamFileSP GetOutputStreamFileSP(); - lldb::StreamFileSP &GetErrorStreamFileSP(); + lldb::StreamFileSP GetErrorStreamFileSP(); Debugger &GetDebugger() { return m_debugger; } @@ -203,6 +205,9 @@ public: virtual void IOHandlerDeactivated(IOHandler &io_handler) {} + virtual llvm::Optional<std::string> IOHandlerSuggestion(IOHandler &io_handler, + llvm::StringRef line); + virtual void IOHandlerComplete(IOHandler &io_handler, CompletionRequest &request); @@ -420,6 +425,9 @@ private: static int FixIndentationCallback(Editline *editline, const StringList &lines, int cursor_position, void *baton); + static llvm::Optional<std::string> SuggestionCallback(llvm::StringRef line, + void *baton); + static void AutoCompleteCallback(CompletionRequest &request, void *baton); #endif diff --git a/contrib/llvm-project/lldb/include/lldb/Core/IOHandlerCursesGUI.h b/contrib/llvm-project/lldb/include/lldb/Core/IOHandlerCursesGUI.h index fe62eaea643e..22ca735063ba 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/IOHandlerCursesGUI.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/IOHandlerCursesGUI.h @@ -31,6 +31,8 @@ public: void Deactivate() override; + void TerminalSizeChanged() override; + protected: curses::ApplicationAP m_app_ap; }; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Module.h b/contrib/llvm-project/lldb/include/lldb/Core/Module.h index 8bd70ab16b5a..9eb7477730c1 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/Module.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/Module.h @@ -506,10 +506,6 @@ public: return m_object_mod_time; } - void SetObjectModificationTime(const llvm::sys::TimePoint<> &mod_time) { - m_mod_time = mod_time; - } - /// This callback will be called by SymbolFile implementations when /// parsing a compile unit that contains SDK information. /// \param sysroot will be added to the path remapping dictionary. diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ModuleList.h b/contrib/llvm-project/lldb/include/lldb/Core/ModuleList.h index d90b27e474ac..46a718f08f04 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ModuleList.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ModuleList.h @@ -56,7 +56,7 @@ public: ModuleListProperties(); FileSpec GetClangModulesCachePath() const; - bool SetClangModulesCachePath(llvm::StringRef path); + bool SetClangModulesCachePath(const FileSpec &path); bool GetEnableExternalLookup() const; bool SetEnableExternalLookup(bool new_value); @@ -237,20 +237,6 @@ public: /// \see ModuleList::GetSize() Module *GetModulePointerAtIndex(size_t idx) const; - /// Get the module pointer for the module at index \a idx without acquiring - /// the ModuleList mutex. This MUST already have been acquired with - /// ModuleList::GetMutex and locked for this call to be safe. - /// - /// \param[in] idx - /// An index into this module collection. - /// - /// \return - /// A pointer to a Module which can by nullptr if \a idx is out - /// of range. - /// - /// \see ModuleList::GetSize() - Module *GetModulePointerAtIndexUnlocked(size_t idx) const; - /// Find compile units by partial or full path. /// /// Finds all compile units that match \a path in all of the modules and @@ -491,11 +477,13 @@ public: typedef LockingAdaptedIterable<collection, lldb::ModuleSP, vector_adapter, std::recursive_mutex> ModuleIterable; - ModuleIterable Modules() { return ModuleIterable(m_modules, GetMutex()); } + ModuleIterable Modules() const { + return ModuleIterable(m_modules, GetMutex()); + } typedef AdaptedIterable<collection, lldb::ModuleSP, vector_adapter> ModuleIterableNoLocking; - ModuleIterableNoLocking ModulesNoLocking() { + ModuleIterableNoLocking ModulesNoLocking() const { return ModuleIterableNoLocking(m_modules); } }; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/PluginInterface.h b/contrib/llvm-project/lldb/include/lldb/Core/PluginInterface.h index 17f6dc367155..5bdb2f45b665 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/PluginInterface.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/PluginInterface.h @@ -15,11 +15,15 @@ namespace lldb_private { class PluginInterface { public: - virtual ~PluginInterface() {} + PluginInterface() = default; + virtual ~PluginInterface() = default; virtual ConstString GetPluginName() = 0; virtual uint32_t GetPluginVersion() = 0; + + PluginInterface(const PluginInterface &) = delete; + PluginInterface &operator=(const PluginInterface &) = delete; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Core/PluginManager.h b/contrib/llvm-project/lldb/include/lldb/Core/PluginManager.h index 5e0c9395dae0..0ac8308d1758 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/PluginManager.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/PluginManager.h @@ -330,6 +330,42 @@ public: static SymbolVendorCreateInstance GetSymbolVendorCreateCallbackAtIndex(uint32_t idx); + // Trace + static bool RegisterPlugin(ConstString name, const char *description, + TraceCreateInstance create_callback, + llvm::StringRef schema, + TraceGetStartCommand get_start_command); + + static bool UnregisterPlugin(TraceCreateInstance create_callback); + + static TraceCreateInstance GetTraceCreateCallback(ConstString plugin_name); + + static lldb::CommandObjectSP + GetTraceStartCommand(llvm::StringRef plugin_name, + CommandInterpreter &interpreter); + + /// Get the JSON schema for a trace session file corresponding to the given + /// plugin. + /// + /// \param[in] plugin_name + /// The name of the plugin. + /// + /// \return + /// An empty \a StringRef if no plugin was found with that plugin name, + /// otherwise the actual schema is returned. + static llvm::StringRef GetTraceSchema(ConstString plugin_name); + + /// Get the JSON schema for a trace session file corresponding to the plugin + /// given by its index. + /// + /// \param[in] index + /// The index of the plugin to get the schema of. + /// + /// \return + /// An empty \a StringRef if the index is greater than or equal to the + /// number plugins, otherwise the actual schema is returned. + static llvm::StringRef GetTraceSchema(size_t index); + // UnwindAssembly static bool RegisterPlugin(ConstString name, const char *description, UnwindAssemblyCreateInstance create_callback); diff --git a/contrib/llvm-project/lldb/include/lldb/Core/StructuredDataImpl.h b/contrib/llvm-project/lldb/include/lldb/Core/StructuredDataImpl.h index 9aea645a3ea6..929ce21fb2f9 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/StructuredDataImpl.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/StructuredDataImpl.h @@ -68,14 +68,18 @@ public: return error; } - // Grab the plugin. - auto plugin_sp = lldb::StructuredDataPluginSP(m_plugin_wp); + // Grab the plugin + lldb::StructuredDataPluginSP plugin_sp = m_plugin_wp.lock(); + + // If there's no plugin, call underlying data's dump method: if (!plugin_sp) { - error.SetErrorString("Cannot pretty print structured data: " - "plugin doesn't exist."); + if (!m_data_sp) { + error.SetErrorString("No data to describe."); + return error; + } + m_data_sp->Dump(stream, true); return error; } - // Get the data's description. return plugin_sp->GetDescription(m_data_sp, stream); } diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Value.h b/contrib/llvm-project/lldb/include/lldb/Core/Value.h index 641a64a3bbbe..0ff773e59911 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/Value.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/Value.h @@ -43,8 +43,6 @@ public: // m_value contains... // ============================ eValueTypeScalar, // raw scalar value - eValueTypeVector, // byte array of m_vector.length with endianness of - // m_vector.byte_order eValueTypeFileAddress, // file address value eValueTypeLoadAddress, // load address value eValueTypeHostAddress // host address value (for memory in the process that @@ -62,66 +60,8 @@ public: eContextTypeVariable // lldb_private::Variable * }; - const static size_t kMaxByteSize = 32u; - - struct Vector { - // The byte array must be big enough to hold vector registers for any - // supported target. - uint8_t bytes[kMaxByteSize]; - size_t length; - lldb::ByteOrder byte_order; - - Vector() : length(0), byte_order(lldb::eByteOrderInvalid) {} - - Vector(const Vector &vector) { *this = vector; } - const Vector &operator=(const Vector &vector) { - SetBytes(vector.bytes, vector.length, vector.byte_order); - return *this; - } - - void Clear() { length = 0; } - - bool SetBytes(const void *bytes, size_t length, - lldb::ByteOrder byte_order) { - this->length = length; - this->byte_order = byte_order; - if (length) - ::memcpy(this->bytes, bytes, - length < kMaxByteSize ? length : kMaxByteSize); - return IsValid(); - } - - bool IsValid() const { - return (length > 0 && length < kMaxByteSize && - byte_order != lldb::eByteOrderInvalid); - } - // Casts a vector, if valid, to an unsigned int of matching or largest - // supported size. Truncates to the beginning of the vector if required. - // Returns a default constructed Scalar if the Vector data is internally - // inconsistent. - llvm::APInt rhs = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, - ((type128 *)bytes)->x); - Scalar GetAsScalar() const { - Scalar scalar; - if (IsValid()) { - if (length == 1) - scalar = *(const uint8_t *)bytes; - else if (length == 2) - scalar = *(const uint16_t *)bytes; - else if (length == 4) - scalar = *(const uint32_t *)bytes; - else if (length == 8) - scalar = *(const uint64_t *)bytes; - else if (length >= 16) - scalar = rhs; - } - return scalar; - } - }; - Value(); Value(const Scalar &scalar); - Value(const Vector &vector); Value(const void *bytes, int len); Value(const Value &rhs); @@ -153,8 +93,7 @@ public: m_context = p; if (m_context_type == eContextTypeRegisterInfo) { RegisterInfo *reg_info = GetRegisterInfo(); - if (reg_info->encoding == lldb::eEncodingVector && - m_vector.byte_order != lldb::eByteOrderInvalid) + if (reg_info->encoding == lldb::eEncodingVector) SetValueType(eValueTypeScalar); } } @@ -167,30 +106,8 @@ public: const Scalar &GetScalar() const { return m_value; } - const Vector &GetVector() const { return m_vector; } - Scalar &GetScalar() { return m_value; } - Vector &GetVector() { return m_vector; } - - bool SetVectorBytes(const Vector &vector) { - m_vector = vector; - return m_vector.IsValid(); - } - - bool SetVectorBytes(uint8_t *bytes, size_t length, - lldb::ByteOrder byte_order) { - return m_vector.SetBytes(bytes, length, byte_order); - } - - bool SetScalarFromVector() { - if (m_vector.IsValid()) { - m_value = m_vector.GetAsScalar(); - return true; - } - return false; - } - size_t ResizeData(size_t len); size_t AppendDataToHostBuffer(const Value &rhs); @@ -225,7 +142,6 @@ public: protected: Scalar m_value; - Vector m_vector; CompilerType m_compiler_type; void *m_context; ValueType m_value_type; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObject.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObject.h index 0080368fd996..a665e7afa0ca 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObject.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObject.h @@ -358,7 +358,7 @@ public: virtual bool CanProvideValue(); // Subclasses must implement the functions below. - virtual uint64_t GetByteSize() = 0; + virtual llvm::Optional<uint64_t> GetByteSize() = 0; virtual lldb::ValueType GetValueType() const = 0; @@ -702,12 +702,12 @@ public: } void SetSummaryFormat(lldb::TypeSummaryImplSP format) { - m_type_summary_sp = format; + m_type_summary_sp = std::move(format); ClearUserVisibleData(eClearUserVisibleDataItemsSummary); } void SetValueFormat(lldb::TypeFormatImplSP format) { - m_type_format_sp = format; + m_type_format_sp = std::move(format); ClearUserVisibleData(eClearUserVisibleDataItemsValue); } diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectCast.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectCast.h index d91ca6a92be8..342803f8ca63 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectCast.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectCast.h @@ -30,7 +30,7 @@ public: ConstString name, const CompilerType &cast_type); - uint64_t GetByteSize() override; + llvm::Optional<uint64_t> GetByteSize() override; size_t CalculateNumChildren(uint32_t max) override; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectChild.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectChild.h index c6f44a29b059..9a9fd9294261 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectChild.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectChild.h @@ -30,7 +30,7 @@ class ValueObjectChild : public ValueObject { public: ~ValueObjectChild() override; - uint64_t GetByteSize() override { return m_byte_size; } + llvm::Optional<uint64_t> GetByteSize() override { return m_byte_size; } lldb::offset_t GetByteOffset() override { return m_byte_offset; } diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResult.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResult.h index 0e868c687e93..8d823baa0b7b 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResult.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResult.h @@ -62,7 +62,7 @@ public: static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, const Status &error); - uint64_t GetByteSize() override; + llvm::Optional<uint64_t> GetByteSize() override; lldb::ValueType GetValueType() const override; @@ -113,7 +113,7 @@ protected: CompilerType GetCompilerTypeImpl() override; ConstString m_type_name; - uint64_t m_byte_size; + llvm::Optional<uint64_t> m_byte_size; ValueObjectConstResultImpl m_impl; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectDynamicValue.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectDynamicValue.h index 9f5304b55e93..2806857339ef 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectDynamicValue.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectDynamicValue.h @@ -34,7 +34,7 @@ class ValueObjectDynamicValue : public ValueObject { public: ~ValueObjectDynamicValue() override; - uint64_t GetByteSize() override; + llvm::Optional<uint64_t> GetByteSize() override; ConstString GetTypeName() override; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectMemory.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectMemory.h index d1cd6ae41445..b5d5e6ecf4c0 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectMemory.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectMemory.h @@ -40,7 +40,7 @@ public: const Address &address, const CompilerType &ast_type); - uint64_t GetByteSize() override; + llvm::Optional<uint64_t> GetByteSize() override; ConstString GetTypeName() override; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectRegister.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectRegister.h index 41051d93b707..3968584ad518 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectRegister.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectRegister.h @@ -36,7 +36,7 @@ public: lldb::RegisterContextSP ®_ctx_sp, uint32_t set_idx); - uint64_t GetByteSize() override; + llvm::Optional<uint64_t> GetByteSize() override; lldb::ValueType GetValueType() const override { return lldb::eValueTypeRegisterSet; @@ -86,7 +86,7 @@ public: lldb::RegisterContextSP ®_ctx_sp, uint32_t reg_num); - uint64_t GetByteSize() override; + llvm::Optional<uint64_t> GetByteSize() override; lldb::ValueType GetValueType() const override { return lldb::eValueTypeRegister; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h index cb471657aec9..41c461ce13f0 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h @@ -36,7 +36,7 @@ class ValueObjectSynthetic : public ValueObject { public: ~ValueObjectSynthetic() override; - uint64_t GetByteSize() override; + llvm::Optional<uint64_t> GetByteSize() override; ConstString GetTypeName() override; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectVariable.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectVariable.h index b7e262574a14..23fdedbf5a4a 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectVariable.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectVariable.h @@ -37,7 +37,7 @@ public: static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, const lldb::VariableSP &var_sp); - uint64_t GetByteSize() override; + llvm::Optional<uint64_t> GetByteSize() override; ConstString GetTypeName() override; diff --git a/contrib/llvm-project/lldb/include/lldb/DataFormatters/DataVisualization.h b/contrib/llvm-project/lldb/include/lldb/DataFormatters/DataVisualization.h index b053aa074d9e..7be07d65acdd 100644 --- a/contrib/llvm-project/lldb/include/lldb/DataFormatters/DataVisualization.h +++ b/contrib/llvm-project/lldb/include/lldb/DataFormatters/DataVisualization.h @@ -69,9 +69,9 @@ public: static void Clear(); - static void - ForEach(std::function<bool(ConstString, const lldb::TypeSummaryImplSP &)> - callback); + static void ForEach(std::function<bool(const TypeMatcher &, + const lldb::TypeSummaryImplSP &)> + callback); static uint32_t GetCount(); }; diff --git a/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormatManager.h b/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormatManager.h index 56a0303f9b02..978ad148d6c4 100644 --- a/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormatManager.h +++ b/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormatManager.h @@ -34,7 +34,7 @@ namespace lldb_private { // this file's objects directly class FormatManager : public IFormatChangeListener { - typedef FormatMap<ConstString, TypeSummaryImpl> NamedSummariesMap; + typedef FormattersContainer<TypeSummaryImpl> NamedSummariesMap; typedef TypeCategoryMap::MapType::iterator CategoryMapIterator; public: @@ -144,13 +144,6 @@ public: static const char *GetFormatAsCString(lldb::Format format); - // if the user tries to add formatters for, say, "struct Foo" those will not - // match any type because of the way we strip qualifiers from typenames this - // method looks for the case where the user is adding a - // "class","struct","enum" or "union" Foo and strips the unnecessary - // qualifier - static ConstString GetValidTypeName(ConstString type); - // when DataExtractor dumps a vectorOfT, it uses a predefined format for each // item this method returns it, or eFormatInvalid if vector_format is not a // vectorOf diff --git a/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormattersContainer.h b/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormattersContainer.h index d414882bae19..2f56218c43a7 100644 --- a/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormattersContainer.h +++ b/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormattersContainer.h @@ -37,57 +37,103 @@ public: virtual uint32_t GetCurrentRevision() = 0; }; -// if the user tries to add formatters for, say, "struct Foo" those will not -// match any type because of the way we strip qualifiers from typenames this -// method looks for the case where the user is adding a "class","struct","enum" -// or "union" Foo and strips the unnecessary qualifier -static inline ConstString GetValidTypeName_Impl(ConstString type) { - if (type.IsEmpty()) - return type; +/// Class for matching type names. +class TypeMatcher { + RegularExpression m_type_name_regex; + ConstString m_type_name; + /// False if m_type_name_regex should be used for matching. False if this is + /// just matching by comparing with m_type_name string. + bool m_is_regex; - std::string type_cstr(type.AsCString()); - StringLexer type_lexer(type_cstr); + // if the user tries to add formatters for, say, "struct Foo" those will not + // match any type because of the way we strip qualifiers from typenames this + // method looks for the case where the user is adding a + // "class","struct","enum" or "union" Foo and strips the unnecessary qualifier + static ConstString StripTypeName(ConstString type) { + if (type.IsEmpty()) + return type; - type_lexer.AdvanceIf("class "); - type_lexer.AdvanceIf("enum "); - type_lexer.AdvanceIf("struct "); - type_lexer.AdvanceIf("union "); + std::string type_cstr(type.AsCString()); + StringLexer type_lexer(type_cstr); - while (type_lexer.NextIf({' ', '\t', '\v', '\f'}).first) - ; + type_lexer.AdvanceIf("class "); + type_lexer.AdvanceIf("enum "); + type_lexer.AdvanceIf("struct "); + type_lexer.AdvanceIf("union "); - return ConstString(type_lexer.GetUnlexed()); -} + while (type_lexer.NextIf({' ', '\t', '\v', '\f'}).first) + ; -template <typename KeyType, typename ValueType> class FormattersContainer; + return ConstString(type_lexer.GetUnlexed()); + } -template <typename KeyType, typename ValueType> class FormatMap { public: - typedef typename ValueType::SharedPointer ValueSP; - typedef std::vector<std::pair<KeyType, ValueSP>> MapType; - typedef typename MapType::iterator MapIterator; - typedef std::function<bool(const KeyType &, const ValueSP &)> ForEachCallback; + TypeMatcher() = delete; + /// Creates a matcher that accepts any type with exactly the given type name. + TypeMatcher(ConstString type_name) + : m_type_name(type_name), m_is_regex(false) {} + /// Creates a matcher that accepts any type matching the given regex. + TypeMatcher(RegularExpression regex) + : m_type_name_regex(std::move(regex)), m_is_regex(true) {} + + /// True iff this matches the given type name. + bool Matches(ConstString type_name) const { + if (m_is_regex) + return m_type_name_regex.Execute(type_name.GetStringRef()); + return m_type_name == type_name || + StripTypeName(m_type_name) == StripTypeName(type_name); + } + + /// Returns the underlying match string for this TypeMatcher. + ConstString GetMatchString() const { + if (m_is_regex) + return ConstString(m_type_name_regex.GetText()); + return StripTypeName(m_type_name); + } + + /// Returns true if this TypeMatcher and the given one were most created by + /// the same match string. + /// The main purpose of this function is to find existing TypeMatcher + /// instances by the user input that created them. This is necessary as LLDB + /// allows referencing existing TypeMatchers in commands by the user input + /// that originally created them: + /// (lldb) type summary add --summary-string \"A\" -x TypeName + /// (lldb) type summary delete TypeName + bool CreatedBySameMatchString(TypeMatcher other) const { + return GetMatchString() == other.GetMatchString(); + } +}; + +template <typename ValueType> class FormattersContainer { +public: + typedef typename std::shared_ptr<ValueType> ValueSP; + typedef std::vector<std::pair<TypeMatcher, ValueSP>> MapType; + typedef std::function<bool(const TypeMatcher &, const ValueSP &)> + ForEachCallback; + typedef typename std::shared_ptr<FormattersContainer<ValueType>> + SharedPointer; + + friend class TypeCategoryImpl; - FormatMap(IFormatChangeListener *lst) - : m_map(), m_map_mutex(), listener(lst) {} + FormattersContainer(IFormatChangeListener *lst) : listener(lst) {} - void Add(KeyType name, const ValueSP &entry) { + void Add(TypeMatcher matcher, const ValueSP &entry) { if (listener) entry->GetRevision() = listener->GetCurrentRevision(); else entry->GetRevision() = 0; std::lock_guard<std::recursive_mutex> guard(m_map_mutex); - Delete(name); - m_map.emplace_back(std::move(name), std::move(entry)); + Delete(matcher); + m_map.emplace_back(std::move(matcher), std::move(entry)); if (listener) listener->Changed(); } - bool Delete(const KeyType &name) { + bool Delete(TypeMatcher matcher) { std::lock_guard<std::recursive_mutex> guard(m_map_mutex); - for (MapIterator iter = m_map.begin(); iter != m_map.end(); ++iter) - if (iter->first == name) { + for (auto iter = m_map.begin(); iter != m_map.end(); ++iter) + if (iter->first.CreatedBySameMatchString(matcher)) { m_map.erase(iter); if (listener) listener->Changed(); @@ -96,217 +142,78 @@ public: return false; } - void Clear() { + bool Get(ConstString type, ValueSP &entry) { std::lock_guard<std::recursive_mutex> guard(m_map_mutex); - m_map.clear(); - if (listener) - listener->Changed(); + for (auto &formatter : llvm::reverse(m_map)) { + if (formatter.first.Matches(type)) { + entry = formatter.second; + return true; + } + } + return false; } - bool Get(const KeyType &name, ValueSP &entry) { + bool GetExact(TypeMatcher matcher, ValueSP &entry) { std::lock_guard<std::recursive_mutex> guard(m_map_mutex); for (const auto &pos : m_map) - if (pos.first == name) { + if (pos.first.CreatedBySameMatchString(matcher)) { entry = pos.second; return true; } return false; } - void ForEach(ForEachCallback callback) { - if (callback) { - std::lock_guard<std::recursive_mutex> guard(m_map_mutex); - for (const auto &pos : m_map) { - const KeyType &type = pos.first; - if (!callback(type, pos.second)) - break; - } - } - } - - uint32_t GetCount() { return m_map.size(); } - - ValueSP GetValueAtIndex(size_t index) { + ValueSP GetAtIndex(size_t index) { std::lock_guard<std::recursive_mutex> guard(m_map_mutex); if (index >= m_map.size()) return ValueSP(); return m_map[index].second; } - // If caller holds the mutex we could return a reference without copy ctor. - KeyType GetKeyAtIndex(size_t index) { + lldb::TypeNameSpecifierImplSP GetTypeNameSpecifierAtIndex(size_t index) { std::lock_guard<std::recursive_mutex> guard(m_map_mutex); if (index >= m_map.size()) - return {}; - return m_map[index].first; - } - -protected: - MapType m_map; - std::recursive_mutex m_map_mutex; - IFormatChangeListener *listener; - - MapType &map() { return m_map; } - - std::recursive_mutex &mutex() { return m_map_mutex; } - - friend class FormattersContainer<KeyType, ValueType>; - friend class FormatManager; -}; - -template <typename KeyType, typename ValueType> class FormattersContainer { -protected: - typedef FormatMap<KeyType, ValueType> BackEndType; - -public: - typedef typename BackEndType::MapType MapType; - typedef typename MapType::iterator MapIterator; - typedef KeyType MapKeyType; - typedef std::shared_ptr<ValueType> MapValueType; - typedef typename BackEndType::ForEachCallback ForEachCallback; - typedef typename std::shared_ptr<FormattersContainer<KeyType, ValueType>> - SharedPointer; - - friend class TypeCategoryImpl; - - FormattersContainer(std::string name, IFormatChangeListener *lst) - : m_format_map(lst), m_name(name) {} - - void Add(MapKeyType type, const MapValueType &entry) { - Add_Impl(std::move(type), entry, static_cast<KeyType *>(nullptr)); - } - - bool Delete(ConstString type) { - return Delete_Impl(type, static_cast<KeyType *>(nullptr)); - } - - bool Get(ValueObject &valobj, MapValueType &entry, - lldb::DynamicValueType use_dynamic) { - CompilerType ast_type(valobj.GetCompilerType()); - bool ret = Get(valobj, ast_type, entry, use_dynamic); - if (ret) - entry = MapValueType(entry); - else - entry = MapValueType(); - return ret; + return lldb::TypeNameSpecifierImplSP(); + TypeMatcher type_matcher = m_map[index].first; + return std::make_shared<TypeNameSpecifierImpl>( + type_matcher.GetMatchString().GetStringRef(), true); } - bool Get(ConstString type, MapValueType &entry) { - return Get_Impl(type, entry, static_cast<KeyType *>(nullptr)); + void Clear() { + std::lock_guard<std::recursive_mutex> guard(m_map_mutex); + m_map.clear(); + if (listener) + listener->Changed(); } - bool GetExact(ConstString type, MapValueType &entry) { - return GetExact_Impl(type, entry, static_cast<KeyType *>(nullptr)); + void ForEach(ForEachCallback callback) { + if (callback) { + std::lock_guard<std::recursive_mutex> guard(m_map_mutex); + for (const auto &pos : m_map) { + const TypeMatcher &type = pos.first; + if (!callback(type, pos.second)) + break; + } + } } - MapValueType GetAtIndex(size_t index) { - return m_format_map.GetValueAtIndex(index); + uint32_t GetCount() { + std::lock_guard<std::recursive_mutex> guard(m_map_mutex); + return m_map.size(); } - lldb::TypeNameSpecifierImplSP GetTypeNameSpecifierAtIndex(size_t index) { - return GetTypeNameSpecifierAtIndex_Impl(index, - static_cast<KeyType *>(nullptr)); + void AutoComplete(CompletionRequest &request) { + ForEach([&request](const TypeMatcher &matcher, const ValueSP &value) { + request.TryCompleteCurrentArg(matcher.GetMatchString().GetStringRef()); + return true; + }); } - void Clear() { m_format_map.Clear(); } - - void ForEach(ForEachCallback callback) { m_format_map.ForEach(callback); } - - uint32_t GetCount() { return m_format_map.GetCount(); } - protected: - BackEndType m_format_map; - std::string m_name; - FormattersContainer(const FormattersContainer &) = delete; const FormattersContainer &operator=(const FormattersContainer &) = delete; - void Add_Impl(MapKeyType type, const MapValueType &entry, - RegularExpression *dummy) { - m_format_map.Add(std::move(type), entry); - } - - void Add_Impl(ConstString type, const MapValueType &entry, - ConstString *dummy) { - m_format_map.Add(GetValidTypeName_Impl(type), entry); - } - - bool Delete_Impl(ConstString type, ConstString *dummy) { - return m_format_map.Delete(type); - } - - bool Delete_Impl(ConstString type, RegularExpression *dummy) { - std::lock_guard<std::recursive_mutex> guard(m_format_map.mutex()); - MapIterator pos, end = m_format_map.map().end(); - for (pos = m_format_map.map().begin(); pos != end; pos++) { - const RegularExpression ®ex = pos->first; - if (type.GetStringRef() == regex.GetText()) { - m_format_map.map().erase(pos); - if (m_format_map.listener) - m_format_map.listener->Changed(); - return true; - } - } - return false; - } - - bool Get_Impl(ConstString type, MapValueType &entry, ConstString *dummy) { - return m_format_map.Get(type, entry); - } - - bool GetExact_Impl(ConstString type, MapValueType &entry, - ConstString *dummy) { - return Get_Impl(type, entry, static_cast<KeyType *>(nullptr)); - } - - lldb::TypeNameSpecifierImplSP - GetTypeNameSpecifierAtIndex_Impl(size_t index, ConstString *dummy) { - ConstString key = m_format_map.GetKeyAtIndex(index); - if (key) - return lldb::TypeNameSpecifierImplSP( - new TypeNameSpecifierImpl(key.GetStringRef(), false)); - else - return lldb::TypeNameSpecifierImplSP(); - } - - lldb::TypeNameSpecifierImplSP - GetTypeNameSpecifierAtIndex_Impl(size_t index, RegularExpression *dummy) { - RegularExpression regex = m_format_map.GetKeyAtIndex(index); - if (regex == RegularExpression()) - return lldb::TypeNameSpecifierImplSP(); - return lldb::TypeNameSpecifierImplSP( - new TypeNameSpecifierImpl(regex.GetText().str().c_str(), true)); - } - - bool Get_Impl(ConstString key, MapValueType &value, - RegularExpression *dummy) { - llvm::StringRef key_str = key.GetStringRef(); - std::lock_guard<std::recursive_mutex> guard(m_format_map.mutex()); - // Patterns are matched in reverse-chronological order. - for (const auto &pos : llvm::reverse(m_format_map.map())) { - const RegularExpression ®ex = pos.first; - if (regex.Execute(key_str)) { - value = pos.second; - return true; - } - } - return false; - } - - bool GetExact_Impl(ConstString key, MapValueType &value, - RegularExpression *dummy) { - std::lock_guard<std::recursive_mutex> guard(m_format_map.mutex()); - for (const auto &pos : m_format_map.map()) { - const RegularExpression ®ex = pos.first; - if (regex.GetText() == key.GetStringRef()) { - value = pos.second; - return true; - } - } - return false; - } - - bool Get(const FormattersMatchVector &candidates, MapValueType &entry) { + bool Get(const FormattersMatchVector &candidates, ValueSP &entry) { for (const FormattersMatchCandidate &candidate : candidates) { if (Get(candidate.GetTypeName(), entry)) { if (candidate.IsMatch(entry) == false) { @@ -319,6 +226,10 @@ protected: } return false; } + + MapType m_map; + std::recursive_mutex m_map_mutex; + IFormatChangeListener *listener; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/DataFormatters/StringPrinter.h b/contrib/llvm-project/lldb/include/lldb/DataFormatters/StringPrinter.h index 17c645f8637a..4a6e2e9051bf 100644 --- a/contrib/llvm-project/lldb/include/lldb/DataFormatters/StringPrinter.h +++ b/contrib/llvm-project/lldb/include/lldb/DataFormatters/StringPrinter.h @@ -109,7 +109,7 @@ public: uint64_t GetLocation() const { return m_location; } - void SetProcessSP(lldb::ProcessSP p) { m_process_sp = p; } + void SetProcessSP(lldb::ProcessSP p) { m_process_sp = std::move(p); } lldb::ProcessSP GetProcessSP() const { return m_process_sp; } diff --git a/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeCategory.h b/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeCategory.h index 820872a59bda..2c9305901837 100644 --- a/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeCategory.h +++ b/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeCategory.h @@ -25,14 +25,13 @@ namespace lldb_private { template <typename FormatterImpl> class FormatterContainerPair { public: - typedef FormattersContainer<ConstString, FormatterImpl> ExactMatchContainer; - typedef FormattersContainer<RegularExpression, FormatterImpl> - RegexMatchContainer; + typedef FormattersContainer<FormatterImpl> ExactMatchContainer; + typedef FormattersContainer<FormatterImpl> RegexMatchContainer; - typedef typename ExactMatchContainer::MapType ExactMatchMap; - typedef typename RegexMatchContainer::MapType RegexMatchMap; + typedef TypeMatcher ExactMatchMap; + typedef TypeMatcher RegexMatchMap; - typedef typename ExactMatchContainer::MapValueType MapValueType; + typedef typename ExactMatchContainer::ValueSP MapValueType; typedef typename ExactMatchContainer::SharedPointer ExactMatchContainerSP; typedef typename RegexMatchContainer::SharedPointer RegexMatchContainerSP; @@ -42,10 +41,9 @@ public: typedef typename RegexMatchContainer::ForEachCallback RegexMatchForEachCallback; - FormatterContainerPair(const char *exact_name, const char *regex_name, - IFormatChangeListener *clist) - : m_exact_sp(new ExactMatchContainer(std::string(exact_name), clist)), - m_regex_sp(new RegexMatchContainer(std::string(regex_name), clist)) {} + FormatterContainerPair(IFormatChangeListener *clist) + : m_exact_sp(new ExactMatchContainer(clist)), + m_regex_sp(new RegexMatchContainer(clist)) {} ~FormatterContainerPair() = default; @@ -93,52 +91,52 @@ public: template <typename U = TypeFormatImpl> typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type SetExact(FormatContainer::ExactMatchForEachCallback callback) { - m_format_exact = callback; + m_format_exact = std::move(callback); return *this; } template <typename U = TypeFormatImpl> typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type SetWithRegex(FormatContainer::RegexMatchForEachCallback callback) { - m_format_regex = callback; + m_format_regex = std::move(callback); return *this; } template <typename U = TypeSummaryImpl> typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type SetExact(SummaryContainer::ExactMatchForEachCallback callback) { - m_summary_exact = callback; + m_summary_exact = std::move(callback); return *this; } template <typename U = TypeSummaryImpl> typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type SetWithRegex(SummaryContainer::RegexMatchForEachCallback callback) { - m_summary_regex = callback; + m_summary_regex = std::move(callback); return *this; } template <typename U = TypeFilterImpl> typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type SetExact(FilterContainer::ExactMatchForEachCallback callback) { - m_filter_exact = callback; + m_filter_exact = std::move(callback); return *this; } template <typename U = TypeFilterImpl> typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type SetWithRegex(FilterContainer::RegexMatchForEachCallback callback) { - m_filter_regex = callback; + m_filter_regex = std::move(callback); return *this; } template <typename U = SyntheticChildren> typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type SetExact(SynthContainer::ExactMatchForEachCallback callback) { - m_synth_exact = callback; + m_synth_exact = std::move(callback); return *this; } template <typename U = SyntheticChildren> typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type SetWithRegex(SynthContainer::RegexMatchForEachCallback callback) { - m_synth_regex = callback; + m_synth_regex = std::move(callback); return *this; } @@ -349,19 +347,13 @@ private: friend class LanguageCategory; friend class TypeCategoryMap; - friend class FormattersContainer<ConstString, TypeFormatImpl>; - friend class FormattersContainer<lldb::RegularExpressionSP, TypeFormatImpl>; + friend class FormattersContainer<TypeFormatImpl>; - friend class FormattersContainer<ConstString, TypeSummaryImpl>; - friend class FormattersContainer<lldb::RegularExpressionSP, TypeSummaryImpl>; + friend class FormattersContainer<TypeSummaryImpl>; - friend class FormattersContainer<ConstString, TypeFilterImpl>; - friend class FormattersContainer<lldb::RegularExpressionSP, TypeFilterImpl>; - - friend class FormattersContainer<ConstString, ScriptedSyntheticChildren>; - friend class FormattersContainer<lldb::RegularExpressionSP, - ScriptedSyntheticChildren>; + friend class FormattersContainer<TypeFilterImpl>; + friend class FormattersContainer<ScriptedSyntheticChildren>; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeCategoryMap.h b/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeCategoryMap.h index 832652f7d745..4dbca29db066 100644 --- a/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeCategoryMap.h +++ b/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeCategoryMap.h @@ -84,7 +84,8 @@ private: lldb::TypeCategoryImplSP ptr; public: - delete_matching_categories(lldb::TypeCategoryImplSP p) : ptr(p) {} + delete_matching_categories(lldb::TypeCategoryImplSP p) + : ptr(std::move(p)) {} bool operator()(const lldb::TypeCategoryImplSP &other) { return ptr.get() == other.get(); @@ -103,7 +104,7 @@ private: std::recursive_mutex &mutex() { return m_map_mutex; } - friend class FormattersContainer<KeyType, ValueType>; + friend class FormattersContainer<ValueType>; friend class FormatManager; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeSummary.h b/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeSummary.h index 6c3780f7276d..ce3195dbb693 100644 --- a/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeSummary.h +++ b/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeSummary.h @@ -322,7 +322,7 @@ struct CXXFunctionSummaryFormat : public TypeSummaryImpl { const char *GetTextualInfo() const { return m_description.c_str(); } - void SetBackendFunction(Callback cb_func) { m_impl = cb_func; } + void SetBackendFunction(Callback cb_func) { m_impl = std::move(cb_func); } void SetTextualInfo(const char *descr) { if (descr) diff --git a/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeSynthetic.h b/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeSynthetic.h index c852ff18bfa2..fa1458281f1e 100644 --- a/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeSynthetic.h +++ b/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeSynthetic.h @@ -362,7 +362,7 @@ public: CreateFrontEndCallback; CXXSyntheticChildren(const SyntheticChildren::Flags &flags, const char *description, CreateFrontEndCallback callback) - : SyntheticChildren(flags), m_create_callback(callback), + : SyntheticChildren(flags), m_create_callback(std::move(callback)), m_description(description ? description : "") {} bool IsScripted() override { return false; } diff --git a/contrib/llvm-project/lldb/include/lldb/Expression/DWARFExpression.h b/contrib/llvm-project/lldb/include/lldb/Expression/DWARFExpression.h index 6b63b186e3e4..c7d4e4b1882f 100644 --- a/contrib/llvm-project/lldb/include/lldb/Expression/DWARFExpression.h +++ b/contrib/llvm-project/lldb/include/lldb/Expression/DWARFExpression.h @@ -219,6 +219,10 @@ public: bool MatchesOperand(StackFrame &frame, const Instruction::Operand &op); + llvm::Optional<DataExtractor> + GetLocationExpression(lldb::addr_t load_function_start, + lldb::addr_t addr) const; + private: /// Pretty-prints the location expression to a stream /// @@ -237,10 +241,6 @@ private: void DumpLocation(Stream *s, const DataExtractor &data, lldb::DescriptionLevel level, ABI *abi) const; - llvm::Optional<DataExtractor> - GetLocationExpression(lldb::addr_t load_function_start, - lldb::addr_t addr) const; - /// Module which defined this expression. lldb::ModuleWP m_module_wp; diff --git a/contrib/llvm-project/lldb/include/lldb/Expression/ExpressionVariable.h b/contrib/llvm-project/lldb/include/lldb/Expression/ExpressionVariable.h index 60062d212bad..4259e6395da4 100644 --- a/contrib/llvm-project/lldb/include/lldb/Expression/ExpressionVariable.h +++ b/contrib/llvm-project/lldb/include/lldb/Expression/ExpressionVariable.h @@ -32,7 +32,7 @@ public: virtual ~ExpressionVariable(); - size_t GetByteSize() { return m_frozen_sp->GetByteSize(); } + llvm::Optional<uint64_t> GetByteSize() { return m_frozen_sp->GetByteSize(); } ConstString GetName() { return m_frozen_sp->GetName(); } diff --git a/contrib/llvm-project/lldb/include/lldb/Expression/UtilityFunction.h b/contrib/llvm-project/lldb/include/lldb/Expression/UtilityFunction.h index 5ebbc0ede1e3..99fb32153aa2 100644 --- a/contrib/llvm-project/lldb/include/lldb/Expression/UtilityFunction.h +++ b/contrib/llvm-project/lldb/include/lldb/Expression/UtilityFunction.h @@ -42,8 +42,8 @@ public: /// /// \param[in] name /// The name of the function, as used in the text. - UtilityFunction(ExecutionContextScope &exe_scope, const char *text, - const char *name); + UtilityFunction(ExecutionContextScope &exe_scope, std::string text, + std::string name); ~UtilityFunction() override; @@ -110,9 +110,10 @@ public: protected: std::shared_ptr<IRExecutionUnit> m_execution_unit_sp; lldb::ModuleWP m_jit_module_wp; - std::string m_function_text; ///< The text of the function. Must be a - ///well-formed translation unit. - std::string m_function_name; ///< The name of the function. + /// The text of the function. Must be a well-formed translation unit. + std::string m_function_text; + /// The name of the function. + std::string m_function_name; std::unique_ptr<FunctionCaller> m_caller_up; }; diff --git a/contrib/llvm-project/lldb/include/lldb/Host/Config.h.cmake b/contrib/llvm-project/lldb/include/lldb/Host/Config.h.cmake index 42f4ca1a26c6..c667708a90a6 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/Config.h.cmake +++ b/contrib/llvm-project/lldb/include/lldb/Host/Config.h.cmake @@ -20,6 +20,8 @@ #cmakedefine01 HAVE_PPOLL +#cmakedefine01 HAVE_PTSNAME_R + #cmakedefine01 HAVE_SIGACTION #cmakedefine01 HAVE_PROCESS_VM_READV @@ -38,6 +40,8 @@ #cmakedefine01 LLDB_ENABLE_CURSES +#cmakedefine01 CURSES_HAVE_NCURSES_CURSES_H + #cmakedefine01 LLDB_ENABLE_LIBEDIT #cmakedefine01 LLDB_ENABLE_LIBXML2 @@ -48,7 +52,7 @@ #cmakedefine01 LLDB_EMBED_PYTHON_HOME -#cmakedefine LLDB_PYTHON_HOME "${LLDB_PYTHON_HOME}" +#cmakedefine LLDB_PYTHON_HOME R"(${LLDB_PYTHON_HOME})" #define LLDB_LIBDIR_SUFFIX "${LLVM_LIBDIR_SUFFIX}" diff --git a/contrib/llvm-project/lldb/include/lldb/Host/Editline.h b/contrib/llvm-project/lldb/include/lldb/Host/Editline.h index 356e8f734732..a37ad1b9d106 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/Editline.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/Editline.h @@ -98,6 +98,9 @@ typedef int (*FixIndentationCallbackType)(Editline *editline, const StringList &lines, int cursor_position, void *baton); +typedef llvm::Optional<std::string> (*SuggestionCallbackType)( + llvm::StringRef line, void *baton); + typedef void (*CompleteCallbackType)(CompletionRequest &request, void *baton); /// Status used to decide when and how to start editing another line in @@ -184,6 +187,9 @@ public: /// Cancel this edit and oblitarate all trace of it bool Cancel(); + /// Register a callback for autosuggestion. + void SetSuggestionCallback(SuggestionCallbackType callback, void *baton); + /// Register a callback for the tab key void SetAutoCompleteCallback(CompleteCallbackType callback, void *baton); @@ -312,6 +318,12 @@ private: /// tab key is typed. unsigned char TabCommand(int ch); + /// Apply autosuggestion part in gray as editline. + unsigned char ApplyAutosuggestCommand(int ch); + + /// Command used when a character is typed. + unsigned char TypedCharacter(int ch); + /// Respond to normal character insertion by fixing line indentation unsigned char FixIndentationCommand(int ch); @@ -360,7 +372,9 @@ private: const char *m_fix_indentation_callback_chars = nullptr; CompleteCallbackType m_completion_callback = nullptr; void *m_completion_callback_baton = nullptr; - + SuggestionCallbackType m_suggestion_callback = nullptr; + void *m_suggestion_callback_baton = nullptr; + std::size_t m_previous_autosuggestion_size = 0; std::mutex m_output_mutex; }; } diff --git a/contrib/llvm-project/lldb/include/lldb/Host/FileSystem.h b/contrib/llvm-project/lldb/include/lldb/Host/FileSystem.h index 8dcff3402592..02ff5f301336 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/FileSystem.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/FileSystem.h @@ -33,13 +33,14 @@ public: FileSystem() : m_fs(llvm::vfs::getRealFileSystem()), m_collector(nullptr), - m_mapped(false) {} - FileSystem(std::shared_ptr<llvm::FileCollector> collector) - : m_fs(llvm::vfs::getRealFileSystem()), m_collector(collector), - m_mapped(false) {} + m_home_directory(), m_mapped(false) {} + FileSystem(std::shared_ptr<llvm::FileCollectorBase> collector) + : m_fs(llvm::vfs::getRealFileSystem()), m_collector(std::move(collector)), + m_home_directory(), m_mapped(false) {} FileSystem(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs, bool mapped = false) - : m_fs(fs), m_collector(nullptr), m_mapped(mapped) {} + : m_fs(std::move(fs)), m_collector(nullptr), m_home_directory(), + m_mapped(mapped) {} FileSystem(const FileSystem &fs) = delete; FileSystem &operator=(const FileSystem &fs) = delete; @@ -47,7 +48,7 @@ public: static FileSystem &Instance(); static void Initialize(); - static void Initialize(std::shared_ptr<llvm::FileCollector> collector); + static void Initialize(std::shared_ptr<llvm::FileCollectorBase> collector); static llvm::Error Initialize(const FileSpec &mapping); static void Initialize(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs); static void Terminate(); @@ -154,6 +155,10 @@ public: /// Call into the Host to see if it can help find the file. bool ResolveExecutableLocation(FileSpec &file_spec); + /// Get the user home directory. + bool GetHomeDirectory(llvm::SmallVectorImpl<char> &path) const; + bool GetHomeDirectory(FileSpec &file_spec) const; + enum EnumerateDirectoryResult { /// Enumerate next entry in the current directory. eEnumerateDirectoryResultNext, @@ -189,10 +194,13 @@ public: void Collect(const FileSpec &file_spec); void Collect(const llvm::Twine &file); + void SetHomeDirectory(std::string home_directory); + private: static llvm::Optional<FileSystem> &InstanceImpl(); llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> m_fs; - std::shared_ptr<llvm::FileCollector> m_collector; + std::shared_ptr<llvm::FileCollectorBase> m_collector; + std::string m_home_directory; bool m_mapped; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Host/Host.h b/contrib/llvm-project/lldb/include/lldb/Host/Host.h index f19cb85d2329..76792cc6eab5 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/Host.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/Host.h @@ -196,19 +196,34 @@ public: static Status ShellExpandArguments(ProcessLaunchInfo &launch_info); /// Run a shell command. - /// \arg command shouldn't be NULL + /// \arg command shouldn't be empty /// \arg working_dir Pass empty FileSpec to use the current working directory /// \arg status_ptr Pass NULL if you don't want the process exit status /// \arg signo_ptr Pass NULL if you don't want the signal that caused the /// process to exit /// \arg command_output Pass NULL if you don't want the command output /// \arg hide_stderr if this is false, redirect stderr to stdout - /// TODO: Convert this function to take a StringRef. - static Status RunShellCommand(const char *command, + static Status RunShellCommand(llvm::StringRef command, const FileSpec &working_dir, int *status_ptr, int *signo_ptr, std::string *command_output, const Timeout<std::micro> &timeout, - bool run_in_default_shell = true, + bool run_in_shell = true, + bool hide_stderr = false); + + /// Run a shell command. + /// \arg shell Pass an empty string if you want to use the default shell + /// interpreter \arg command \arg working_dir Pass empty FileSpec to use the + /// current working directory \arg status_ptr Pass NULL if you don't want + /// the process exit status \arg signo_ptr Pass NULL if you don't want the + /// signal that caused + /// the process to exit + /// \arg command_output Pass NULL if you don't want the command output + /// \arg hide_stderr If this is \b false, redirect stderr to stdout + static Status RunShellCommand(llvm::StringRef shell, llvm::StringRef command, + const FileSpec &working_dir, int *status_ptr, + int *signo_ptr, std::string *command_output, + const Timeout<std::micro> &timeout, + bool run_in_shell = true, bool hide_stderr = false); /// Run a shell command. @@ -222,7 +237,23 @@ public: int *status_ptr, int *signo_ptr, std::string *command_output, const Timeout<std::micro> &timeout, - bool run_in_default_shell = true, + bool run_in_shell = true, + bool hide_stderr = false); + + /// Run a shell command. + /// \arg shell Pass an empty string if you want to use the default + /// shell interpreter \arg command \arg working_dir Pass empty FileSpec to use + /// the current working directory \arg status_ptr Pass NULL if you don't + /// want the process exit status \arg signo_ptr Pass NULL if you don't + /// want the signal that caused the + /// process to exit + /// \arg command_output Pass NULL if you don't want the command output + /// \arg hide_stderr If this is \b false, redirect stderr to stdout + static Status RunShellCommand(llvm::StringRef shell, const Args &args, + const FileSpec &working_dir, int *status_ptr, + int *signo_ptr, std::string *command_output, + const Timeout<std::micro> &timeout, + bool run_in_shell = true, bool hide_stderr = false); static bool OpenFileInExternalEditor(const FileSpec &file_spec, diff --git a/contrib/llvm-project/lldb/include/lldb/Host/HostInfoBase.h b/contrib/llvm-project/lldb/include/lldb/Host/HostInfoBase.h index 70682c9b685e..15bb168aad97 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/HostInfoBase.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/HostInfoBase.h @@ -11,6 +11,7 @@ #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/UUID.h" #include "lldb/Utility/UserIDResolver.h" #include "lldb/Utility/XcodeSDK.h" #include "lldb/lldb-enumerations.h" @@ -24,6 +25,11 @@ namespace lldb_private { class FileSpec; +struct SharedCacheImageInfo { + UUID uuid; + lldb::DataBufferSP data_sp; +}; + class HostInfoBase { private: // Static class, unconstructable. @@ -98,6 +104,13 @@ public: /// Return the directory containing a specific Xcode SDK. static llvm::StringRef GetXcodeSDKPath(XcodeSDK sdk) { return {}; } + /// Return information about module \p image_name if it is loaded in + /// the current process's address space. + static SharedCacheImageInfo + GetSharedCacheImageInfo(llvm::StringRef image_name) { + return {}; + } + protected: static bool ComputeSharedLibraryDirectory(FileSpec &file_spec); static bool ComputeSupportExeDirectory(FileSpec &file_spec); diff --git a/contrib/llvm-project/lldb/include/lldb/Host/ProcessLaunchInfo.h b/contrib/llvm-project/lldb/include/lldb/Host/ProcessLaunchInfo.h index e83d8396e9f2..ee9755580825 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/ProcessLaunchInfo.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/ProcessLaunchInfo.h @@ -94,10 +94,9 @@ public: void Clear(); - bool ConvertArgumentsForLaunchingInShell(Status &error, bool localhost, - bool will_debug, + bool ConvertArgumentsForLaunchingInShell(Status &error, bool will_debug, bool first_arg_is_full_shell_command, - int32_t num_resumes); + uint32_t num_resumes); void SetMonitorProcessCallback(const Host::MonitorChildProcessCallback &callback, diff --git a/contrib/llvm-project/lldb/include/lldb/Host/PseudoTerminal.h b/contrib/llvm-project/lldb/include/lldb/Host/PseudoTerminal.h index 8a5a233e7748..350f926dcac1 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/PseudoTerminal.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/PseudoTerminal.h @@ -9,11 +9,11 @@ #ifndef LLDB_HOST_PSEUDOTERMINAL_H #define LLDB_HOST_PSEUDOTERMINAL_H +#include "lldb/lldb-defines.h" +#include "llvm/Support/Error.h" #include <fcntl.h> #include <string> -#include "lldb/lldb-defines.h" - namespace lldb_private { /// \class PseudoTerminal PseudoTerminal.h "lldb/Host/PseudoTerminal.h" @@ -62,15 +62,11 @@ public: /// @li PseudoTerminal::ReleasePrimaryFileDescriptor() @li /// PseudoTerminal::ReleaseSaveFileDescriptor() /// - /// \param[out] error_str - /// An pointer to an error that can describe any errors that - /// occur. This can be NULL if no error status is desired. - /// /// \return /// \b Parent process: a child process ID that is greater - /// than zero, or -1 if the fork fails. + /// than zero, or an error if the fork fails. /// \b Child process: zero. - lldb::pid_t Fork(char *error_str, size_t error_len); + llvm::Expected<lldb::pid_t> Fork(); /// The primary file descriptor accessor. /// @@ -105,20 +101,11 @@ public: /// A primary pseudo terminal should already be valid prior to /// calling this function. /// - /// \param[out] error_str - /// An pointer to an error that can describe any errors that - /// occur. This can be NULL if no error status is desired. - /// /// \return - /// The name of the secondary pseudo terminal as a NULL terminated - /// C. This string that comes from static memory, so a copy of - /// the string should be made as subsequent calls can change - /// this value. NULL is returned if this object doesn't have - /// a valid primary pseudo terminal opened or if the call to - /// \c ptsname() fails. + /// The name of the secondary pseudo terminal. /// /// \see PseudoTerminal::OpenFirstAvailablePrimary() - const char *GetSecondaryName(char *error_str, size_t error_len) const; + std::string GetSecondaryName() const; /// Open the first available pseudo terminal. /// @@ -137,18 +124,9 @@ public: /// Flags to use when calling \c posix_openpt(\a oflag). /// A value of "O_RDWR|O_NOCTTY" is suggested. /// - /// \param[out] error_str - /// An pointer to an error that can describe any errors that - /// occur. This can be NULL if no error status is desired. - /// - /// \return - /// \b true when the primary files descriptor is - /// successfully opened. - /// \b false if anything goes wrong. - /// /// \see PseudoTerminal::GetPrimaryFileDescriptor() @see /// PseudoTerminal::ReleasePrimaryFileDescriptor() - bool OpenFirstAvailablePrimary(int oflag, char *error_str, size_t error_len); + llvm::Error OpenFirstAvailablePrimary(int oflag); /// Open the secondary for the current primary pseudo terminal. /// @@ -166,19 +144,10 @@ public: /// \param[in] oflag /// Flags to use when calling \c open(\a oflag). /// - /// \param[out] error_str - /// An pointer to an error that can describe any errors that - /// occur. This can be NULL if no error status is desired. - /// - /// \return - /// \b true when the primary files descriptor is - /// successfully opened. - /// \b false if anything goes wrong. - /// /// \see PseudoTerminal::OpenFirstAvailablePrimary() @see /// PseudoTerminal::GetSecondaryFileDescriptor() @see /// PseudoTerminal::ReleaseSecondaryFileDescriptor() - bool OpenSecondary(int oflag, char *error_str, size_t error_len); + llvm::Error OpenSecondary(int oflag); /// Release the primary file descriptor. /// diff --git a/contrib/llvm-project/lldb/include/lldb/Host/common/NativeProcessProtocol.h b/contrib/llvm-project/lldb/include/lldb/Host/common/NativeProcessProtocol.h index 2faab6f587cd..5be9cb657382 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/common/NativeProcessProtocol.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/common/NativeProcessProtocol.h @@ -17,6 +17,7 @@ #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/TraceOptions.h" +#include "lldb/Utility/UnimplementedError.h" #include "lldb/lldb-private-forward.h" #include "lldb/lldb-types.h" #include "llvm/ADT/ArrayRef.h" @@ -112,10 +113,14 @@ public: virtual Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written) = 0; - virtual Status AllocateMemory(size_t size, uint32_t permissions, - lldb::addr_t &addr) = 0; + virtual llvm::Expected<lldb::addr_t> AllocateMemory(size_t size, + uint32_t permissions) { + return llvm::make_error<UnimplementedError>(); + } - virtual Status DeallocateMemory(lldb::addr_t addr) = 0; + virtual llvm::Error DeallocateMemory(lldb::addr_t addr) { + return llvm::make_error<UnimplementedError>(); + } virtual lldb::addr_t GetSharedLibraryInfoAddress() = 0; @@ -387,6 +392,11 @@ public: return Status("Not implemented"); } + /// \copydoc Process::GetSupportedTraceType() + virtual llvm::Expected<TraceTypeInfo> GetSupportedTraceType() { + return llvm::make_error<UnimplementedError>(); + } + protected: struct SoftwareBreakpoint { uint32_t ref_count; diff --git a/contrib/llvm-project/lldb/include/lldb/Host/common/NativeRegisterContext.h b/contrib/llvm-project/lldb/include/lldb/Host/common/NativeRegisterContext.h index 3b54d4ae1e05..f7568fe31b80 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/common/NativeRegisterContext.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/common/NativeRegisterContext.h @@ -16,6 +16,8 @@ namespace lldb_private { class NativeThreadProtocol; +enum class ExpeditedRegs { Minimal, Full }; + class NativeRegisterContext : public std::enable_shared_from_this<NativeRegisterContext> { public: @@ -75,6 +77,8 @@ public: virtual bool ClearHardwareWatchpoint(uint32_t hw_index); + virtual Status ClearWatchpointHit(uint32_t hw_index); + virtual Status ClearAllHardwareWatchpoints(); virtual Status IsWatchpointHit(uint32_t wp_index, bool &is_hit); @@ -114,6 +118,11 @@ public: virtual NativeThreadProtocol &GetThread() { return m_thread; } + virtual std::vector<uint32_t> + GetExpeditedRegisters(ExpeditedRegs expType) const; + + virtual bool RegisterOffsetIsDynamic() const { return false; } + const RegisterInfo *GetRegisterInfoByName(llvm::StringRef reg_name, uint32_t start_idx = 0); diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandCompletions.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandCompletions.h index 39d1c98eaa39..c80bde0e719b 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandCompletions.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandCompletions.h @@ -37,10 +37,23 @@ public: eRegisterCompletion = (1u << 9), eBreakpointCompletion = (1u << 10), eProcessPluginCompletion = (1u << 11), + eDisassemblyFlavorCompletion = (1u << 12), + eTypeLanguageCompletion = (1u << 13), + eFrameIndexCompletion = (1u << 14), + eModuleUUIDCompletion = (1u << 15), + eStopHookIDCompletion = (1u << 16), + eThreadIndexCompletion = (1u << 17), + eWatchPointIDCompletion = (1u << 18), + eBreakpointNameCompletion = (1u << 19), + eProcessIDCompletion = (1u << 20), + eProcessNameCompletion = (1u << 21), + eRemoteDiskFileCompletion = (1u << 22), + eRemoteDiskDirectoryCompletion = (1u << 23), + eTypeCategoryNameCompletion = (1u << 24), // This item serves two purposes. It is the last element in the enum, so // you can add custom enums starting from here in your Option class. Also // if you & in this bit the base code will not process the option. - eCustomCompletion = (1u << 12) + eCustomCompletion = (1u << 24) }; static bool InvokeCommonCompletionCallbacks( @@ -62,12 +75,23 @@ public: StringList &matches, TildeExpressionResolver &Resolver); + static void RemoteDiskFiles(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher); + + static void RemoteDiskDirectories(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher); + static void SourceFiles(CommandInterpreter &interpreter, CompletionRequest &request, SearchFilter *searcher); static void Modules(CommandInterpreter &interpreter, CompletionRequest &request, SearchFilter *searcher); + static void ModuleUUIDs(CommandInterpreter &interpreter, + CompletionRequest &request, SearchFilter *searcher); + static void Symbols(CommandInterpreter &interpreter, CompletionRequest &request, SearchFilter *searcher); @@ -91,9 +115,42 @@ public: static void Breakpoints(CommandInterpreter &interpreter, CompletionRequest &request, SearchFilter *searcher); + static void BreakpointNames(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher); + static void ProcessPluginNames(CommandInterpreter &interpreter, CompletionRequest &request, SearchFilter *searcher); + + static void ProcessIDs(CommandInterpreter &interpreter, + CompletionRequest &request, SearchFilter *searcher); + + static void ProcessNames(CommandInterpreter &interpreter, + CompletionRequest &request, SearchFilter *searcher); + + static void DisassemblyFlavors(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher); + + static void TypeLanguages(CommandInterpreter &interpreter, + CompletionRequest &request, SearchFilter *searcher); + + static void FrameIndexes(CommandInterpreter &interpreter, + CompletionRequest &request, SearchFilter *searcher); + + static void StopHookIDs(CommandInterpreter &interpreter, + CompletionRequest &request, SearchFilter *searcher); + + static void ThreadIndexes(CommandInterpreter &interpreter, + CompletionRequest &request, SearchFilter *searcher); + + static void WatchPointIDs(CommandInterpreter &interpreter, + CompletionRequest &request, SearchFilter *searcher); + + static void TypeCategoryNames(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher); }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandInterpreter.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandInterpreter.h index 8a9dce7a19bc..c4f9dd2fdb37 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandInterpreter.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandInterpreter.h @@ -20,6 +20,7 @@ #include "lldb/Utility/CompletionRequest.h" #include "lldb/Utility/Event.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/StreamString.h" #include "lldb/Utility/StringList.h" #include "lldb/lldb-forward.h" #include "lldb/lldb-private.h" @@ -255,7 +256,7 @@ public: } void SourceInitFileCwd(CommandReturnObject &result); - void SourceInitFileHome(CommandReturnObject &result); + void SourceInitFileHome(CommandReturnObject &result, bool is_repl = false); bool AddCommand(llvm::StringRef name, const lldb::CommandObjectSP &cmd_sp, bool can_replace); @@ -264,7 +265,7 @@ public: bool can_replace); lldb::CommandObjectSP GetCommandSPExact(llvm::StringRef cmd, - bool include_aliases) const; + bool include_aliases = false) const; CommandObject *GetCommandObject(llvm::StringRef cmd, StringList *matches = nullptr, @@ -350,6 +351,10 @@ public: CommandObject *GetCommandObjectForCommand(llvm::StringRef &command_line); + /// Returns the auto-suggestion string that should be added to the given + /// command line. + llvm::Optional<std::string> GetAutoSuggestionForCommand(llvm::StringRef line); + // This handles command line completion. void HandleCompletion(CompletionRequest &request); @@ -485,9 +490,11 @@ public: bool GetExpandRegexAliases() const; bool GetPromptOnQuit() const; - void SetPromptOnQuit(bool enable); + bool GetSaveSessionOnQuit() const; + void SetSaveSessionOnQuit(bool enable); + bool GetEchoCommands() const; void SetEchoCommands(bool enable); @@ -498,6 +505,12 @@ public: return m_user_dict; } + const CommandObject::CommandMap &GetCommands() const { + return m_command_dict; + } + + const CommandObject::CommandMap &GetAliases() const { return m_alias_dict; } + /// Specify if the command interpreter should allow that the user can /// specify a custom exit code when calling 'quit'. void AllowExitCodeOnQuit(bool allow); @@ -526,6 +539,20 @@ public: bool GetSpaceReplPrompts() const; + /// Save the current debugger session transcript to a file on disk. + /// \param output_file + /// The file path to which the session transcript will be written. Since + /// the argument is optional, an arbitrary temporary file will be create + /// when no argument is passed. + /// \param result + /// This is used to pass function output and error messages. + /// \return \b true if the session transcript was successfully written to + /// disk, \b false otherwise. + bool SaveTranscript(CommandReturnObject &result, + llvm::Optional<std::string> output_file = llvm::None); + + FileSpec GetCurrentSourceDir(); + protected: friend class Debugger; @@ -612,7 +639,13 @@ private: ChildrenTruncatedWarningStatus m_truncation_warning; // Whether we truncated // children and whether // the user has been told + + // FIXME: Stop using this to control adding to the history and then replace + // this with m_command_source_dirs.size(). uint32_t m_command_source_depth; + /// A stack of directory paths. When not empty, the last one is the directory + /// of the file that's currently sourced. + std::vector<FileSpec> m_command_source_dirs; std::vector<uint32_t> m_command_source_flags; CommandInterpreterRunResult m_result; @@ -621,6 +654,8 @@ private: llvm::Optional<int> m_quit_exit_code; // If the driver is accepts custom exit codes for the 'quit' command. bool m_allow_exit_code = false; + + StreamString m_transcript_stream; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObject.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObject.h index cc4d40b23c31..d5ad969cda66 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObject.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObject.h @@ -90,14 +90,15 @@ public: { lldb::CommandArgumentType arg_type; ArgumentRepetitionType arg_repetition; - uint32_t arg_opt_set_association; // This arg might be associated only with - // some particular option set(s). - CommandArgumentData() - : arg_type(lldb::eArgTypeNone), arg_repetition(eArgRepeatPlain), - arg_opt_set_association(LLDB_OPT_SET_ALL) // By default, the arg - // associates to all option - // sets. - {} + /// This arg might be associated only with some particular option set(s). By + /// default the arg associates to all option sets. + uint32_t arg_opt_set_association; + + CommandArgumentData(lldb::CommandArgumentType type = lldb::eArgTypeNone, + ArgumentRepetitionType repetition = eArgRepeatPlain, + uint32_t opt_set = LLDB_OPT_SET_ALL) + : arg_type(type), arg_repetition(repetition), + arg_opt_set_association(opt_set) {} }; typedef std::vector<CommandArgumentData> diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObjectMultiword.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObjectMultiword.h index 6b383f8cfb34..f330a745f9bd 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObjectMultiword.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObjectMultiword.h @@ -82,6 +82,10 @@ public: // for this object. virtual CommandObject *GetProxyCommandObject() = 0; + llvm::StringRef GetSyntax() override; + + llvm::StringRef GetHelp() override; + llvm::StringRef GetHelpLong() override; bool IsRemovable() const override; @@ -121,6 +125,11 @@ public: const char *GetRepeatCommand(Args ¤t_command_args, uint32_t index) override; + /// \return + /// An error message to be displayed when the command is executed (i.e. + /// Execute is called) and \a GetProxyCommandObject returned null. + virtual llvm::StringRef GetUnsupportedError(); + bool Execute(const char *args_string, CommandReturnObject &result) override; protected: diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObjectRegexCommand.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObjectRegexCommand.h deleted file mode 100644 index 01d7c6d118d4..000000000000 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObjectRegexCommand.h +++ /dev/null @@ -1,61 +0,0 @@ -//===-- CommandObjectRegexCommand.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_INTERPRETER_COMMANDOBJECTREGEXCOMMAND_H -#define LLDB_INTERPRETER_COMMANDOBJECTREGEXCOMMAND_H - -#include <list> - -#include "lldb/Interpreter/CommandObject.h" -#include "lldb/Utility/CompletionRequest.h" -#include "lldb/Utility/RegularExpression.h" - -namespace lldb_private { - -// CommandObjectRegexCommand - -class CommandObjectRegexCommand : public CommandObjectRaw { -public: - CommandObjectRegexCommand(CommandInterpreter &interpreter, llvm::StringRef name, - llvm::StringRef help, llvm::StringRef syntax, - uint32_t max_matches, uint32_t completion_type_mask, - bool is_removable); - - ~CommandObjectRegexCommand() override; - - bool IsRemovable() const override { return m_is_removable; } - - bool AddRegexCommand(const char *re_cstr, const char *command_cstr); - - bool HasRegexEntries() const { return !m_entries.empty(); } - - void HandleCompletion(CompletionRequest &request) override; - -protected: - bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override; - - struct Entry { - RegularExpression regex; - std::string command; - }; - - typedef std::list<Entry> EntryCollection; - const uint32_t m_max_matches; - const uint32_t m_completion_type_mask; - EntryCollection m_entries; - bool m_is_removable; - -private: - CommandObjectRegexCommand(const CommandObjectRegexCommand &) = delete; - const CommandObjectRegexCommand & - operator=(const CommandObjectRegexCommand &) = delete; -}; - -} // namespace lldb_private - -#endif // LLDB_INTERPRETER_COMMANDOBJECTREGEXCOMMAND_H diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValue.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValue.h index 5b07427094bf..a8176e39940a 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValue.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValue.h @@ -31,6 +31,7 @@ public: eTypeChar, eTypeDictionary, eTypeEnum, + eTypeFileLineColumn, eTypeFileSpec, eTypeFileSpecList, eTypeFormat, @@ -84,7 +85,7 @@ public: SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign); - virtual bool Clear() = 0; + virtual void Clear() = 0; virtual lldb::OptionValueSP DeepCopy() const = 0; @@ -135,6 +136,8 @@ public: return eTypeDictionary; case 1u << eTypeEnum: return eTypeEnum; + case 1u << eTypeFileLineColumn: + return eTypeFileLineColumn; case 1u << eTypeFileSpec: return eTypeFileSpec; case 1u << eTypeFileSpecList: diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueArch.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueArch.h index 7b63c68fddbf..809261ef22c3 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueArch.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueArch.h @@ -47,10 +47,9 @@ public: SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { m_current_value = m_default_value; m_value_was_set = false; - return true; } lldb::OptionValueSP DeepCopy() const override; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueArray.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueArray.h index 000351c2f586..4546bbb80394 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueArray.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueArray.h @@ -36,10 +36,9 @@ public: SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { m_values.clear(); m_value_was_set = false; - return true; } lldb::OptionValueSP DeepCopy() const override; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueBoolean.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueBoolean.h index d221f6d034c2..1af14a4980ed 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueBoolean.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueBoolean.h @@ -37,10 +37,9 @@ public: SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { m_current_value = m_default_value; m_value_was_set = false; - return true; } void AutoComplete(CommandInterpreter &interpreter, diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueChar.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueChar.h index 8d0aa91d7076..a8ecf507a4cf 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueChar.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueChar.h @@ -38,10 +38,9 @@ public: SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { m_current_value = m_default_value; m_value_was_set = false; - return true; } // Subclass specific functions diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueDictionary.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueDictionary.h index 1bc45252607c..dab1c3ea0c1c 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueDictionary.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueDictionary.h @@ -35,10 +35,9 @@ public: SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - bool Clear() override { + void Clear() override { m_values.clear(); m_value_was_set = false; - return true; } lldb::OptionValueSP DeepCopy() const override; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueEnumeration.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueEnumeration.h index 26ba7ad5f646..12c6473c7f1c 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueEnumeration.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueEnumeration.h @@ -47,10 +47,9 @@ public: SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { m_current_value = m_default_value; m_value_was_set = false; - return true; } lldb::OptionValueSP DeepCopy() const override; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileColonLine.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileColonLine.h new file mode 100644 index 000000000000..713deea9e141 --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileColonLine.h @@ -0,0 +1,64 @@ +//===-- OptionValueFileColonLine.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_INTERPRETER_OPTIONVALUEFILECOLONLINE_H +#define LLDB_INTERPRETER_OPTIONVALUEFILECOLONLINE_H + +#include "lldb/Interpreter/OptionValue.h" + +#include "lldb/Utility/FileSpec.h" +#include "llvm/Support/Chrono.h" + +namespace lldb_private { + +class OptionValueFileColonLine : public OptionValue { +public: + OptionValueFileColonLine(); + OptionValueFileColonLine(const llvm::StringRef input); + + ~OptionValueFileColonLine() override {} + + OptionValue::Type GetType() const override { return eTypeFileLineColumn; } + + void DumpValue(const ExecutionContext *exe_ctx, Stream &strm, + uint32_t dump_mask) override; + + Status + SetValueFromString(llvm::StringRef value, + VarSetOperationType op = eVarSetOperationAssign) override; + Status + SetValueFromString(const char *, + VarSetOperationType = eVarSetOperationAssign) = delete; + + void Clear() override { + m_file_spec.Clear(); + m_line_number = LLDB_INVALID_LINE_NUMBER; + m_column_number = LLDB_INVALID_COLUMN_NUMBER; + } + + lldb::OptionValueSP DeepCopy() const override; + + void AutoComplete(CommandInterpreter &interpreter, + CompletionRequest &request) override; + + FileSpec &GetFileSpec() { return m_file_spec; } + uint32_t GetLineNumber() { return m_line_number; } + uint32_t GetColumnNumber() { return m_column_number; } + + void SetCompletionMask(uint32_t mask) { m_completion_mask = mask; } + +protected: + FileSpec m_file_spec; + uint32_t m_line_number; + uint32_t m_column_number; + uint32_t m_completion_mask; +}; + +} // namespace lldb_private + +#endif // LLDB_INTERPRETER_OPTIONVALUEFILECOLONLINE_H diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileSpec.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileSpec.h index 2b18c9533f91..4fde3f6e3c8a 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileSpec.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileSpec.h @@ -41,12 +41,11 @@ public: SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { m_current_value = m_default_value; m_value_was_set = false; m_data_sp.reset(); m_data_mod_time = llvm::sys::TimePoint<>(); - return true; } lldb::OptionValueSP DeepCopy() const override; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileSpecList.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileSpecList.h index 7b762bf6b309..38773525c8db 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileSpecList.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileSpecList.h @@ -39,11 +39,10 @@ public: SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { std::lock_guard<std::recursive_mutex> lock(m_mutex); m_current_value.Clear(); m_value_was_set = false; - return true; } lldb::OptionValueSP DeepCopy() const override; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFormat.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFormat.h index 6904c93a2f33..5a83ff3b8983 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFormat.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFormat.h @@ -38,10 +38,9 @@ public: SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { m_current_value = m_default_value; m_value_was_set = false; - return true; } lldb::OptionValueSP DeepCopy() const override; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h index beb5d6843a98..7c2f9fba0242 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h @@ -34,7 +34,7 @@ public: SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override; + void Clear() override; lldb::OptionValueSP DeepCopy() const override; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueLanguage.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueLanguage.h index f4ca2fd69ab5..129365296759 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueLanguage.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueLanguage.h @@ -41,10 +41,9 @@ public: SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { m_current_value = m_default_value; m_value_was_set = false; - return true; } lldb::OptionValueSP DeepCopy() const override; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValuePathMappings.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValuePathMappings.h index 18f5cbaf4336..6d1a0816f45b 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValuePathMappings.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValuePathMappings.h @@ -35,10 +35,9 @@ public: SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { m_path_mappings.Clear(m_notify_changes); m_value_was_set = false; - return true; } lldb::OptionValueSP DeepCopy() const override; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueProperties.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueProperties.h index 76f09cc77123..d60afdeb46fb 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueProperties.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueProperties.h @@ -34,7 +34,7 @@ public: Type GetType() const override { return eTypeProperties; } - bool Clear() override; + void Clear() override; lldb::OptionValueSP DeepCopy() const override; @@ -104,11 +104,6 @@ public: Status SetSubValue(const ExecutionContext *exe_ctx, VarSetOperationType op, llvm::StringRef path, llvm::StringRef value) override; - virtual bool PredicateMatches(const ExecutionContext *exe_ctx, - llvm::StringRef predicate) const { - return false; - } - OptionValueArch * GetPropertyAtIndexAsOptionValueArch(const ExecutionContext *exe_ctx, uint32_t idx) const; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueRegex.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueRegex.h index b09b8414d5bf..4751a1dc27ed 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueRegex.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueRegex.h @@ -36,10 +36,9 @@ public: SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { m_regex = RegularExpression(m_default_regex_str); m_value_was_set = false; - return true; } lldb::OptionValueSP DeepCopy() const override; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueSInt64.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueSInt64.h index fbabaaeb2ff4..87917c108865 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueSInt64.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueSInt64.h @@ -50,10 +50,9 @@ public: SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { m_current_value = m_default_value; m_value_was_set = false; - return true; } lldb::OptionValueSP DeepCopy() const override; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueString.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueString.h index cd371c567020..ed44dae67d1d 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueString.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueString.h @@ -85,10 +85,9 @@ public: SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { m_current_value = m_default_value; m_value_was_set = false; - return true; } lldb::OptionValueSP DeepCopy() const override; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueUInt64.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueUInt64.h index 0096e87de367..1164fb802f68 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueUInt64.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueUInt64.h @@ -47,10 +47,9 @@ public: SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { m_current_value = m_default_value; m_value_was_set = false; - return true; } lldb::OptionValueSP DeepCopy() const override; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueUUID.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueUUID.h index 2fb8caa3aa53..1f663e999b9d 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueUUID.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueUUID.h @@ -36,10 +36,9 @@ public: SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { m_uuid.Clear(); m_value_was_set = false; - return true; } lldb::OptionValueSP DeepCopy() const override; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValues.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValues.h index 36e7c192d60a..6efc9e1ad064 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValues.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValues.h @@ -17,6 +17,7 @@ #include "lldb/Interpreter/OptionValueChar.h" #include "lldb/Interpreter/OptionValueDictionary.h" #include "lldb/Interpreter/OptionValueEnumeration.h" +#include "lldb/Interpreter/OptionValueFileColonLine.h" #include "lldb/Interpreter/OptionValueFileSpec.h" #include "lldb/Interpreter/OptionValueFileSpecList.h" #include "lldb/Interpreter/OptionValueFormat.h" diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/Options.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/Options.h index ebceaea8383d..9738cce2f7a1 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/Options.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/Options.h @@ -14,6 +14,7 @@ #include "lldb/Utility/Args.h" #include "lldb/Utility/CompletionRequest.h" +#include "lldb/Utility/OptionDefinition.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-defines.h" #include "lldb/lldb-private.h" @@ -40,12 +41,6 @@ struct OptionArgElement { typedef std::vector<OptionArgElement> OptionElementVector; -static inline bool isprint8(int ch) { - if (ch & 0xffffff00u) - return false; - return llvm::isPrint(ch); -} - /// \class Options Options.h "lldb/Interpreter/Options.h" /// A command line option parsing protocol class. /// diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptInterpreter.h index 491923e6a6c4..4abd1ca68167 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptInterpreter.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptInterpreter.h @@ -298,6 +298,23 @@ public: return lldb::eSearchDepthModule; } + virtual StructuredData::GenericSP + CreateScriptedStopHook(lldb::TargetSP target_sp, const char *class_name, + StructuredDataImpl *args_data, Status &error) { + error.SetErrorString("Creating scripted stop-hooks with the current " + "script interpreter is not supported."); + return StructuredData::GenericSP(); + } + + // This dispatches to the handle_stop method of the stop-hook class. It + // returns a "should_stop" bool. + virtual bool + ScriptedStopHookHandleStop(StructuredData::GenericSP implementor_sp, + ExecutionContext &exc_ctx, + lldb::StreamSP stream_sp) { + return true; + } + virtual StructuredData::ObjectSP LoadPluginModule(const FileSpec &file_spec, lldb_private::Status &error) { return StructuredData::ObjectSP(); @@ -490,7 +507,8 @@ public: virtual bool LoadScriptingModule(const char *filename, bool init_session, lldb_private::Status &error, - StructuredData::ObjectSP *module_sp = nullptr); + StructuredData::ObjectSP *module_sp = nullptr, + FileSpec extra_search_dir = {}); virtual bool IsReservedWord(const char *word) { return false; } diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/CompilerType.h b/contrib/llvm-project/lldb/include/lldb/Symbol/CompilerType.h index 280966a327ec..5a0e8e57200d 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/CompilerType.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/CompilerType.h @@ -20,7 +20,7 @@ namespace lldb_private { class DataExtractor; -/// Represents a generic type in a programming language. +/// Generic representation of a type in a programming language. /// /// This class serves as an abstraction for a type inside one of the TypeSystems /// implemented by the language plugins. It does not have any actual logic in it @@ -82,6 +82,8 @@ public: bool IsAnonymousType() const; + bool IsScopedEnumerationType() const; + bool IsBeingDefined() const; bool IsCharType() const; @@ -96,7 +98,7 @@ public: bool IsFloatingPointType(uint32_t &count, bool &is_complex) const; - bool IsFunctionType(bool *is_variadic_ptr = nullptr) const; + bool IsFunctionType() const; uint32_t IsHomogeneousAggregate(CompilerType *base_type_ptr) const; @@ -177,7 +179,7 @@ public: /// Creating related types. /// \{ - CompilerType GetArrayElementType(uint64_t *stride = nullptr) const; + CompilerType GetArrayElementType(ExecutionContextScope *exe_scope) const; CompilerType GetArrayType(uint64_t size) const; @@ -185,6 +187,8 @@ public: CompilerType GetFullyUnqualifiedType() const; + CompilerType GetEnumerationIntegerType() const; + /// Returns -1 if this isn't a function of if the function doesn't /// have a prototype Returns a value >= 0 if there is a prototype. int GetFunctionArgumentCount() const; @@ -383,7 +387,8 @@ public: /// \} bool GetValueAsScalar(const DataExtractor &data, lldb::offset_t data_offset, - size_t data_byte_size, Scalar &value) const; + size_t data_byte_size, Scalar &value, + ExecutionContextScope *exe_scope) const; void Clear() { m_type = nullptr; m_type_system = nullptr; diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/LineTable.h b/contrib/llvm-project/lldb/include/lldb/Symbol/LineTable.h index d66b58ca4c6d..b48e82f19ffb 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/LineTable.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/LineTable.h @@ -9,6 +9,7 @@ #ifndef LLDB_SYMBOL_LINETABLE_H #define LLDB_SYMBOL_LINETABLE_H +#include "lldb/Core/Address.h" #include "lldb/Core/ModuleChild.h" #include "lldb/Core/Section.h" #include "lldb/Symbol/LineEntry.h" diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/ObjectFile.h b/contrib/llvm-project/lldb/include/lldb/Symbol/ObjectFile.h index e814015c0bf7..080724cb86bd 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/ObjectFile.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/ObjectFile.h @@ -91,6 +91,17 @@ public: eStrataJIT }; + /// If we have a corefile binary hint, this enum + /// specifies the binary type which we can use to + /// select the correct DynamicLoader plugin. + enum BinaryType { + eBinaryTypeInvalid = 0, + eBinaryTypeUnknown, + eBinaryTypeKernel, /// kernel binary + eBinaryTypeUser, /// user process binary + eBinaryTypeStandalone /// standalone binary / firmware + }; + struct LoadableData { lldb::addr_t Dest; llvm::ArrayRef<uint8_t> Contents; @@ -500,12 +511,17 @@ public: /// If the uuid of the binary is specified, this will be set. /// If no UUID is available, will be cleared. /// + /// \param[out] type + /// Return the type of the binary, which will dictate which + /// DynamicLoader plugin should be used. + /// /// \return /// Returns true if either address or uuid has been set. - virtual bool GetCorefileMainBinaryInfo (lldb::addr_t &address, UUID &uuid) { - address = LLDB_INVALID_ADDRESS; - uuid.Clear(); - return false; + virtual bool GetCorefileMainBinaryInfo(lldb::addr_t &address, UUID &uuid, + ObjectFile::BinaryType &type) { + address = LLDB_INVALID_ADDRESS; + uuid.Clear(); + return false; } virtual lldb::RegisterContextSP diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolContext.h b/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolContext.h index cc49ce51c713..c513dbb447f8 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolContext.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolContext.h @@ -139,11 +139,19 @@ public: /// be printed. In disassembly formatting, where we want a format /// like "<*+36>", this should be false and "*" will be printed /// instead. + /// + /// \param[in] show_inline_callsite_line_info + /// When processing an inline block, the line info of the callsite + /// is dumped if this flag is \b true, otherwise the line info + /// of the actual inlined function is dumped. + /// + /// \return + /// \b true if some text was dumped, \b false otherwise. bool DumpStopContext(Stream *s, ExecutionContextScope *exe_scope, const Address &so_addr, bool show_fullpaths, bool show_module, bool show_inlined_frames, - bool show_function_arguments, - bool show_function_name) const; + bool show_function_arguments, bool show_function_name, + bool show_inline_callsite_line_info = true) const; /// Get the address range contained within a symbol context. /// @@ -340,7 +348,7 @@ public: void Clear(); - bool SymbolContextMatches(SymbolContext &sc); + bool SymbolContextMatches(const SymbolContext &sc); bool AddressMatches(lldb::addr_t addr); diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolVendor.h b/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolVendor.h index c9c59a3fc1be..5c785e8c5a85 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolVendor.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolVendor.h @@ -14,6 +14,7 @@ #include "lldb/Core/ModuleChild.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Symbol/SourceModule.h" +#include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/TypeMap.h" #include "lldb/lldb-private.h" #include "llvm/ADT/DenseSet.h" @@ -35,8 +36,6 @@ public: // Constructors and Destructors SymbolVendor(const lldb::ModuleSP &module_sp); - ~SymbolVendor() override; - void AddSymbolFileRepresentation(const lldb::ObjectFileSP &objfile_sp); SymbolFile *GetSymbolFile() { return m_sym_file_up.get(); } @@ -49,11 +48,6 @@ public: protected: std::unique_ptr<SymbolFile> m_sym_file_up; // A single symbol file. Subclasses // can add more of these if needed. - -private: - // For SymbolVendor only - SymbolVendor(const SymbolVendor &) = delete; - const SymbolVendor &operator=(const SymbolVendor &) = delete; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/Type.h b/contrib/llvm-project/lldb/include/lldb/Symbol/Type.h index 8735d016bb22..dd917cfb7ca8 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/Type.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/Type.h @@ -56,6 +56,7 @@ public: Type *operator->() { return GetType(); } Type *GetType(); + SymbolFile &GetSymbolFile() const { return m_symbol_file; } protected: SymbolFile &m_symbol_file; @@ -108,20 +109,27 @@ public: void DumpTypeName(Stream *s); - // Since Type instances only keep a "SymbolFile *" internally, other classes - // like TypeImpl need make sure the module is still around before playing - // with - // Type instances. They can store a weak pointer to the Module; + /// Since Type instances only keep a "SymbolFile *" internally, other classes + /// like TypeImpl need make sure the module is still around before playing + /// with + /// Type instances. They can store a weak pointer to the Module; lldb::ModuleSP GetModule(); - void GetDescription(Stream *s, lldb::DescriptionLevel level, bool show_name); + /// GetModule may return module for compile unit's object file. + /// GetExeModule returns module for executable object file that contains + /// compile unit where type was actualy defined. + /// GetModule and GetExeModule may return the same value. + lldb::ModuleSP GetExeModule(); + + void GetDescription(Stream *s, lldb::DescriptionLevel level, bool show_name, + ExecutionContextScope *exe_scope); SymbolFile *GetSymbolFile() { return m_symbol_file; } const SymbolFile *GetSymbolFile() const { return m_symbol_file; } ConstString GetName(); - llvm::Optional<uint64_t> GetByteSize(); + llvm::Optional<uint64_t> GetByteSize(ExecutionContextScope *exe_scope); uint32_t GetNumChildren(bool omit_empty_base_classes); @@ -259,6 +267,8 @@ public: void Clear(); + lldb::ModuleSP GetModule() const; + ConstString GetName() const; ConstString GetDisplayTypeName() const; @@ -286,8 +296,12 @@ public: private: bool CheckModule(lldb::ModuleSP &module_sp) const; + bool CheckExeModule(lldb::ModuleSP &module_sp) const; + bool CheckModuleCommon(const lldb::ModuleWP &input_module_wp, + lldb::ModuleSP &module_sp) const; lldb::ModuleWP m_module_wp; + lldb::ModuleWP m_exe_module_wp; CompilerType m_static_type; CompilerType m_dynamic_type; }; diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/TypeSystem.h b/contrib/llvm-project/lldb/include/lldb/Symbol/TypeSystem.h index e188f29354b8..1fad8f61ac37 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/TypeSystem.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/TypeSystem.h @@ -152,8 +152,7 @@ public: virtual bool IsFloatingPointType(lldb::opaque_compiler_type_t type, uint32_t &count, bool &is_complex) = 0; - virtual bool IsFunctionType(lldb::opaque_compiler_type_t type, - bool *is_variadic_ptr) = 0; + virtual bool IsFunctionType(lldb::opaque_compiler_type_t type) = 0; virtual size_t GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) = 0; @@ -176,6 +175,8 @@ public: return false; } + virtual bool IsScopedEnumerationType(lldb::opaque_compiler_type_t type) = 0; + virtual bool IsPossibleDynamicType(lldb::opaque_compiler_type_t type, CompilerType *target_type, // Can pass NULL bool check_cplusplus, bool check_objc) = 0; @@ -217,14 +218,18 @@ public: // Creating related types - virtual CompilerType GetArrayElementType(lldb::opaque_compiler_type_t type, - uint64_t *stride) = 0; + virtual CompilerType + GetArrayElementType(lldb::opaque_compiler_type_t type, + ExecutionContextScope *exe_scope) = 0; virtual CompilerType GetArrayType(lldb::opaque_compiler_type_t type, uint64_t size); virtual CompilerType GetCanonicalType(lldb::opaque_compiler_type_t type) = 0; + virtual CompilerType + GetEnumerationIntegerType(lldb::opaque_compiler_type_t type) = 0; + // Returns -1 if this isn't a function of if the function doesn't have a // prototype Returns a value >= 0 if there is a prototype. virtual int GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) = 0; @@ -464,10 +469,8 @@ public: return nullptr; } - virtual UtilityFunction *GetUtilityFunction(const char *text, - const char *name) { - return nullptr; - } + virtual std::unique_ptr<UtilityFunction> + CreateUtilityFunction(std::string text, std::string name); virtual PersistentExpressionState *GetPersistentExpressionState() { return nullptr; @@ -522,6 +525,22 @@ protected: ///multi-threaded environments. collection m_map; bool m_clear_in_progress; + +private: + typedef llvm::function_ref<lldb::TypeSystemSP()> CreateCallback; + /// Finds the type system for the given language. If no type system could be + /// found for a language and a CreateCallback was provided, the value returned + /// by the callback will be treated as the TypeSystem for the language. + /// + /// \param language The language for which the type system should be found. + /// \param create_callback A callback that will be called if no previously + /// created TypeSystem that fits the given language + /// could found. Can be omitted if a non-existent + /// type system should be treated as an error instead. + /// \return The found type system or an error. + llvm::Expected<TypeSystem &> GetTypeSystemForLanguage( + lldb::LanguageType language, + llvm::Optional<CreateCallback> create_callback = llvm::None); }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/UnwindPlan.h b/contrib/llvm-project/lldb/include/lldb/Symbol/UnwindPlan.h index 8902b5f4eaa7..40814da3de4a 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/UnwindPlan.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/UnwindPlan.h @@ -393,6 +393,7 @@ public: m_plan_is_sourced_from_compiler(rhs.m_plan_is_sourced_from_compiler), m_plan_is_valid_at_all_instruction_locations( rhs.m_plan_is_valid_at_all_instruction_locations), + m_plan_is_for_signal_trap(rhs.m_plan_is_for_signal_trap), m_lsda_address(rhs.m_lsda_address), m_personality_func_addr(rhs.m_personality_func_addr) { m_row_list.reserve(rhs.m_row_list.size()); diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/Variable.h b/contrib/llvm-project/lldb/include/lldb/Symbol/Variable.h index 66abdc0b3117..0dcbbd8e4c8e 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/Variable.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/Variable.h @@ -33,7 +33,8 @@ public: const lldb::SymbolFileTypeSP &symfile_type_sp, lldb::ValueType scope, SymbolContextScope *owner_scope, const RangeList &scope_range, Declaration *decl, const DWARFExpression &location, bool external, - bool artificial, bool static_member = false); + bool artificial, bool location_is_constant_data, + bool static_member = false); virtual ~Variable(); @@ -64,6 +65,8 @@ public: lldb::ValueType GetScope() const { return m_scope; } + const RangeList &GetScopeRange() const { return m_scope_range; } + bool IsExternal() const { return m_external; } bool IsArtificial() const { return m_artificial; } diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ABI.h b/contrib/llvm-project/lldb/include/lldb/Target/ABI.h index b252e4b54f03..131b2eaff765 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/ABI.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/ABI.h @@ -159,7 +159,7 @@ public: protected: using ABI::ABI; - bool GetRegisterInfoByName(ConstString name, RegisterInfo &info); + bool GetRegisterInfoByName(llvm::StringRef name, RegisterInfo &info); virtual const RegisterInfo *GetRegisterInfoArray(uint32_t &count) = 0; }; diff --git a/contrib/llvm-project/lldb/include/lldb/Target/DynamicLoader.h b/contrib/llvm-project/lldb/include/lldb/Target/DynamicLoader.h index d3ce1b05ed51..dead3eec7013 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/DynamicLoader.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/DynamicLoader.h @@ -68,12 +68,6 @@ public: /// 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 @@ -308,10 +302,6 @@ protected: // Member variables. Process *m_process; ///< The process that this dynamic loader plug-in is tracking. - -private: - DynamicLoader(const DynamicLoader &) = delete; - const DynamicLoader &operator=(const DynamicLoader &) = delete; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Target/InstrumentationRuntime.h b/contrib/llvm-project/lldb/include/lldb/Target/InstrumentationRuntime.h index dd4da26c215e..eeec91f36af4 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/InstrumentationRuntime.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/InstrumentationRuntime.h @@ -53,7 +53,7 @@ protected: lldb::ModuleSP GetRuntimeModuleSP() { return m_runtime_module; } void SetRuntimeModuleSP(lldb::ModuleSP module_sp) { - m_runtime_module = module_sp; + m_runtime_module = std::move(module_sp); } lldb::user_id_t GetBreakpointID() const { return m_breakpoint_id; } diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Language.h b/contrib/llvm-project/lldb/include/lldb/Target/Language.h index 9dc9df363d79..6368828e36da 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/Language.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/Language.h @@ -211,6 +211,10 @@ public: // nil/null object, this method returns true virtual bool IsNilReference(ValueObject &valobj); + /// Returns the summary string for ValueObjects for which IsNilReference() is + /// true. + virtual llvm::StringRef GetNilReferenceSummaryString() { return {}; } + // 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 diff --git a/contrib/llvm-project/lldb/include/lldb/Target/LanguageRuntime.h b/contrib/llvm-project/lldb/include/lldb/Target/LanguageRuntime.h index b0b9b919911a..a3897adfe46a 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/LanguageRuntime.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/LanguageRuntime.h @@ -18,6 +18,7 @@ #include "lldb/Expression/LLVMUserExpression.h" #include "lldb/Symbol/DeclVendor.h" #include "lldb/Target/ExecutionContextScope.h" +#include "lldb/Target/Runtime.h" #include "lldb/lldb-private.h" #include "lldb/lldb-public.h" @@ -56,10 +57,8 @@ protected: void UpdateModuleListIfNeeded(); }; -class LanguageRuntime : public PluginInterface { +class LanguageRuntime : public Runtime, public PluginInterface { public: - ~LanguageRuntime() override; - static LanguageRuntime *FindPlugin(Process *process, lldb::LanguageType language); @@ -127,10 +126,6 @@ public: return lldb::ThreadSP(); } - Process *GetProcess() { return m_process; } - - Target &GetTargetRef() { return m_process->GetTarget(); } - virtual DeclVendor *GetDeclVendor() { return nullptr; } virtual lldb::BreakpointResolverSP @@ -159,7 +154,7 @@ public: return llvm::None; } - virtual void ModulesDidLoad(const ModuleList &module_list) {} + virtual void ModulesDidLoad(const ModuleList &module_list) override {} // Called by ClangExpressionParser::PrepareForExecution to query for any // custom LLVM IR passes that need to be run before an expression is @@ -179,14 +174,7 @@ public: static char ID; protected: - // Classes that inherit from LanguageRuntime can see and modify these - LanguageRuntime(Process *process); - Process *m_process; - -private: - LanguageRuntime(const LanguageRuntime &) = delete; - const LanguageRuntime &operator=(const LanguageRuntime &) = delete; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Target/MemoryRegionInfo.h b/contrib/llvm-project/lldb/include/lldb/Target/MemoryRegionInfo.h index 9f089b4b0083..392e1edd273e 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/MemoryRegionInfo.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/MemoryRegionInfo.h @@ -24,16 +24,17 @@ public: MemoryRegionInfo() = default; MemoryRegionInfo(RangeType range, OptionalBool read, OptionalBool write, OptionalBool execute, OptionalBool mapped, ConstString name, - OptionalBool flash, lldb::offset_t blocksize) + OptionalBool flash, lldb::offset_t blocksize, + OptionalBool memory_tagged) : m_range(range), m_read(read), m_write(write), m_execute(execute), - m_mapped(mapped), m_name(name), m_flash(flash), m_blocksize(blocksize) { - } + m_mapped(mapped), m_name(name), m_flash(flash), m_blocksize(blocksize), + m_memory_tagged(memory_tagged) {} RangeType &GetRange() { return m_range; } void Clear() { m_range.Clear(); - m_read = m_write = m_execute = eDontKnow; + m_read = m_write = m_execute = m_memory_tagged = eDontKnow; } const RangeType &GetRange() const { return m_range; } @@ -48,6 +49,8 @@ public: ConstString GetName() const { return m_name; } + OptionalBool GetMemoryTagged() const { return m_memory_tagged; } + void SetReadable(OptionalBool val) { m_read = val; } void SetWritable(OptionalBool val) { m_write = val; } @@ -66,6 +69,8 @@ public: void SetBlocksize(lldb::offset_t blocksize) { m_blocksize = blocksize; } + void SetMemoryTagged(OptionalBool val) { m_memory_tagged = val; } + // Get permissions as a uint32_t that is a mask of one or more bits from the // lldb::Permissions uint32_t GetLLDBPermissions() const { @@ -91,7 +96,8 @@ public: 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 && m_name == rhs.m_name && - m_flash == rhs.m_flash && m_blocksize == rhs.m_blocksize; + m_flash == rhs.m_flash && m_blocksize == rhs.m_blocksize && + m_memory_tagged == rhs.m_memory_tagged; } bool operator!=(const MemoryRegionInfo &rhs) const { return !(*this == rhs); } @@ -105,6 +111,7 @@ protected: ConstString m_name; OptionalBool m_flash = eDontKnow; lldb::offset_t m_blocksize = 0; + OptionalBool m_memory_tagged = eDontKnow; }; inline bool operator<(const MemoryRegionInfo &lhs, diff --git a/contrib/llvm-project/lldb/include/lldb/Target/OperatingSystem.h b/contrib/llvm-project/lldb/include/lldb/Target/OperatingSystem.h index 6db5c0a01f36..ceeddceb0f2c 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/OperatingSystem.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/OperatingSystem.h @@ -40,11 +40,8 @@ public: /// 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, @@ -68,9 +65,6 @@ protected: // Member variables. Process *m_process; ///< The process that this dynamic loader plug-in is tracking. -private: - OperatingSystem(const OperatingSystem &) = delete; - const OperatingSystem &operator=(const OperatingSystem &) = delete; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Platform.h b/contrib/llvm-project/lldb/include/lldb/Target/Platform.h index 277fcf68cb0c..df46466655c3 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/Platform.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/Platform.h @@ -522,6 +522,9 @@ public: return UINT64_MAX; } + virtual void AutoCompleteDiskFileOrDirectory(CompletionRequest &request, + bool only_dir) {} + virtual uint64_t ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst, uint64_t dst_len, Status &error) { error.SetErrorStringWithFormat( @@ -617,7 +620,18 @@ public: } virtual lldb_private::Status RunShellCommand( - const char *command, // Shouldn't be nullptr + llvm::StringRef command, + 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 lldb_private::Status RunShellCommand( + llvm::StringRef shell, llvm::StringRef command, 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 @@ -636,7 +650,7 @@ public: virtual bool CalculateMD5(const FileSpec &file_spec, uint64_t &low, uint64_t &high); - virtual int32_t GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) { + virtual uint32_t GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) { return 1; } @@ -936,9 +950,6 @@ private: Platform &remote_platform); FileSpec GetModuleCacheRoot(); - - Platform(const Platform &) = delete; - const Platform &operator=(const Platform &) = delete; }; class PlatformList { diff --git a/contrib/llvm-project/lldb/include/lldb/Target/PostMortemProcess.h b/contrib/llvm-project/lldb/include/lldb/Target/PostMortemProcess.h new file mode 100644 index 000000000000..353bfc0919ee --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Target/PostMortemProcess.h @@ -0,0 +1,32 @@ +//===-- PostMortemProcess.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_POSTMORTEMPROCESS_H +#define LLDB_TARGET_POSTMORTEMPROCESS_H + +#include "lldb/Target/Process.h" + +namespace lldb_private { + +/// \class PostMortemProcess +/// Base class for all processes that don't represent a live process, such as +/// coredumps or processes traced in the past. +/// +/// \a lldb_private::Process virtual functions overrides that are common +/// between these kinds of processes can have default implementations in this +/// class. +class PostMortemProcess : public Process { +public: + using Process::Process; + + bool IsLiveDebugSession() const override { return false; } +}; + +} // namespace lldb_private + +#endif // LLDB_TARGET_POSTMORTEMPROCESS_H diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Process.h b/contrib/llvm-project/lldb/include/lldb/Target/Process.h index bf9b64547ed5..fbdb5069b39f 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/Process.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/Process.h @@ -30,7 +30,6 @@ #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" @@ -38,6 +37,7 @@ #include "lldb/Target/QueueList.h" #include "lldb/Target/ThreadList.h" #include "lldb/Target/ThreadPlanStack.h" +#include "lldb/Target/Trace.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/Broadcaster.h" #include "lldb/Utility/Event.h" @@ -47,6 +47,7 @@ #include "lldb/Utility/Status.h" #include "lldb/Utility/StructuredData.h" #include "lldb/Utility/TraceOptions.h" +#include "lldb/Utility/UnimplementedError.h" #include "lldb/Utility/UserIDResolver.h" #include "lldb/lldb-private.h" @@ -91,6 +92,7 @@ public: std::chrono::seconds GetUtilityExpressionTimeout() const; bool GetOSPluginReportsAllThreads() const; void SetOSPluginReportsAllThreads(bool does_report); + bool GetSteppingRunsAllThreads() const; protected: Process *m_process; // Can be nullptr for global ProcessProperties @@ -207,32 +209,6 @@ protected: // 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.) @@ -326,7 +302,7 @@ public: } void SetStopEventForLastNaturalStopID(lldb::EventSP event_sp) { - m_last_natural_stop_event = event_sp; + m_last_natural_stop_event = std::move(event_sp); } lldb::EventSP GetStopEventForStopID(uint32_t stop_id) const { @@ -361,7 +337,6 @@ inline bool operator!=(const ProcessModID &lhs, const ProcessModID &rhs) { /// 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 { @@ -535,7 +510,8 @@ public: static lldb::ProcessSP FindPlugin(lldb::TargetSP target_sp, llvm::StringRef plugin_name, lldb::ListenerSP listener_sp, - const FileSpec *crash_file_path); + const FileSpec *crash_file_path, + bool can_connect); /// Static function that can be used with the \b host function /// Host::StartMonitoringChildProcess (). @@ -557,6 +533,15 @@ public: uint32_t GetAddressByteSize() const; + /// Sets the stored pid. + /// + /// This does not change the pid of underlying process. + lldb::pid_t GetID() const { return m_pid; } + + /// Returns the pid of the process or LLDB_INVALID_PROCESS_ID if there is + /// no known pid. + void SetID(lldb::pid_t new_pid) { m_pid = new_pid; } + uint32_t GetUniqueID() const { return m_process_unique_id; } /// Check if a plug-in instance can debug the file in \a module. @@ -582,7 +567,7 @@ public: /// \return /// Returns \b true if this Process has not been finalized /// and \b false otherwise. - bool IsValid() const { return !m_finalize_called; } + bool IsValid() const { return !m_finalizing; } /// Return a multi-word command object that can be used to expose plug-in /// specific commands. @@ -727,11 +712,6 @@ public: /// 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. /// @@ -743,6 +723,12 @@ public: void SetShouldDetach(bool b) { m_should_detach = b; } + /// Get the image vector for the current process. + /// + /// \return + /// The constant reference to the member m_image_tokens. + const std::vector<lldb::addr_t>& GetImageTokens() { return m_image_tokens; } + /// Get the image information address for the current process. /// /// Some runtimes have system functions that can help dynamic loaders locate @@ -915,11 +901,6 @@ public: /// 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. /// @@ -1393,6 +1374,8 @@ public: /// otherwise. virtual bool IsAlive(); + virtual bool IsLiveDebugSession() const { return true; }; + /// 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 @@ -1404,35 +1387,6 @@ public: /// 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 @@ -2060,8 +2014,17 @@ public: virtual Status DisableWatchpoint(Watchpoint *wp, bool notify = true); // Thread Queries - virtual bool UpdateThreadList(ThreadList &old_thread_list, - ThreadList &new_thread_list) = 0; + + /// Update the thread list. + /// + /// This method performs some general clean up before invoking + /// \a DoUpdateThreadList, which should be implemented by each + /// process plugin. + /// + /// \return + /// \b true if the new thread list could be generated, \b false otherwise. + bool UpdateThreadList(ThreadList &old_thread_list, + ThreadList &new_thread_list); void UpdateThreadListIfNeeded(); @@ -2163,7 +2126,7 @@ public: public: ProcessEventHijacker(Process &process, lldb::ListenerSP listener_sp) : m_process(process) { - m_process.HijackProcessEvents(listener_sp); + m_process.HijackProcessEvents(std::move(listener_sp)); } ~ProcessEventHijacker() { m_process.RestoreProcessEvents(); } @@ -2238,7 +2201,7 @@ void PruneThreadPlans(); /// Dump the thread plans associated with thread with \a tid. /// - /// \param[in/out] strm + /// \param[in,out] strm /// The stream to which to dump the output /// /// \param[in] tid @@ -2265,7 +2228,7 @@ void PruneThreadPlans(); /// Dump all the thread plans for this process. /// - /// \param[in/out] strm + /// \param[in,out] strm /// The stream to which to dump the output /// /// \param[in] desc_level @@ -2545,12 +2508,59 @@ void PruneThreadPlans(); return Status("Not implemented"); } + /// Get the processor tracing type supported for this process. + /// Responses might be different depending on the architecture and + /// capabilities of the underlying OS. + /// + /// \return + /// The supported trace type or an \a llvm::Error if tracing is + /// not supported for the inferior. + virtual llvm::Expected<TraceTypeInfo> GetSupportedTraceType(); + // This calls a function of the form "void * (*)(void)". bool CallVoidArgVoidPtrReturn(const Address *address, lldb::addr_t &returned_func, bool trap_exceptions = false); protected: + /// Update the thread list following process plug-in's specific logic. + /// + /// This method should only be invoked by \a UpdateThreadList. + /// + /// \return + /// \b true if the new thread list could be generated, \b false otherwise. + virtual bool DoUpdateThreadList(ThreadList &old_thread_list, + ThreadList &new_thread_list) = 0; + + /// 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; + void SetState(lldb::EventSP &event_sp); lldb::StateType GetPrivateState(); @@ -2720,6 +2730,7 @@ protected: // Member variables std::weak_ptr<Target> m_target_wp; ///< The target that owns this process. + lldb::pid_t m_pid = LLDB_INVALID_PROCESS_ID; ThreadSafeValue<lldb::StateType> m_public_state; ThreadSafeValue<lldb::StateType> m_private_state; // The actual state of our process @@ -2811,10 +2822,11 @@ protected: // 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() + + /// This is set at the beginning of Process::Finalize() to stop functions + /// from looking up or creating things during or after a finalize call. + std::atomic<bool> m_finalizing; + 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 @@ -2918,6 +2930,8 @@ protected: void LoadOperatingSystemPlugin(bool flush); private: + Status DestroyImpl(bool force_kill); + /// 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 diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ProcessTrace.h b/contrib/llvm-project/lldb/include/lldb/Target/ProcessTrace.h new file mode 100644 index 000000000000..55faba1576d0 --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Target/ProcessTrace.h @@ -0,0 +1,86 @@ +//===-- ProcessTrace.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_PROCESSTRACE_H +#define LLDB_TARGET_PROCESSTRACE_H + +#include "lldb/Target/PostMortemProcess.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/Status.h" + +namespace lldb_private { + +class ProcessTrace : public PostMortemProcess { +public: + static void Initialize(); + + static void Terminate(); + + static ConstString GetPluginNameStatic(); + + static const char *GetPluginDescriptionStatic(); + + ProcessTrace(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp); + + ~ProcessTrace() override; + + bool CanDebug(lldb::TargetSP target_sp, + bool plugin_specified_by_name) override; + + void DidAttach(ArchSpec &process_arch) override; + + DynamicLoader *GetDynamicLoader() override { return nullptr; } + + SystemRuntime *GetSystemRuntime() override { return nullptr; } + + ConstString GetPluginName() override; + + uint32_t GetPluginVersion() override; + + Status DoDestroy() override; + + void RefreshStateAfterStop() override; + + Status WillResume() override { + Status error; + error.SetErrorStringWithFormat( + "error: %s does not support resuming processes", + GetPluginName().GetCString()); + return error; + } + + bool IsAlive() override; + + bool WarnBeforeDetach() const override { return false; } + + size_t ReadMemory(lldb::addr_t addr, void *buf, size_t size, + Status &error) override; + + size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size, + Status &error) override; + + ArchSpec GetArchitecture(); + + bool GetProcessInfo(ProcessInstanceInfo &info) override; + +protected: + void Clear(); + + bool DoUpdateThreadList(ThreadList &old_thread_list, + ThreadList &new_thread_list) override; + +private: + static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp, + lldb::ListenerSP listener_sp, + const FileSpec *crash_file_path, + bool can_connect); +}; + +} // namespace lldb_private + +#endif // LLDB_TARGET_PROCESSTRACE_H diff --git a/contrib/llvm-project/lldb/include/lldb/Target/RemoteAwarePlatform.h b/contrib/llvm-project/lldb/include/lldb/Target/RemoteAwarePlatform.h index 5741dbe027b7..6d6ac99c093f 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/RemoteAwarePlatform.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/RemoteAwarePlatform.h @@ -68,11 +68,16 @@ public: bool GetRemoteOSKernelDescription(std::string &s) override; ArchSpec GetRemoteSystemArchitecture() override; - Status RunShellCommand(const char *command, const FileSpec &working_dir, + Status RunShellCommand(llvm::StringRef command, const FileSpec &working_dir, int *status_ptr, int *signo_ptr, std::string *command_output, const Timeout<std::micro> &timeout) override; + Status RunShellCommand(llvm::StringRef interpreter, llvm::StringRef 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; diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Runtime.h b/contrib/llvm-project/lldb/include/lldb/Target/Runtime.h new file mode 100644 index 000000000000..06f0b610e40b --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Target/Runtime.h @@ -0,0 +1,33 @@ +//===-- Runtime.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_RUNTIME_H +#define LLDB_TARGET_RUNTIME_H + +#include "lldb/Target/Process.h" + +namespace lldb_private { +class Runtime { +public: + Runtime(Process *process) : m_process(process) {} + virtual ~Runtime() = default; + Runtime(const Runtime &) = delete; + const Runtime &operator=(const Runtime &) = delete; + + Process *GetProcess() { return m_process; } + Target &GetTargetRef() { return m_process->GetTarget(); } + + /// Called when modules have been loaded in the process. + virtual void ModulesDidLoad(const ModuleList &module_list) = 0; + +protected: + Process *m_process; +}; +} // namespace lldb_private + +#endif // LLDB_TARGET_RUNTIME_H diff --git a/contrib/llvm-project/lldb/include/lldb/Target/StackFrameRecognizer.h b/contrib/llvm-project/lldb/include/lldb/Target/StackFrameRecognizer.h index 9c9105ac04e4..baffc890bb06 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/StackFrameRecognizer.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/StackFrameRecognizer.h @@ -17,6 +17,8 @@ #include "lldb/lldb-private-forward.h" #include "lldb/lldb-public.h" +#include <vector> + namespace lldb_private { /// \class RecognizedStackFrame @@ -95,37 +97,44 @@ private: operator=(const ScriptedStackFrameRecognizer &) = delete; }; -/// \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 that provides a registry of known stack frame recognizers. class StackFrameRecognizerManager { public: - static void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, - ConstString module, - llvm::ArrayRef<ConstString> symbols, - bool first_instruction_only = true); + void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, + ConstString module, llvm::ArrayRef<ConstString> symbols, + bool first_instruction_only = true); + + void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, + lldb::RegularExpressionSP module, + lldb::RegularExpressionSP symbol, + bool first_instruction_only = true); - static void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, - lldb::RegularExpressionSP module, - lldb::RegularExpressionSP symbol, - bool first_instruction_only = true); + void ForEach(std::function< + void(uint32_t recognizer_id, std::string recognizer_name, + std::string module, llvm::ArrayRef<ConstString> symbols, + bool regexp)> const &callback); - static void - ForEach(std::function<void(uint32_t recognizer_id, - std::string recognizer_name, std::string module, - llvm::ArrayRef<ConstString> symbols, - bool regexp)> const &callback); + bool RemoveRecognizerWithID(uint32_t recognizer_id); - static bool RemoveRecognizerWithID(uint32_t recognizer_id); + void RemoveAllRecognizers(); - static void RemoveAllRecognizers(); + lldb::StackFrameRecognizerSP GetRecognizerForFrame(lldb::StackFrameSP frame); - static lldb::StackFrameRecognizerSP GetRecognizerForFrame( - lldb::StackFrameSP frame); + lldb::RecognizedStackFrameSP RecognizeFrame(lldb::StackFrameSP frame); - static lldb::RecognizedStackFrameSP RecognizeFrame(lldb::StackFrameSP frame); +private: + struct RegisteredEntry { + uint32_t recognizer_id; + lldb::StackFrameRecognizerSP recognizer; + bool is_regexp; + ConstString module; + lldb::RegularExpressionSP module_regexp; + std::vector<ConstString> symbols; + lldb::RegularExpressionSP symbol_regexp; + bool first_instruction_only; + }; + + std::deque<RegisteredEntry> m_recognizers; }; /// \class ValueObjectRecognizerSynthesizedValue @@ -145,7 +154,9 @@ class ValueObjectRecognizerSynthesizedValue : public ValueObject { SetName(parent.GetName()); } - uint64_t GetByteSize() override { return m_parent->GetByteSize(); } + llvm::Optional<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; diff --git a/contrib/llvm-project/lldb/include/lldb/Target/SystemRuntime.h b/contrib/llvm-project/lldb/include/lldb/Target/SystemRuntime.h index 4f07d7ab52e5..0ec0793e95f9 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/SystemRuntime.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/SystemRuntime.h @@ -15,6 +15,7 @@ #include "lldb/Core/PluginInterface.h" #include "lldb/Target/QueueItem.h" #include "lldb/Target/QueueList.h" +#include "lldb/Target/Runtime.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/StructuredData.h" #include "lldb/lldb-private.h" @@ -39,7 +40,7 @@ namespace lldb_private { /// can be asked to provide that information. /// -class SystemRuntime : public PluginInterface { +class SystemRuntime : public Runtime, public PluginInterface { public: /// Find a system runtime plugin for a given process. /// @@ -52,7 +53,7 @@ public: static SystemRuntime *FindPlugin(Process *process); /// Construct with a process. - SystemRuntime(lldb_private::Process *process); + SystemRuntime(Process *process); /// Destructor. /// @@ -76,7 +77,7 @@ public: /// /// Allow the SystemRuntime plugin to enable logging features in the system /// runtime libraries. - virtual void ModulesDidLoad(lldb_private::ModuleList &module_list); + virtual void ModulesDidLoad(const ModuleList &module_list) override; /// Called before detaching from a process. /// @@ -294,9 +295,6 @@ public: } protected: - // Member variables. - Process *m_process; - std::vector<ConstString> m_types; private: diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Target.h b/contrib/llvm-project/lldb/include/lldb/Target/Target.h index 280ce6359c72..69baefb964b0 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/Target.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/Target.h @@ -28,6 +28,7 @@ #include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/PathMappingList.h" #include "lldb/Target/SectionLoadHistory.h" +#include "lldb/Target/ThreadSpec.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/Broadcaster.h" #include "lldb/Utility/LLDBAssert.h" @@ -64,6 +65,12 @@ enum LoadDependentFiles { eLoadDependentsNo, }; +enum ImportStdModule { + eImportStdModuleFalse, + eImportStdModuleFallback, + eImportStdModuleTrue, +}; + class TargetExperimentalProperties : public Properties { public: TargetExperimentalProperties(); @@ -93,6 +100,10 @@ public: void SetDisableASLR(bool b); + bool GetInheritTCC() const; + + void SetInheritTCC(bool b); + bool GetDetachOnError() const; void SetDetachOnError(bool b); @@ -130,7 +141,7 @@ public: bool GetEnableAutoImportClangModules() const; - bool GetEnableImportStdModule() const; + ImportStdModule GetImportStdModule() const; bool GetEnableAutoApplyFixIts() const; @@ -168,6 +179,8 @@ public: llvm::StringRef GetExpressionPrefixContents(); + uint64_t GetExprErrorLimit() const; + bool GetUseHexImmediates() const; bool GetUseFastStepping() const; @@ -205,7 +218,7 @@ public: bool GetInjectLocalVariables(ExecutionContext *exe_ctx) const; void SetInjectLocalVariables(ExecutionContext *exe_ctx, bool b); - + void SetRequireHardwareBreakpoints(bool b); bool GetRequireHardwareBreakpoints() const; @@ -214,7 +227,6 @@ public: void UpdateLaunchInfoFromProperties(); - private: // Callbacks for m_launch_info. void Arg0ValueChangedCallback(); @@ -225,6 +237,7 @@ private: void ErrorPathValueChangedCallback(); void DetachOnErrorValueChangedCallback(); void DisableASLRValueChangedCallback(); + void InheritTCCValueChangedCallback(); void DisableSTDIOValueChangedCallback(); Environment ComputeEnvironment() const; @@ -434,6 +447,7 @@ class Target : public std::enable_shared_from_this<Target>, public ModuleList::Notifier { public: friend class TargetList; + friend class Debugger; /// Broadcaster event bits definitions. enum { @@ -503,6 +517,8 @@ public: static void SetDefaultArchitecture(const ArchSpec &arch); + bool IsDummyTarget() const { return m_is_dummy_target; } + /// Find a binary on the system and return its Module, /// or return an existing Module that is already in the Target. /// @@ -563,7 +579,8 @@ public: // used. const lldb::ProcessSP &CreateProcess(lldb::ListenerSP listener_sp, llvm::StringRef plugin_name, - const FileSpec *crash_file); + const FileSpec *crash_file, + bool can_connect); const lldb::ProcessSP &GetProcessSP() const; @@ -1064,14 +1081,10 @@ public: 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); + /// Creates and installs a UtilityFunction for the given language. + llvm::Expected<std::unique_ptr<UtilityFunction>> + CreateUtilityFunction(std::string expression, std::string name, + lldb::LanguageType language, ExecutionContext &exe_ctx); // Install any files through the platform that need be to installed prior to // launching or attaching. @@ -1097,6 +1110,20 @@ public: void ClearAllLoadedSections(); + /// Set the \a Trace object containing processor trace information of this + /// target. + /// + /// \param[in] trace_sp + /// The trace object. + void SetTrace(const lldb::TraceSP &trace_sp); + + /// Get the \a Trace object containing processor trace information of this + /// target. + /// + /// \return + /// The trace object. It might be undefined. + const lldb::TraceSP &GetTrace(); + // 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 @@ -1134,23 +1161,32 @@ public: class StopHook : public UserID { public: StopHook(const StopHook &rhs); + virtual ~StopHook() = default; - ~StopHook(); - - StringList *GetCommandPointer() { return &m_commands; } - - const StringList &GetCommands() { return m_commands; } + enum class StopHookKind : uint32_t { CommandBased = 0, ScriptBased }; + enum class StopHookResult : uint32_t { + KeepStopped = 0, + RequestContinue, + AlreadyContinued + }; 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(); } + bool ExecutionContextPasses(const ExecutionContext &exe_ctx); + + // Called on stop, this gets passed the ExecutionContext for each "stop + // with a reason" thread. It should add to the stream whatever text it + // wants to show the user, and return False to indicate it wants the target + // not to stop. + virtual StopHookResult HandleStop(ExecutionContext &exe_ctx, + lldb::StreamSP output) = 0; + // 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); @@ -1168,28 +1204,84 @@ public: bool GetAutoContinue() const { return m_auto_continue; } void GetDescription(Stream *s, lldb::DescriptionLevel level) const; + virtual void GetSubclassDescription(Stream *s, + lldb::DescriptionLevel level) const = 0; - private: + protected: 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; + StopHook(lldb::TargetSP target_sp, lldb::user_id_t uid); + }; + + class StopHookCommandLine : public StopHook { + public: + virtual ~StopHookCommandLine() = default; + + StringList &GetCommands() { return m_commands; } + void SetActionFromString(const std::string &strings); + void SetActionFromStrings(const std::vector<std::string> &strings); + + StopHookResult HandleStop(ExecutionContext &exc_ctx, + lldb::StreamSP output_sp) override; + void GetSubclassDescription(Stream *s, + lldb::DescriptionLevel level) const override; + + private: + StringList m_commands; // 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); + StopHookCommandLine(lldb::TargetSP target_sp, lldb::user_id_t uid) + : StopHook(target_sp, uid) {} + friend class Target; + }; + + class StopHookScripted : public StopHook { + public: + virtual ~StopHookScripted() = default; + StopHookResult HandleStop(ExecutionContext &exc_ctx, + lldb::StreamSP output) override; + + Status SetScriptCallback(std::string class_name, + StructuredData::ObjectSP extra_args_sp); + + void GetSubclassDescription(Stream *s, + lldb::DescriptionLevel level) const override; + + private: + std::string m_class_name; + /// This holds the dictionary of keys & values that can be used to + /// parametrize any given callback's behavior. + StructuredDataImpl *m_extra_args; // We own this structured data, + // but the SD itself manages the UP. + /// This holds the python callback object. + StructuredData::GenericSP m_implementation_sp; + + /// 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.) + StopHookScripted(lldb::TargetSP target_sp, lldb::user_id_t uid) + : StopHook(target_sp, 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(); + /// 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(StopHook::StopHookKind kind); + + /// If you tried to create a stop hook, and that failed, call this to + /// remove the stop hook, as it will also reset the stop hook counter. + void UndoCreateStopHook(lldb::user_id_t uid); - void RunStopHooks(); + // Runs the stop hooks that have been registered for this target. + // Returns true if the stop hooks cause the target to resume. + bool RunStopHooks(); size_t GetStopHookSize(); @@ -1251,6 +1343,10 @@ public: void SetREPL(lldb::LanguageType language, lldb::REPLSP repl_sp); + StackFrameRecognizerManager &GetFrameRecognizerManager() { + return *m_frame_recognizer_manager_up; + } + protected: /// Implementing of ModuleList::Notifier. @@ -1285,12 +1381,12 @@ protected: 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 - /// When the private state thread calls SB API's - usually because it is + /// When the private state thread calls SB API's - usually because it is /// running OS plugin or Python ThreadPlan code - it should not block on the /// API mutex that is held by the code that kicked off the sequence of events - /// that led us to run the code. We hand out this mutex instead when we + /// that led us to run the code. We hand out this mutex instead when we /// detect that code is running on the private state thread. - std::recursive_mutex m_private_mutex; + std::recursive_mutex m_private_mutex; Arch m_arch; ModuleList m_images; ///< The list of images for this process (shared /// libraries and anything dynamically loaded). @@ -1325,6 +1421,11 @@ protected: bool m_suppress_stop_hooks; bool m_is_dummy_target; unsigned m_next_persistent_variable_index = 0; + /// An optional \a lldb_private::Trace object containing processor trace + /// information of this target. + lldb::TraceSP m_trace_sp; + /// Stores the frame recognizers of this target. + lldb::StackFrameRecognizerManagerUP m_frame_recognizer_manager_up; static void ImageSearchPathsChanged(const PathMappingList &path_list, void *baton); @@ -1364,7 +1465,7 @@ private: bool ProcessIsValid(); // Copy breakpoints, stop hooks and so forth from the dummy target: - void PrimeFromDummyTarget(Target *dummy_target); + void PrimeFromDummyTarget(Target &target); void AddBreakpoint(lldb::BreakpointSP breakpoint_sp, bool internal); diff --git a/contrib/llvm-project/lldb/include/lldb/Target/TargetList.h b/contrib/llvm-project/lldb/include/lldb/Target/TargetList.h index 5ed0344f175c..903ca4bcefbc 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/TargetList.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/TargetList.h @@ -42,8 +42,6 @@ public: return GetStaticBroadcasterClass(); } - ~TargetList() override; - /// Create a new Target. /// /// Clients must use this function to create a Target. This allows @@ -175,7 +173,9 @@ public: uint32_t SignalIfRunning(lldb::pid_t pid, int signo); - uint32_t SetSelectedTarget(Target *target); + void SetSelectedTarget(uint32_t index); + + void SetSelectedTarget(const lldb::TargetSP &target); lldb::TargetSP GetSelectedTarget(); @@ -183,28 +183,25 @@ 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); + static 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); + + static Status CreateTargetInternal(Debugger &debugger, + llvm::StringRef user_exe_path, + const ArchSpec &arch, + LoadDependentFiles get_dependent_modules, + lldb::PlatformSP &platform_sp, + lldb::TargetSP &target_sp); + + void AddTargetInternal(lldb::TargetSP target_sp, bool do_select); + + void SetSelectedTargetInternal(uint32_t index); TargetList(const TargetList &) = delete; const TargetList &operator=(const TargetList &) = delete; diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Thread.h b/contrib/llvm-project/lldb/include/lldb/Target/Thread.h index 205a0d965c63..4b148063ec6e 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/Thread.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/Thread.h @@ -19,6 +19,7 @@ #include "lldb/Target/RegisterCheckpoint.h" #include "lldb/Target/StackFrameList.h" #include "lldb/Utility/Broadcaster.h" +#include "lldb/Utility/CompletionRequest.h" #include "lldb/Utility/Event.h" #include "lldb/Utility/StructuredData.h" #include "lldb/Utility/UserID.h" @@ -253,9 +254,9 @@ public: bool ThreadStoppedForAReason(); - static const char *RunModeAsCString(lldb::RunMode mode); + static std::string RunModeAsString(lldb::RunMode mode); - static const char *StopReasonAsCString(lldb::StopReason reason); + static std::string StopReasonAsString(lldb::StopReason reason); virtual const char *GetInfo() { return nullptr; } @@ -468,6 +469,24 @@ public: // the backing thread for all memory threads each time we stop. } + /// Dump \a count instructions of the thread's \a Trace starting at the \a + /// start_position position in reverse order. + /// + /// The instructions are indexed in reverse order, which means that the \a + /// start_position 0 represents the last instruction of the trace + /// chronologically. + /// + /// \param[in] s + /// The stream object where the instructions are printed. + /// + /// \param[in] count + /// The number of instructions to print. + /// + /// \param[in] start_position + /// The position of the first instruction to print. + void DumpTraceInstructions(Stream &s, size_t count, + size_t start_position = 0) const; + // 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, @@ -911,6 +930,12 @@ public: // Thread Plan accessors: + /// Format the thread plan information for auto completion. + /// + /// \param[in] request + /// The reference to the completion handler. + void AutoCompleteThreadPlans(CompletionRequest &request) const; + /// Gets the plan which will execute next on the plan stack. /// /// \return diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlan.h b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlan.h index 8c2f9776eeb3..242a4d3c2d6c 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlan.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlan.h @@ -23,310 +23,260 @@ 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. +// 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 +// 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. +// 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 +// 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. +// 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. +// 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. +// 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: +// "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 +// 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. +// 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. +// 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: +// 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. +// 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. +// 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. +// 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. +// 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. +// 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. +// 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 +// 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, +// 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 +// 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. +// 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 example 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. +// 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 +// example 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. +// 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. +// 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. +// 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. +// 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. -// +// "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 { @@ -375,6 +325,12 @@ public: const Target &GetTarget() const; + /// Clear the Thread* cache. + /// + /// This is useful in situations like when a new Thread list is being + /// generated. + void ClearThreadCache(); + /// Print a description of this thread to the stream \a s. /// \a thread. Don't expect that the result of GetThread is valid in /// the description method. This might get called when the underlying diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanPython.h b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanPython.h index 27bf3a560b1f..7b37b2b9ce5a 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanPython.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanPython.h @@ -45,7 +45,9 @@ public: bool WillStop() override; - bool StopOthers() override; + bool StopOthers() override { return m_stop_others; } + + void SetStopOthers(bool new_value) override { m_stop_others = new_value; } void DidPush() override; @@ -67,6 +69,7 @@ private: std::string m_error_str; StructuredData::ObjectSP m_implementation_sp; bool m_did_push; + bool m_stop_others; ThreadPlanPython(const ThreadPlanPython &) = delete; const ThreadPlanPython &operator=(const ThreadPlanPython &) = delete; diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStack.h b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStack.h index f1874136cad8..7b2817b2e8fd 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStack.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStack.h @@ -35,8 +35,6 @@ public: ThreadPlanStack(const Thread &thread, bool make_empty = false); ~ThreadPlanStack() {} - enum StackKind { ePlans, eCompletedPlans, eDiscardedPlans }; - using PlanStack = std::vector<lldb::ThreadPlanSP>; void DumpThreadPlans(Stream &s, lldb::DescriptionLevel desc_level, @@ -95,9 +93,13 @@ public: void WillResume(); -private: - const PlanStack &GetStackOfKind(ThreadPlanStack::StackKind kind) const; + /// Clear the Thread* cache that each ThreadPlan contains. + /// + /// This is useful in situations like when a new Thread list is being + /// generated. + void ClearThreadCache(); +private: void PrintOneStack(Stream &s, llvm::StringRef stack_name, const PlanStack &stack, lldb::DescriptionLevel desc_level, bool include_internal) const; @@ -145,6 +147,15 @@ public: return &result->second; } + /// Clear the Thread* cache that each ThreadPlan contains. + /// + /// This is useful in situations like when a new Thread list is being + /// generated. + void ClearThreadCache() { + for (auto &plan_list : m_plans_list) + plan_list.second.ClearThreadCache(); + } + void Clear() { for (auto plan : m_plans_list) plan.second.ThreadDestroyed(nullptr); diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStepInRange.h b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStepInRange.h index 59b5721998b5..a26b0fb87b3a 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStepInRange.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStepInRange.h @@ -26,13 +26,6 @@ public: 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; @@ -78,17 +71,6 @@ protected: 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 diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ThreadTrace.h b/contrib/llvm-project/lldb/include/lldb/Target/ThreadTrace.h new file mode 100644 index 000000000000..a32b33867c26 --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Target/ThreadTrace.h @@ -0,0 +1,61 @@ +//===-- ThreadTrace.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_THREADTRACE_H +#define LLDB_TARGET_THREADTRACE_H + +#include "lldb/Target/Thread.h" + +namespace lldb_private { + +/// \class ThreadTrace ThreadTrace.h +/// +/// Thread implementation used for representing threads gotten from trace +/// session files, which are similar to threads from core files. +/// +/// See \a TraceSessionFileParser for more information regarding trace session +/// files. +class ThreadTrace : public Thread { +public: + /// \param[in] process + /// The process who owns this thread. + /// + /// \param[in] tid + /// The tid of this thread. + /// + /// \param[in] trace_file. + /// The file that contains the list of instructions that were traced when + /// this thread was being executed. + ThreadTrace(Process &process, lldb::tid_t tid, const FileSpec &trace_file) + : Thread(process, tid), m_trace_file(trace_file) {} + + void RefreshStateAfterStop() override; + + lldb::RegisterContextSP GetRegisterContext() override; + + lldb::RegisterContextSP + CreateRegisterContextForFrame(StackFrame *frame) override; + + /// \return + /// The trace file of this thread. + const FileSpec &GetTraceFile() const; + +protected: + bool CalculateStopInfo() override; + + lldb::RegisterContextSP m_thread_reg_ctx_sp; + +private: + FileSpec m_trace_file; +}; + +typedef std::shared_ptr<ThreadTrace> ThreadTraceSP; + +} // namespace lldb_private + +#endif // LLDB_TARGET_THREADTRACE_H diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Trace.h b/contrib/llvm-project/lldb/include/lldb/Target/Trace.h new file mode 100644 index 000000000000..3b127916a917 --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Target/Trace.h @@ -0,0 +1,203 @@ +//===-- Trace.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_TRACE_H +#define LLDB_TARGET_TRACE_H + +#include "llvm/Support/JSON.h" + +#include "lldb/Core/PluginInterface.h" +#include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/UnimplementedError.h" +#include "lldb/lldb-private.h" + +namespace lldb_private { + +/// \class Trace Trace.h "lldb/Target/Trace.h" +/// A plug-in interface definition class for trace information. +/// +/// Trace plug-ins allow processor trace information to be loaded into LLDB so +/// that the data can be dumped, used for reverse and forward stepping to allow +/// introspection into the reason your process crashed or found its way to its +/// current state. +/// +/// Trace information can be loaded into a target without a process to allow +/// introspection of the trace information during post mortem analysis, such as +/// when loading core files. +/// +/// Processor trace information can also be fetched through the process +/// interfaces during a live debug session if your process supports gathering +/// this information. +/// +/// In order to support live tracing, the name of the plug-in should match the +/// name of the tracing type returned by the gdb-remote packet +/// \a jLLDBTraceSupportedType. +class Trace : public PluginInterface, + public std::enable_shared_from_this<Trace> { +public: + enum class TraceDirection { + Forwards = 0, + Backwards, + }; + + /// Dump the trace data that this plug-in has access to. + /// + /// This function will dump all of the trace data for all threads in a user + /// readable format. Options for dumping can be added as this API is iterated + /// on. + /// + /// \param[in] s + /// A stream object to dump the information to. + virtual void Dump(Stream *s) const = 0; + + /// Find a trace plug-in using JSON data. + /// + /// When loading trace data from disk, the information for the trace data + /// can be contained in multiple files and require plug-in specific + /// information about the CPU. Using data like JSON provides an + /// easy way to specify all of the settings and information that we will need + /// to load trace data into LLDB. This structured data can include: + /// - The plug-in name (this allows a specific plug-in to be selected) + /// - Architecture or target triple + /// - one or more paths to the trace data file on disk + /// - core trace data + /// - thread events or related information + /// - shared library load information to use for this trace data that + /// allows a target to be created so the trace information can be + /// symbolicated so that the trace information can be displayed to the + /// user + /// - shared library path + /// - load address + /// - information on how to fetch the shared library + /// - path to locally cached file on disk + /// - URL to download the file + /// - Any information needed to load the trace file + /// - CPU information + /// - Custom plug-in information needed to decode the trace information + /// correctly. + /// + /// \param[in] debugger + /// The debugger instance where new Targets will be created as part of the + /// JSON data parsing. + /// + /// \param[in] trace_session_file + /// The contents of the trace session file describing the trace session. + /// See \a TraceSessionFileParser::BuildSchema for more information about + /// the schema of this JSON file. + /// + /// \param[in] session_file_dir + /// The path to the directory that contains the session file. It's used to + /// resolved relative paths in the session file. + static llvm::Expected<lldb::TraceSP> + FindPlugin(Debugger &debugger, const llvm::json::Value &trace_session_file, + llvm::StringRef session_file_dir); + + /// Get the schema of a Trace plug-in given its name. + /// + /// \param[in] plugin_name + /// Name of the trace plugin. + static llvm::Expected<llvm::StringRef> + FindPluginSchema(llvm::StringRef plugin_name); + + /// \return + /// The JSON schema of this Trace plug-in. + virtual llvm::StringRef GetSchema() = 0; + + /// Each decoded thread contains a cursor to the current position the user is + /// stopped at. When reverse debugging, each operation like reverse-next or + /// reverse-continue will move this cursor, which is then picked by any + /// subsequent dump or reverse operation. + /// + /// The initial position for this cursor is the last element of the thread, + /// which is the most recent chronologically. + /// + /// \return + /// The current position of the thread's trace or \b 0 if empty. + virtual size_t GetCursorPosition(const Thread &thread) = 0; + + /// Dump \a count instructions of the given thread's trace ending at the + /// given \a end_position position. + /// + /// The instructions are printed along with their indices or positions, which + /// are increasing chronologically. This means that the \a index 0 represents + /// the oldest instruction of the trace chronologically. + /// + /// \param[in] thread + /// The thread whose trace will be dumped. + /// + /// \param[in] s + /// The stream object where the instructions are printed. + /// + /// \param[in] count + /// The number of instructions to print. + /// + /// \param[in] end_position + /// The position of the last instruction to print. + /// + /// \param[in] raw + /// Dump only instruction addresses without disassembly nor symbol + /// information. + void DumpTraceInstructions(Thread &thread, Stream &s, size_t count, + size_t end_position, bool raw); + + /// Run the provided callback on the instructions of the trace of the given + /// thread. + /// + /// The instructions will be traversed starting at the given \a position + /// sequentially until the callback returns \b false, in which case no more + /// instructions are inspected. + /// + /// The purpose of this method is to allow inspecting traced instructions + /// without exposing the internal representation of how they are stored on + /// memory. + /// + /// \param[in] thread + /// The thread whose trace will be traversed. + /// + /// \param[in] position + /// The instruction position to start iterating on. + /// + /// \param[in] direction + /// If \b TraceDirection::Forwards, then then instructions will be + /// traversed forwards chronologically, i.e. with incrementing indices. If + /// \b TraceDirection::Backwards, the traversal is done backwards + /// chronologically, i.e. with decrementing indices. + /// + /// \param[in] callback + /// The callback to execute on each instruction. If it returns \b false, + /// the iteration stops. + virtual void TraverseInstructions( + const Thread &thread, size_t position, TraceDirection direction, + std::function<bool(size_t index, llvm::Expected<lldb::addr_t> load_addr)> + callback) = 0; + + /// Stop tracing a live thread + /// + /// \param[in] thread + /// The thread object to stop tracing. + /// + /// \return + /// An \a llvm::Error if stopping tracing failed, or \b + /// llvm::Error::success() otherwise. + virtual llvm::Error StopTracingThread(const Thread &thread) { + return llvm::make_error<UnimplementedError>(); + } + + /// Get the number of available instructions in the trace of the given thread. + /// + /// \param[in] thread + /// The thread whose trace will be inspected. + /// + /// \return + /// The total number of instructions in the trace. + virtual size_t GetInstructionCount(const Thread &thread) = 0; +}; + +} // namespace lldb_private + +#endif // LLDB_TARGET_TRACE_H diff --git a/contrib/llvm-project/lldb/include/lldb/Target/TraceSessionFileParser.h b/contrib/llvm-project/lldb/include/lldb/Target/TraceSessionFileParser.h new file mode 100644 index 000000000000..52cc27c1a485 --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Target/TraceSessionFileParser.h @@ -0,0 +1,179 @@ +//===-- TraceSessionFileParser.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_TRACESESSIONPARSER_H +#define LLDB_TARGET_TRACESESSIONPARSER_H + +#include "llvm/Support/JSON.h" + +#include "lldb/Target/ThreadTrace.h" + +namespace lldb_private { + +/// \class TraceSessionFileParser TraceSessionFileParser.h +/// +/// Base class for parsing the common information of JSON trace session files. +/// Contains the basic C++ structs that represent the JSON data, which include +/// \a JSONTraceSession as the root object. +/// +/// See \a Trace::FindPlugin for more information regarding these JSON files. +class TraceSessionFileParser { +public: + /// C++ structs representing the JSON trace session. + /// \{ + struct JSONAddress { + lldb::addr_t value; + }; + + struct JSONModule { + std::string system_path; + llvm::Optional<std::string> file; + JSONAddress load_address; + llvm::Optional<std::string> uuid; + }; + + struct JSONThread { + int64_t tid; + std::string trace_file; + }; + + struct JSONProcess { + int64_t pid; + std::string triple; + std::vector<JSONThread> threads; + std::vector<JSONModule> modules; + }; + + struct JSONTracePluginSettings { + std::string type; + }; + + struct JSONTraceSessionBase { + std::vector<JSONProcess> processes; + }; + + /// The trace plug-in implementation should provide its own TPluginSettings, + /// which corresponds to the "trace" section of the schema. + template <class TPluginSettings> + struct JSONTraceSession : JSONTraceSessionBase { + TPluginSettings trace; + }; + /// \} + + /// Helper struct holding the objects created when parsing a process + struct ParsedProcess { + lldb::TargetSP target_sp; + std::vector<ThreadTraceSP> threads; + }; + + TraceSessionFileParser(Debugger &debugger, llvm::StringRef session_file_dir, + llvm::StringRef schema) + : m_debugger(debugger), m_session_file_dir(session_file_dir), + m_schema(schema) {} + + /// Build the full schema for a Trace plug-in. + /// + /// \param[in] plugin_schema + /// The subschema that corresponds to the "trace" section of the schema. + /// + /// \return + /// The full schema containing the common attributes and the plug-in + /// specific attributes. + static std::string BuildSchema(llvm::StringRef plugin_schema); + + /// Parse the fields common to all trace session schemas. + /// + /// \param[in] session + /// The session json objects already deserialized. + /// + /// \return + /// A list of \a ParsedProcess containing all threads and targets created + /// during the parsing, or an error in case of failures. In case of + /// errors, no side effects are produced. + llvm::Expected<std::vector<ParsedProcess>> + ParseCommonSessionFile(const JSONTraceSessionBase &session); + +protected: + /// Resolve non-absolute paths relative to the session file folder. It + /// modifies the given file_spec. + void NormalizePath(lldb_private::FileSpec &file_spec); + + ThreadTraceSP ParseThread(lldb::ProcessSP &process_sp, + const JSONThread &thread); + + llvm::Expected<ParsedProcess> ParseProcess(const JSONProcess &process); + + llvm::Error ParseModule(lldb::TargetSP &target_sp, const JSONModule &module); + + /// Create a user-friendly error message upon a JSON-parsing failure using the + /// \a json::ObjectMapper functionality. + /// + /// \param[in] root + /// The \a llvm::json::Path::Root used to parse the JSON \a value. + /// + /// \param[in] value + /// The json value that failed to parse. + /// + /// \return + /// An \a llvm::Error containing the user-friendly error message. + llvm::Error CreateJSONError(llvm::json::Path::Root &root, + const llvm::json::Value &value); + + Debugger &m_debugger; + std::string m_session_file_dir; + llvm::StringRef m_schema; +}; +} // namespace lldb_private + +namespace llvm { +namespace json { + +bool fromJSON(const Value &value, + lldb_private::TraceSessionFileParser::JSONAddress &address, + Path path); + +bool fromJSON(const Value &value, + lldb_private::TraceSessionFileParser::JSONModule &module, + Path path); + +bool fromJSON(const Value &value, + lldb_private::TraceSessionFileParser::JSONThread &thread, + Path path); + +bool fromJSON(const Value &value, + lldb_private::TraceSessionFileParser::JSONProcess &process, + Path path); + +bool fromJSON(const Value &value, + lldb_private::TraceSessionFileParser::JSONTracePluginSettings + &plugin_settings, + Path path); + +bool fromJSON( + const Value &value, + lldb_private::TraceSessionFileParser::JSONTraceSessionBase &session, + Path path); + +template <class TPluginSettings> +bool fromJSON( + const Value &value, + lldb_private::TraceSessionFileParser::JSONTraceSession<TPluginSettings> + &session, + Path path) { + ObjectMapper o(value, path); + return o && o.map("trace", session.trace) && + fromJSON(value, + (lldb_private::TraceSessionFileParser::JSONTraceSessionBase &) + session, + path); +} + +} // namespace json +} // namespace llvm + +#endif // LLDB_TARGET_TRACESESSIONPARSER_H diff --git a/contrib/llvm-project/lldb/include/lldb/Target/UnwindAssembly.h b/contrib/llvm-project/lldb/include/lldb/Target/UnwindAssembly.h index abfd38774399..d20aa52d6f59 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/UnwindAssembly.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/UnwindAssembly.h @@ -20,8 +20,6 @@ class UnwindAssembly : public std::enable_shared_from_this<UnwindAssembly>, public: static lldb::UnwindAssemblySP FindPlugin(const ArchSpec &arch); - ~UnwindAssembly() override; - virtual bool GetNonCallSiteUnwindPlanFromAssembly(AddressRange &func, Thread &thread, UnwindPlan &unwind_plan) = 0; @@ -42,11 +40,6 @@ public: protected: UnwindAssembly(const ArchSpec &arch); ArchSpec m_arch; - -private: - UnwindAssembly() = delete; - UnwindAssembly(const UnwindAssembly &) = delete; - const UnwindAssembly &operator=(const UnwindAssembly &) = delete; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/ArchSpec.h b/contrib/llvm-project/lldb/include/lldb/Utility/ArchSpec.h index 5466e573c1a5..fdfe6aceb033 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/ArchSpec.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/ArchSpec.h @@ -92,6 +92,12 @@ public: eARM_abi_hard_float = 0x00000400 }; + enum RISCVSubType { + eRISCVSubType_unknown, + eRISCVSubType_riscv32, + eRISCVSubType_riscv64, + }; + enum Core { eCore_arm_generic, eCore_arm_armv4, @@ -125,6 +131,7 @@ public: eCore_arm_arm64, eCore_arm_armv8, eCore_arm_armv8l, + eCore_arm_arm64e, eCore_arm_arm64_32, eCore_arm_aarch64, @@ -184,6 +191,9 @@ public: eCore_hexagon_hexagonv4, eCore_hexagon_hexagonv5, + eCore_riscv32, + eCore_riscv64, + eCore_uknownMach32, eCore_uknownMach64, @@ -505,7 +515,7 @@ public: void SetFlags(uint32_t flags) { m_flags = flags; } - void SetFlags(std::string elf_abi); + void SetFlags(const std::string &elf_abi); protected: bool IsEqualTo(const ArchSpec &rhs, bool exact_match) const; diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Args.h b/contrib/llvm-project/lldb/include/lldb/Utility/Args.h index 2cce7d0c697c..b93677b53935 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/Args.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/Args.h @@ -66,6 +66,7 @@ public: Args(const Args &rhs); explicit Args(const StringList &list); + explicit Args(llvm::ArrayRef<llvm::StringRef> args); Args &operator=(const Args &rhs); @@ -262,9 +263,8 @@ public: static uint32_t StringToGenericRegister(llvm::StringRef s); - static const char *GetShellSafeArgument(const FileSpec &shell, - const char *unsafe_arg, - std::string &safe_arg); + static std::string GetShellSafeArgument(const FileSpec &shell, + llvm::StringRef unsafe_arg); // EncodeEscapeSequences will change the textual representation of common // escape sequences like "\n" (two characters) into a single '\n'. It does diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Broadcaster.h b/contrib/llvm-project/lldb/include/lldb/Utility/Broadcaster.h index 03995454ecb0..9c025a7c7dd8 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/Broadcaster.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/Broadcaster.h @@ -39,7 +39,7 @@ namespace lldb_private { /// Debugger maintains a list of BroadcastEventSpec's and when it is made class BroadcastEventSpec { public: - BroadcastEventSpec(ConstString broadcaster_class, uint32_t event_bits) + BroadcastEventSpec(const ConstString &broadcaster_class, uint32_t event_bits) : m_broadcaster_class(broadcaster_class), m_event_bits(event_bits) {} ~BroadcastEventSpec() = default; @@ -117,7 +117,7 @@ private: class BroadcasterClassMatches { public: - BroadcasterClassMatches(ConstString broadcaster_class) + BroadcasterClassMatches(const ConstString &broadcaster_class) : m_broadcaster_class(broadcaster_class) {} ~BroadcasterClassMatches() = default; diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/ConstString.h b/contrib/llvm-project/lldb/include/lldb/Utility/ConstString.h index 1e55b2ebb957..8a67faf5b54a 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/ConstString.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/ConstString.h @@ -42,15 +42,7 @@ public: /// Default constructor /// /// Initializes the string to an empty string. - ConstString() : m_string(nullptr) {} - - /// Copy constructor - /// - /// Copies the string value in \a rhs into this object. - /// - /// \param[in] rhs - /// Another string object to copy. - ConstString(const ConstString &rhs) : m_string(rhs.m_string) {} + ConstString() = default; explicit ConstString(const llvm::StringRef &s); @@ -86,12 +78,6 @@ public: /// from \a cstr. explicit ConstString(const char *cstr, size_t max_cstr_len); - /// Destructor - /// - /// Since constant string values are currently not reference counted, there - /// isn't much to do here. - ~ConstString() = default; - /// C string equality binary predicate function object for ConstString /// objects. struct StringIsEqual { @@ -124,20 +110,6 @@ public: /// false otherwise. explicit operator bool() const { return !IsEmpty(); } - /// Assignment operator - /// - /// Assigns the string in this object with the value from \a rhs. - /// - /// \param[in] rhs - /// Another string object to copy into this object. - /// - /// \return - /// A const reference to this object. - ConstString operator=(ConstString rhs) { - m_string = rhs.m_string; - return *this; - } - /// Equal to operator /// /// Returns true if this string is equal to the string in \a rhs. This @@ -192,9 +164,7 @@ public: /// \return /// \b true if this object is not equal to \a rhs. /// \b false if this object is equal to \a rhs. - bool operator!=(ConstString rhs) const { - return m_string != rhs.m_string; - } + bool operator!=(ConstString rhs) const { return m_string != rhs.m_string; } /// Not equal to operator against a non-ConstString value. /// @@ -447,8 +417,7 @@ protected: return s; }; - // Member variables - const char *m_string; + const char *m_string = nullptr; }; /// Stream the string value \a str to the stream \a s diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/GDBRemote.h b/contrib/llvm-project/lldb/include/lldb/Utility/GDBRemote.h index f5749b7e6eaf..2ee706efbea2 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/GDBRemote.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/GDBRemote.h @@ -10,7 +10,7 @@ #define LLDB_UTILITY_GDBREMOTE_H #include "lldb/Utility/FileSpec.h" -#include "lldb/Utility/Reproducer.h" +#include "lldb/Utility/ReproducerProvider.h" #include "lldb/Utility/StreamString.h" #include "lldb/lldb-enumerations.h" #include "lldb/lldb-public.h" diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Iterable.h b/contrib/llvm-project/lldb/include/lldb/Utility/Iterable.h index 3f9b8b1e4c57..5c38e46feb92 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/Iterable.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/Iterable.h @@ -170,7 +170,7 @@ template <typename C, typename E, E (*A)(typename C::const_iterator &), typename MutexType> class LockingAdaptedIterable : public AdaptedIterable<C, E, A> { public: - LockingAdaptedIterable(C &container, MutexType &mutex) + LockingAdaptedIterable(const C &container, MutexType &mutex) : AdaptedIterable<C, E, A>(container), m_mutex(&mutex) { m_mutex->lock(); } diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/OptionDefinition.h b/contrib/llvm-project/lldb/include/lldb/Utility/OptionDefinition.h new file mode 100644 index 000000000000..082f0f0aa3fa --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Utility/OptionDefinition.h @@ -0,0 +1,58 @@ +//===-- OptionDefinition.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_UTILITY_OPTIONDEFINITION_H +#define LLDB_UTILITY_OPTIONDEFINITION_H + +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-private-types.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/Support/MathExtras.h" +#include <climits> +#include <cstdint> + +namespace lldb_private { +struct OptionDefinition { + /// Used to mark options that can be used together. If + /// `(1 << n & usage_mask) != 0` then this option belongs to option set n. + uint32_t usage_mask; + /// This option is required (in the current usage level). + bool required; + /// Full name for this option. + const char *long_option; + /// Single character for this option. If the option doesn't use a short + /// option character, this has to be a integer value that is not a printable + /// ASCII code point and also unique in the used set of options. + /// @see OptionDefinition::HasShortOption + int short_option; + /// no_argument, required_argument or optional_argument + int option_has_arg; + /// If non-NULL, option is valid iff |validator->IsValid()|, otherwise + /// always valid. + OptionValidator *validator; + /// If not empty, an array of enum values. + OptionEnumValues enum_values; + /// The kind of completion for this option. + /// Contains values of the CommandCompletions::CommonCompletionTypes enum. + uint32_t completion_type; + /// Type of argument this option takes. + lldb::CommandArgumentType argument_type; + /// Full text explaining what this options does and what (if any) argument to + /// pass it. + const char *usage_text; + + /// Whether this has a short option character. + bool HasShortOption() const { + // See the short_option documentation for more. + return llvm::isUInt<CHAR_BIT>(short_option) && + llvm::isPrint(short_option); + } +}; +} // namespace lldb_private + +#endif // LLDB_UTILITY_OPTIONDEFINITION_H diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/ProcessInfo.h b/contrib/llvm-project/lldb/include/lldb/Utility/ProcessInfo.h index ec91060cda54..8f5a5f6d21fb 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/ProcessInfo.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/ProcessInfo.h @@ -14,7 +14,6 @@ #include "lldb/Utility/Environment.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/NameMatches.h" -#include "lldb/Utility/Reproducer.h" #include "llvm/Support/YAMLTraits.h" #include <vector> @@ -217,40 +216,7 @@ protected: }; namespace repro { -class ProcessInfoRecorder : public AbstractRecorder { -public: - ProcessInfoRecorder(const FileSpec &filename, std::error_code &ec) - : AbstractRecorder(filename, ec) {} - - static llvm::Expected<std::unique_ptr<ProcessInfoRecorder>> - Create(const FileSpec &filename); - - void Record(const ProcessInstanceInfoList &process_infos); -}; - -class ProcessInfoProvider : public repro::Provider<ProcessInfoProvider> { -public: - struct Info { - static const char *name; - static const char *file; - }; - - ProcessInfoProvider(const FileSpec &directory) : Provider(directory) {} - - ProcessInfoRecorder *GetNewProcessInfoRecorder(); - - void Keep() override; - void Discard() override; - - static char ID; - -private: - std::unique_ptr<llvm::raw_fd_ostream> m_stream_up; - std::vector<std::unique_ptr<ProcessInfoRecorder>> m_process_info_recorders; -}; - llvm::Optional<ProcessInstanceInfoList> GetReplayProcessInstanceInfoList(); - } // namespace repro } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/RangeMap.h b/contrib/llvm-project/lldb/include/lldb/Utility/RangeMap.h index fb24c5a43479..118fdfd85fa9 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/RangeMap.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/RangeMap.h @@ -194,41 +194,25 @@ public: #ifdef ASSERT_RANGEMAP_ARE_SORTED assert(IsSorted()); #endif - // Can't combine if ranges if we have zero or one range - if (m_entries.size() > 1) { - // The list should be sorted prior to calling this function - typename Collection::iterator pos; - typename Collection::iterator end; - typename Collection::iterator prev; - bool can_combine = false; - // First we determine if we can combine any of the Entry objects so we - // don't end up allocating and making a new collection for no reason - for (pos = m_entries.begin(), end = m_entries.end(), prev = end; - pos != end; prev = pos++) { - if (prev != end && prev->DoesAdjoinOrIntersect(*pos)) { - can_combine = true; - break; - } - } + auto first_intersect = std::adjacent_find( + m_entries.begin(), m_entries.end(), [](const Entry &a, const Entry &b) { + return a.DoesAdjoinOrIntersect(b); + }); + if (first_intersect == m_entries.end()) + return; - // We we can combine at least one entry, then we make a new collection - // and populate it accordingly, and then swap it into place. - if (can_combine) { - Collection minimal_ranges; - for (pos = m_entries.begin(), end = m_entries.end(), prev = end; - pos != end; prev = pos++) { - if (prev != end && prev->DoesAdjoinOrIntersect(*pos)) - minimal_ranges.back().SetRangeEnd( - std::max<BaseType>(prev->GetRangeEnd(), pos->GetRangeEnd())); - else - minimal_ranges.push_back(*pos); - } - // Use the swap technique in case our new vector is much smaller. We - // must swap when using the STL because std::vector objects never - // release or reduce the memory once it has been allocated/reserved. - m_entries.swap(minimal_ranges); - } + // We we can combine at least one entry, then we make a new collection and + // populate it accordingly, and then swap it into place. + auto pos = std::next(first_intersect); + Collection minimal_ranges(m_entries.begin(), pos); + for (; pos != m_entries.end(); ++pos) { + Entry &back = minimal_ranges.back(); + if (back.DoesAdjoinOrIntersect(*pos)) + back.SetRangeEnd(std::max(back.GetRangeEnd(), pos->GetRangeEnd())); + else + minimal_ranges.push_back(*pos); } + m_entries.swap(minimal_ranges); } BaseType GetMinRangeBase(BaseType fail_value) const { @@ -353,6 +337,10 @@ public: return nullptr; } + using const_iterator = typename Collection::const_iterator; + const_iterator begin() const { return m_entries.begin(); } + const_iterator end() const { return m_entries.end(); } + protected: void CombinePrevAndNext(typename Collection::iterator pos) { // Check if the prev or next entries in case they need to be unioned with diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/RegisterValue.h b/contrib/llvm-project/lldb/include/lldb/Utility/RegisterValue.h index c9f295a8d95a..4211b0a59992 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/RegisterValue.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/RegisterValue.h @@ -18,6 +18,7 @@ #include "llvm/ADT/StringRef.h" #include <cstdint> #include <cstring> +#include <utility> namespace lldb_private { class DataExtractor; @@ -60,7 +61,7 @@ public: } explicit RegisterValue(llvm::APInt inst) : m_type(eTypeUInt128) { - m_scalar = llvm::APInt(inst); + m_scalar = llvm::APInt(std::move(inst)); } explicit RegisterValue(float value) : m_type(eTypeFloat) { m_scalar = value; } @@ -73,9 +74,9 @@ public: m_scalar = value; } - explicit RegisterValue(uint8_t *bytes, size_t length, + explicit RegisterValue(llvm::ArrayRef<uint8_t> bytes, lldb::ByteOrder byte_order) { - SetBytes(bytes, length, byte_order); + SetBytes(bytes.data(), bytes.size(), byte_order); } RegisterValue::Type GetType() const { return m_type; } @@ -169,7 +170,7 @@ public: void operator=(llvm::APInt uint) { m_type = eTypeUInt128; - m_scalar = llvm::APInt(uint); + m_scalar = llvm::APInt(std::move(uint)); } void operator=(float f) { @@ -209,7 +210,7 @@ public: void SetUInt128(llvm::APInt uint) { m_type = eTypeUInt128; - m_scalar = uint; + m_scalar = std::move(uint); } bool SetUInt(uint64_t uint, uint32_t byte_size); diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Reproducer.h b/contrib/llvm-project/lldb/include/lldb/Utility/Reproducer.h index ab673e5e0019..4659254e57d6 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/Reproducer.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/Reproducer.h @@ -11,15 +11,18 @@ #include "lldb/Utility/FileSpec.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" -#include "llvm/Support/FileCollector.h" +#include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/YAMLTraits.h" #include <mutex> #include <string> +#include <utility> #include <vector> namespace lldb_private { +class UUID; namespace repro { class Reproducer; @@ -82,211 +85,6 @@ protected: using ProviderBase::ProviderBase; // Inherit constructor. }; -class FileProvider : public Provider<FileProvider> { -public: - struct Info { - static const char *name; - static const char *file; - }; - - FileProvider(const FileSpec &directory) - : Provider(directory), - m_collector(std::make_shared<llvm::FileCollector>( - directory.CopyByAppendingPathComponent("root").GetPath(), - directory.GetPath())) {} - - std::shared_ptr<llvm::FileCollector> GetFileCollector() { - return m_collector; - } - - void recordInterestingDirectory(const llvm::Twine &dir); - - void Keep() override { - auto mapping = GetRoot().CopyByAppendingPathComponent(Info::file); - // Temporary files that are removed during execution can cause copy errors. - if (auto ec = m_collector->copyFiles(/*stop_on_error=*/false)) - return; - m_collector->writeMapping(mapping.GetPath()); - } - - static char ID; - -private: - std::shared_ptr<llvm::FileCollector> m_collector; -}; - -/// Provider for the LLDB version number. -/// -/// When the reproducer is kept, it writes the lldb version to a file named -/// version.txt in the reproducer root. -class VersionProvider : public Provider<VersionProvider> { -public: - VersionProvider(const FileSpec &directory) : Provider(directory) {} - struct Info { - static const char *name; - static const char *file; - }; - void SetVersion(std::string version) { - assert(m_version.empty()); - m_version = std::move(version); - } - void Keep() override; - std::string m_version; - static char ID; -}; - -/// Provider for the LLDB current working directory. -/// -/// When the reproducer is kept, it writes lldb's current working directory to -/// a file named cwd.txt in the reproducer root. -class WorkingDirectoryProvider : public Provider<WorkingDirectoryProvider> { -public: - WorkingDirectoryProvider(const FileSpec &directory) : Provider(directory) { - llvm::SmallString<128> cwd; - if (std::error_code EC = llvm::sys::fs::current_path(cwd)) - return; - m_cwd = std::string(cwd.str()); - } - - void Update(llvm::StringRef path) { m_cwd = std::string(path); } - - struct Info { - static const char *name; - static const char *file; - }; - void Keep() override; - std::string m_cwd; - static char ID; -}; - -/// The recorder is a small object handed out by a provider to record data. It -/// is commonly used in combination with a MultiProvider which is meant to -/// record information for multiple instances of the same source of data. -class AbstractRecorder { -protected: - AbstractRecorder(const FileSpec &filename, std::error_code &ec) - : m_filename(filename.GetFilename().GetStringRef()), - m_os(filename.GetPath(), ec, llvm::sys::fs::OF_Text), m_record(true) {} - -public: - const FileSpec &GetFilename() { return m_filename; } - - void Stop() { - assert(m_record); - m_record = false; - } - -private: - FileSpec m_filename; - -protected: - llvm::raw_fd_ostream m_os; - bool m_record; -}; - -/// Recorder that records its data as text to a file. -class DataRecorder : public AbstractRecorder { -public: - DataRecorder(const FileSpec &filename, std::error_code &ec) - : AbstractRecorder(filename, ec) {} - - static llvm::Expected<std::unique_ptr<DataRecorder>> - Create(const FileSpec &filename); - - template <typename T> void Record(const T &t, bool newline = false) { - if (!m_record) - return; - m_os << t; - if (newline) - m_os << '\n'; - m_os.flush(); - } -}; - -/// Recorder that records its data as YAML to a file. -class YamlRecorder : public AbstractRecorder { -public: - YamlRecorder(const FileSpec &filename, std::error_code &ec) - : AbstractRecorder(filename, ec) {} - - static llvm::Expected<std::unique_ptr<YamlRecorder>> - Create(const FileSpec &filename); - - template <typename T> void Record(const T &t) { - if (!m_record) - return; - llvm::yaml::Output yout(m_os); - // The YAML traits are defined as non-const because they are used for - // serialization and deserialization. The cast is safe because - // serialization doesn't modify the object. - yout << const_cast<T &>(t); - m_os.flush(); - } -}; - -/// The MultiProvider is a provider that hands out recorder which can be used -/// to capture data for different instances of the same object. The recorders -/// can be passed around or stored as an instance member. -/// -/// The Info::file for the MultiProvider contains an index of files for every -/// recorder. Use the MultiLoader to read the index and get the individual -/// files. -template <typename T, typename V> -class MultiProvider : public repro::Provider<V> { -public: - MultiProvider(const FileSpec &directory) : Provider<V>(directory) {} - - T *GetNewRecorder() { - std::size_t i = m_recorders.size() + 1; - std::string filename = (llvm::Twine(V::Info::name) + llvm::Twine("-") + - llvm::Twine(i) + llvm::Twine(".yaml")) - .str(); - auto recorder_or_error = - T::Create(this->GetRoot().CopyByAppendingPathComponent(filename)); - if (!recorder_or_error) { - llvm::consumeError(recorder_or_error.takeError()); - return nullptr; - } - - m_recorders.push_back(std::move(*recorder_or_error)); - return m_recorders.back().get(); - } - - void Keep() override { - std::vector<std::string> files; - for (auto &recorder : m_recorders) { - recorder->Stop(); - files.push_back(recorder->GetFilename().GetPath()); - } - - FileSpec file = this->GetRoot().CopyByAppendingPathComponent(V::Info::file); - std::error_code ec; - llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text); - if (ec) - return; - llvm::yaml::Output yout(os); - yout << files; - } - - void Discard() override { m_recorders.clear(); } - -private: - std::vector<std::unique_ptr<T>> m_recorders; -}; - -class CommandProvider : public MultiProvider<DataRecorder, CommandProvider> { -public: - struct Info { - static const char *name; - static const char *file; - }; - - CommandProvider(const FileSpec &directory) - : MultiProvider<DataRecorder, CommandProvider>(directory) {} - - static char ID; -}; - /// The generator is responsible for the logic needed to generate a /// reproducer. For doing so it relies on providers, who serialize data that /// is necessary for reproducing a failure. @@ -399,6 +197,7 @@ public: static Reproducer &Instance(); static llvm::Error Initialize(ReproducerMode mode, llvm::Optional<FileSpec> root); + static void Initialize(); static bool Initialized(); static void Terminate(); @@ -428,51 +227,25 @@ private: mutable std::mutex m_mutex; }; -/// Loader for data captured with the MultiProvider. It will read the index and -/// return the path to the files in the index. -template <typename T> class MultiLoader { +class Verifier { public: - MultiLoader(std::vector<std::string> files) : m_files(files) {} - - static std::unique_ptr<MultiLoader> Create(Loader *loader) { - if (!loader) - return {}; - - FileSpec file = loader->GetFile<typename T::Info>(); - if (!file) - return {}; - - auto error_or_file = llvm::MemoryBuffer::getFile(file.GetPath()); - if (auto err = error_or_file.getError()) - return {}; - - std::vector<std::string> files; - llvm::yaml::Input yin((*error_or_file)->getBuffer()); - yin >> files; - - if (auto err = yin.error()) - return {}; - - for (auto &file : files) { - FileSpec absolute_path = - loader->GetRoot().CopyByAppendingPathComponent(file); - file = absolute_path.GetPath(); - } - - return std::make_unique<MultiLoader<T>>(std::move(files)); - } - - llvm::Optional<std::string> GetNextFile() { - if (m_index >= m_files.size()) - return {}; - return m_files[m_index++]; - } + Verifier(Loader *loader) : m_loader(loader) {} + void Verify(llvm::function_ref<void(llvm::StringRef)> error_callback, + llvm::function_ref<void(llvm::StringRef)> warning_callback, + llvm::function_ref<void(llvm::StringRef)> note_callback) const; private: - std::vector<std::string> m_files; - unsigned m_index = 0; + Loader *m_loader; }; +struct ReplayOptions { + bool verify = true; + bool check_version = true; +}; + +llvm::Error Finalize(Loader *loader); +llvm::Error Finalize(const FileSpec &root); + } // namespace repro } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/ReproducerInstrumentation.h b/contrib/llvm-project/lldb/include/lldb/Utility/ReproducerInstrumentation.h index 5fc33ad1a17b..c8a98adf85c7 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/ReproducerInstrumentation.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/ReproducerInstrumentation.h @@ -17,6 +17,7 @@ #include "llvm/Support/ErrorHandling.h" #include <map> +#include <thread> #include <type_traits> template <typename T, @@ -78,6 +79,13 @@ template <typename... Ts> inline std::string stringify_args(const Ts &... ts) { // is initialized or enabled. // #define LLDB_REPRO_INSTR_TRACE +#ifdef LLDB_REPRO_INSTR_TRACE +inline llvm::raw_ostream &this_thread_id() { + size_t tid = std::hash<std::thread::id>{}(std::this_thread::get_id()); + return llvm::errs().write_hex(tid) << " :: "; +} +#endif + #define LLDB_REGISTER_CONSTRUCTOR(Class, Signature) \ R.Register<Class * Signature>(&construct<Class Signature>::record, "", \ #Class, #Class, #Signature) @@ -325,6 +333,7 @@ public: } template <typename T> const T &HandleReplayResult(const T &t) { + CheckSequence(Deserialize<unsigned>()); unsigned result = Deserialize<unsigned>(); if (is_trivially_serializable<T>::value) return t; @@ -334,6 +343,7 @@ public: /// Store the returned value in the index-to-object mapping. template <typename T> T &HandleReplayResult(T &t) { + CheckSequence(Deserialize<unsigned>()); unsigned result = Deserialize<unsigned>(); if (is_trivially_serializable<T>::value) return t; @@ -343,6 +353,7 @@ public: /// Store the returned value in the index-to-object mapping. template <typename T> T *HandleReplayResult(T *t) { + CheckSequence(Deserialize<unsigned>()); unsigned result = Deserialize<unsigned>(); if (is_trivially_serializable<T>::value) return t; @@ -352,6 +363,7 @@ public: /// All returned types are recorded, even when the function returns a void. /// The latter requires special handling. void HandleReplayResultVoid() { + CheckSequence(Deserialize<unsigned>()); unsigned result = Deserialize<unsigned>(); assert(result == 0); (void)result; @@ -361,6 +373,10 @@ public: return m_index_to_object.GetAllObjects(); } + void SetExpectedSequence(unsigned sequence) { + m_expected_sequence = sequence; + } + private: template <typename T> T Read(ValueTag) { assert(HasData(sizeof(T))); @@ -402,11 +418,17 @@ private: return *(new UnderlyingT(Deserialize<UnderlyingT>())); } + /// Verify that the given sequence number matches what we expect. + void CheckSequence(unsigned sequence); + /// Mapping of indices to objects. IndexToObject m_index_to_object; /// Buffer containing the serialized data. llvm::StringRef m_buffer; + + /// The result's expected sequence number. + llvm::Optional<unsigned> m_expected_sequence; }; /// Partial specialization for C-style strings. We read the string value @@ -600,8 +622,8 @@ private: /// objects (in which case we serialize their index). template <typename T> void Serialize(T *t) { #ifdef LLDB_REPRO_INSTR_TRACE - llvm::errs() << "Serializing with " << LLVM_PRETTY_FUNCTION << " -> " - << stringify_args(t) << "\n"; + this_thread_id() << "Serializing with " << LLVM_PRETTY_FUNCTION << " -> " + << stringify_args(t) << "\n"; #endif if (std::is_fundamental<T>::value) { Serialize(*t); @@ -616,8 +638,8 @@ private: /// to objects (in which case we serialize their index). template <typename T> void Serialize(T &t) { #ifdef LLDB_REPRO_INSTR_TRACE - llvm::errs() << "Serializing with " << LLVM_PRETTY_FUNCTION << " -> " - << stringify_args(t) << "\n"; + this_thread_id() << "Serializing with " << LLVM_PRETTY_FUNCTION << " -> " + << stringify_args(t) << "\n"; #endif if (is_trivially_serializable<T>::value) { m_stream.write(reinterpret_cast<const char *>(&t), sizeof(T)); @@ -637,8 +659,8 @@ private: void Serialize(const char *t) { #ifdef LLDB_REPRO_INSTR_TRACE - llvm::errs() << "Serializing with " << LLVM_PRETTY_FUNCTION << " -> " - << stringify_args(t) << "\n"; + this_thread_id() << "Serializing with " << LLVM_PRETTY_FUNCTION << " -> " + << stringify_args(t) << "\n"; #endif const size_t size = t ? strlen(t) : std::numeric_limits<size_t>::max(); Serialize(size); @@ -737,12 +759,15 @@ public: if (!ShouldCapture()) return; + std::lock_guard<std::mutex> lock(g_mutex); + unsigned sequence = GetSequenceNumber(); unsigned id = registry.GetID(uintptr_t(f)); #ifdef LLDB_REPRO_INSTR_TRACE Log(id); #endif + serializer.SerializeAll(sequence); serializer.SerializeAll(id); serializer.SerializeAll(args...); @@ -750,6 +775,7 @@ public: typename std::remove_reference<Result>::type>::type>::value) { m_result_recorded = false; } else { + serializer.SerializeAll(sequence); serializer.SerializeAll(0); m_result_recorded = true; } @@ -763,16 +789,20 @@ public: if (!ShouldCapture()) return; + std::lock_guard<std::mutex> lock(g_mutex); + unsigned sequence = GetSequenceNumber(); unsigned id = registry.GetID(uintptr_t(f)); #ifdef LLDB_REPRO_INSTR_TRACE Log(id); #endif + serializer.SerializeAll(sequence); serializer.SerializeAll(id); serializer.SerializeAll(args...); // Record result. + serializer.SerializeAll(sequence); serializer.SerializeAll(0); m_result_recorded = true; } @@ -798,7 +828,9 @@ public: if (update_boundary) UpdateBoundary(); if (m_serializer && ShouldCapture()) { + std::lock_guard<std::mutex> lock(g_mutex); assert(!m_result_recorded); + m_serializer->SerializeAll(GetSequenceNumber()); m_serializer->SerializeAll(r); m_result_recorded = true; } @@ -808,6 +840,7 @@ public: template <typename Result, typename T> Result Replay(Deserializer &deserializer, Registry ®istry, uintptr_t addr, bool update_boundary) { + deserializer.SetExpectedSequence(deserializer.Deserialize<unsigned>()); unsigned actual_id = registry.GetID(addr); unsigned id = deserializer.Deserialize<unsigned>(); registry.CheckID(id, actual_id); @@ -818,6 +851,7 @@ public: } void Replay(Deserializer &deserializer, Registry ®istry, uintptr_t addr) { + deserializer.SetExpectedSequence(deserializer.Deserialize<unsigned>()); unsigned actual_id = registry.GetID(addr); unsigned id = deserializer.Deserialize<unsigned>(); registry.CheckID(id, actual_id); @@ -833,7 +867,14 @@ public: bool ShouldCapture() { return m_local_boundary; } + /// Mark the current thread as a private thread and pretend that everything + /// on this thread is behind happening behind the API boundary. + static void PrivateThread() { g_global_boundary = true; } + private: + static unsigned GetNextSequenceNumber() { return g_sequence++; } + unsigned GetSequenceNumber() const; + template <typename T> friend struct replay; void UpdateBoundary() { if (m_local_boundary) @@ -842,8 +883,8 @@ private: #ifdef LLDB_REPRO_INSTR_TRACE void Log(unsigned id) { - llvm::errs() << "Recording " << id << ": " << m_pretty_func << " (" - << m_pretty_args << ")\n"; + this_thread_id() << "Recording " << id << ": " << m_pretty_func << " (" + << m_pretty_args << ")\n"; } #endif @@ -859,8 +900,17 @@ private: /// Whether the return value was recorded explicitly. bool m_result_recorded; + /// The sequence number for this pair of function and result. + unsigned m_sequence; + /// Whether we're currently across the API boundary. - static bool g_global_boundary; + static thread_local bool g_global_boundary; + + /// Global mutex to protect concurrent access. + static std::mutex g_mutex; + + /// Unique, monotonically increasing sequence number. + static std::atomic<unsigned> g_sequence; }; /// To be used as the "Runtime ID" of a constructor. It also invokes the @@ -1002,6 +1052,7 @@ struct invoke_char_ptr<Result (Class::*)(Args...) const> { static Result replay(Recorder &recorder, Deserializer &deserializer, Registry ®istry, char *str) { + deserializer.SetExpectedSequence(deserializer.Deserialize<unsigned>()); deserializer.Deserialize<unsigned>(); Class *c = deserializer.Deserialize<Class *>(); deserializer.Deserialize<const char *>(); @@ -1023,6 +1074,7 @@ struct invoke_char_ptr<Result (Class::*)(Args...)> { static Result replay(Recorder &recorder, Deserializer &deserializer, Registry ®istry, char *str) { + deserializer.SetExpectedSequence(deserializer.Deserialize<unsigned>()); deserializer.Deserialize<unsigned>(); Class *c = deserializer.Deserialize<Class *>(); deserializer.Deserialize<const char *>(); @@ -1043,6 +1095,7 @@ struct invoke_char_ptr<Result (*)(Args...)> { static Result replay(Recorder &recorder, Deserializer &deserializer, Registry ®istry, char *str) { + deserializer.SetExpectedSequence(deserializer.Deserialize<unsigned>()); deserializer.Deserialize<unsigned>(); deserializer.Deserialize<const char *>(); size_t l = deserializer.Deserialize<size_t>(); diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/ReproducerProvider.h b/contrib/llvm-project/lldb/include/lldb/Utility/ReproducerProvider.h new file mode 100644 index 000000000000..221c0eb9c5bb --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Utility/ReproducerProvider.h @@ -0,0 +1,434 @@ +//===-- Reproducer.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_UTILITY_REPRODUCER_PROVIDER_H +#define LLDB_UTILITY_REPRODUCER_PROVIDER_H + +#include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/ProcessInfo.h" +#include "lldb/Utility/Reproducer.h" +#include "lldb/Utility/UUID.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/FileCollector.h" +#include "llvm/Support/YAMLTraits.h" + +#include <string> +#include <utility> +#include <vector> + +namespace lldb_private { +namespace repro { + +/// The recorder is a small object handed out by a provider to record data. It +/// is commonly used in combination with a MultiProvider which is meant to +/// record information for multiple instances of the same source of data. +class AbstractRecorder { +protected: + AbstractRecorder(const FileSpec &filename, std::error_code &ec) + : m_filename(filename.GetFilename().GetStringRef()), + m_os(filename.GetPath(), ec, llvm::sys::fs::OF_Text), m_record(true) {} + +public: + const FileSpec &GetFilename() { return m_filename; } + + void Stop() { + assert(m_record); + m_record = false; + } + +private: + FileSpec m_filename; + +protected: + llvm::raw_fd_ostream m_os; + bool m_record; +}; + +/// Recorder that records its data as text to a file. +class DataRecorder : public AbstractRecorder { +public: + DataRecorder(const FileSpec &filename, std::error_code &ec) + : AbstractRecorder(filename, ec) {} + + static llvm::Expected<std::unique_ptr<DataRecorder>> + Create(const FileSpec &filename); + + template <typename T> void Record(const T &t, bool newline = false) { + if (!m_record) + return; + m_os << t; + if (newline) + m_os << '\n'; + m_os.flush(); + } +}; + +/// Recorder that records its data as YAML to a file. +class YamlRecorder : public AbstractRecorder { +public: + YamlRecorder(const FileSpec &filename, std::error_code &ec) + : AbstractRecorder(filename, ec) {} + + static llvm::Expected<std::unique_ptr<YamlRecorder>> + Create(const FileSpec &filename); + + template <typename T> void Record(const T &t) { + if (!m_record) + return; + llvm::yaml::Output yout(m_os); + // The YAML traits are defined as non-const because they are used for + // serialization and deserialization. The cast is safe because + // serialization doesn't modify the object. + yout << const_cast<T &>(t); + m_os.flush(); + } +}; + +class FlushingFileCollector : public llvm::FileCollectorBase { +public: + FlushingFileCollector(llvm::StringRef files_path, llvm::StringRef dirs_path, + std::error_code &ec); + +protected: + void addFileImpl(llvm::StringRef file) override; + + llvm::vfs::directory_iterator + addDirectoryImpl(const llvm::Twine &dir, + llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs, + std::error_code &dir_ec) override; + + llvm::Optional<llvm::raw_fd_ostream> m_files_os; + llvm::Optional<llvm::raw_fd_ostream> m_dirs_os; +}; + +class FileProvider : public Provider<FileProvider> { +public: + struct Info { + static const char *name; + static const char *file; + }; + + FileProvider(const FileSpec &directory) : Provider(directory) { + std::error_code ec; + m_collector = std::make_shared<FlushingFileCollector>( + directory.CopyByAppendingPathComponent("files.txt").GetPath(), + directory.CopyByAppendingPathComponent("dirs.txt").GetPath(), ec); + if (ec) + m_collector.reset(); + } + + std::shared_ptr<llvm::FileCollectorBase> GetFileCollector() { + return m_collector; + } + + void RecordInterestingDirectory(const llvm::Twine &dir); + void RecordInterestingDirectoryRecursive(const llvm::Twine &dir); + + static char ID; + +private: + std::shared_ptr<FlushingFileCollector> m_collector; +}; + +/// Provider for the LLDB version number. +/// +/// When the reproducer is kept, it writes the lldb version to a file named +/// version.txt in the reproducer root. +class VersionProvider : public Provider<VersionProvider> { +public: + VersionProvider(const FileSpec &directory) : Provider(directory) {} + struct Info { + static const char *name; + static const char *file; + }; + void SetVersion(std::string version) { + assert(m_version.empty()); + m_version = std::move(version); + } + void Keep() override; + std::string m_version; + static char ID; +}; + +/// Abstract provider to storing directory paths. +template <typename T> class DirectoryProvider : public repro::Provider<T> { +public: + DirectoryProvider(const FileSpec &root) : Provider<T>(root) {} + void SetDirectory(std::string directory) { + m_directory = std::move(directory); + } + llvm::StringRef GetDirectory() { return m_directory; } + + void Keep() override { + FileSpec file = this->GetRoot().CopyByAppendingPathComponent(T::Info::file); + std::error_code ec; + llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text); + if (ec) + return; + os << m_directory << "\n"; + } + +protected: + std::string m_directory; +}; + +/// Provider for the current working directory. +/// +/// When the reproducer is kept, it writes lldb's current working directory to +/// a file named cwd.txt in the reproducer root. +class WorkingDirectoryProvider + : public DirectoryProvider<WorkingDirectoryProvider> { +public: + WorkingDirectoryProvider(const FileSpec &directory) + : DirectoryProvider(directory) { + llvm::SmallString<128> cwd; + if (std::error_code EC = llvm::sys::fs::current_path(cwd)) + return; + SetDirectory(std::string(cwd)); + } + struct Info { + static const char *name; + static const char *file; + }; + static char ID; +}; + +/// Provider for the home directory. +/// +/// When the reproducer is kept, it writes the user's home directory to a file +/// a file named home.txt in the reproducer root. +class HomeDirectoryProvider : public DirectoryProvider<HomeDirectoryProvider> { +public: + HomeDirectoryProvider(const FileSpec &directory) + : DirectoryProvider(directory) { + llvm::SmallString<128> home_dir; + llvm::sys::path::home_directory(home_dir); + SetDirectory(std::string(home_dir)); + } + struct Info { + static const char *name; + static const char *file; + }; + static char ID; +}; + +/// Provider for mapping UUIDs to symbol and executable files. +class SymbolFileProvider : public Provider<SymbolFileProvider> { +public: + SymbolFileProvider(const FileSpec &directory) + : Provider(directory), m_symbol_files() {} + + void AddSymbolFile(const UUID *uuid, const FileSpec &module_path, + const FileSpec &symbol_path); + void Keep() override; + + struct Entry { + Entry() = default; + Entry(std::string uuid) : uuid(std::move(uuid)) {} + Entry(std::string uuid, std::string module_path, std::string symbol_path) + : uuid(std::move(uuid)), module_path(std::move(module_path)), + symbol_path(std::move(symbol_path)) {} + + bool operator==(const Entry &rhs) const { return uuid == rhs.uuid; } + bool operator<(const Entry &rhs) const { return uuid < rhs.uuid; } + + std::string uuid; + std::string module_path; + std::string symbol_path; + }; + + struct Info { + static const char *name; + static const char *file; + }; + static char ID; + +private: + std::vector<Entry> m_symbol_files; +}; + +/// The MultiProvider is a provider that hands out recorder which can be used +/// to capture data for different instances of the same object. The recorders +/// can be passed around or stored as an instance member. +/// +/// The Info::file for the MultiProvider contains an index of files for every +/// recorder. Use the MultiLoader to read the index and get the individual +/// files. +template <typename T, typename V> +class MultiProvider : public repro::Provider<V> { +public: + MultiProvider(const FileSpec &directory) : Provider<V>(directory) {} + + T *GetNewRecorder() { + std::size_t i = m_recorders.size() + 1; + std::string filename = (llvm::Twine(V::Info::name) + llvm::Twine("-") + + llvm::Twine(i) + llvm::Twine(".yaml")) + .str(); + auto recorder_or_error = + T::Create(this->GetRoot().CopyByAppendingPathComponent(filename)); + if (!recorder_or_error) { + llvm::consumeError(recorder_or_error.takeError()); + return nullptr; + } + + m_recorders.push_back(std::move(*recorder_or_error)); + return m_recorders.back().get(); + } + + void Keep() override { + std::vector<std::string> files; + for (auto &recorder : m_recorders) { + recorder->Stop(); + files.push_back(recorder->GetFilename().GetPath()); + } + + FileSpec file = this->GetRoot().CopyByAppendingPathComponent(V::Info::file); + std::error_code ec; + llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text); + if (ec) + return; + llvm::yaml::Output yout(os); + yout << files; + } + + void Discard() override { m_recorders.clear(); } + +private: + std::vector<std::unique_ptr<T>> m_recorders; +}; + +class CommandProvider : public MultiProvider<DataRecorder, CommandProvider> { +public: + struct Info { + static const char *name; + static const char *file; + }; + + CommandProvider(const FileSpec &directory) + : MultiProvider<DataRecorder, CommandProvider>(directory) {} + + static char ID; +}; + +class ProcessInfoRecorder : public AbstractRecorder { +public: + ProcessInfoRecorder(const FileSpec &filename, std::error_code &ec) + : AbstractRecorder(filename, ec) {} + + static llvm::Expected<std::unique_ptr<ProcessInfoRecorder>> + Create(const FileSpec &filename); + + void Record(const ProcessInstanceInfoList &process_infos); +}; + +class ProcessInfoProvider : public repro::Provider<ProcessInfoProvider> { +public: + struct Info { + static const char *name; + static const char *file; + }; + + ProcessInfoProvider(const FileSpec &directory) : Provider(directory) {} + + ProcessInfoRecorder *GetNewProcessInfoRecorder(); + + void Keep() override; + void Discard() override; + + static char ID; + +private: + std::unique_ptr<llvm::raw_fd_ostream> m_stream_up; + std::vector<std::unique_ptr<ProcessInfoRecorder>> m_process_info_recorders; +}; + +/// Loader for data captured with the MultiProvider. It will read the index and +/// return the path to the files in the index. +template <typename T> class MultiLoader { +public: + MultiLoader(std::vector<std::string> files) : m_files(std::move(files)) {} + + static std::unique_ptr<MultiLoader> Create(Loader *loader) { + if (!loader) + return {}; + + FileSpec file = loader->GetFile<typename T::Info>(); + if (!file) + return {}; + + auto error_or_file = llvm::MemoryBuffer::getFile(file.GetPath()); + if (auto err = error_or_file.getError()) + return {}; + + std::vector<std::string> files; + llvm::yaml::Input yin((*error_or_file)->getBuffer()); + yin >> files; + + if (auto err = yin.error()) + return {}; + + for (auto &file : files) { + FileSpec absolute_path = + loader->GetRoot().CopyByAppendingPathComponent(file); + file = absolute_path.GetPath(); + } + + return std::make_unique<MultiLoader<T>>(std::move(files)); + } + + llvm::Optional<std::string> GetNextFile() { + if (m_index >= m_files.size()) + return {}; + return m_files[m_index++]; + } + +private: + std::vector<std::string> m_files; + unsigned m_index = 0; +}; + +class SymbolFileLoader { +public: + SymbolFileLoader(Loader *loader); + std::pair<FileSpec, FileSpec> GetPaths(const UUID *uuid) const; + +private: + // Sorted list of UUID to path mappings. + std::vector<SymbolFileProvider::Entry> m_symbol_files; +}; + +/// Helper to read directories written by the DirectoryProvider. +template <typename T> +llvm::Expected<std::string> GetDirectoryFrom(repro::Loader *loader) { + llvm::Expected<std::string> dir = loader->LoadBuffer<T>(); + if (!dir) + return dir.takeError(); + return std::string(llvm::StringRef(*dir).rtrim()); +} + +} // namespace repro +} // namespace lldb_private + +LLVM_YAML_IS_SEQUENCE_VECTOR(lldb_private::repro::SymbolFileProvider::Entry) + +namespace llvm { +namespace yaml { +template <> +struct MappingTraits<lldb_private::repro::SymbolFileProvider::Entry> { + static void mapping(IO &io, + lldb_private::repro::SymbolFileProvider::Entry &entry) { + io.mapRequired("uuid", entry.uuid); + io.mapRequired("module-path", entry.module_path); + io.mapRequired("symbol-path", entry.symbol_path); + } +}; +} // namespace yaml +} // namespace llvm + +#endif // LLDB_UTILITY_REPRODUCER_PROVIDER_H diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Scalar.h b/contrib/llvm-project/lldb/include/lldb/Utility/Scalar.h index f215fa71c84c..f797aaf99626 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/Scalar.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/Scalar.h @@ -9,94 +9,68 @@ #ifndef LLDB_UTILITY_SCALAR_H #define LLDB_UTILITY_SCALAR_H +#include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-enumerations.h" #include "lldb/lldb-private-types.h" -#include "lldb/Utility/LLDBAssert.h" #include "llvm/ADT/APFloat.h" -#include "llvm/ADT/APInt.h" +#include "llvm/ADT/APSInt.h" #include <cstddef> #include <cstdint> +#include <utility> namespace lldb_private { + class DataExtractor; class Stream; -} // namespace lldb_private #define NUM_OF_WORDS_INT128 2 #define BITWIDTH_INT128 128 -#define NUM_OF_WORDS_INT256 4 -#define BITWIDTH_INT256 256 -#define NUM_OF_WORDS_INT512 8 -#define BITWIDTH_INT512 512 - -namespace lldb_private { // A class designed to hold onto values and their corresponding types. // Operators are defined and Scalar objects will correctly promote their types // and values before performing these operations. Type promotion currently // follows the ANSI C type promotion rules. class Scalar { + template<typename T> + static llvm::APSInt MakeAPSInt(T v) { + static_assert(std::is_integral<T>::value, ""); + static_assert(sizeof(T) <= sizeof(uint64_t), "Conversion loses precision!"); + return llvm::APSInt( + llvm::APInt(sizeof(T) * 8, uint64_t(v), std::is_signed<T>::value), + std::is_unsigned<T>::value); + } + public: - // FIXME: These are host types which seems to be an odd choice. enum Type { e_void = 0, - e_sint, - e_uint, - e_slong, - e_ulong, - e_slonglong, - e_ulonglong, - e_sint128, - e_uint128, - e_sint256, - e_uint256, - e_sint512, - e_uint512, + e_int, e_float, - e_double, - e_long_double }; // Constructors and Destructors - Scalar(); - Scalar(int v) : m_type(e_sint), m_float(static_cast<float>(0)) { - m_integer = llvm::APInt(sizeof(int) * 8, v, true); - } - Scalar(unsigned int v) : m_type(e_uint), m_float(static_cast<float>(0)) { - m_integer = llvm::APInt(sizeof(int) * 8, v); - } - Scalar(long v) : m_type(e_slong), m_float(static_cast<float>(0)) { - m_integer = llvm::APInt(sizeof(long) * 8, v, true); - } - Scalar(unsigned long v) : m_type(e_ulong), m_float(static_cast<float>(0)) { - m_integer = llvm::APInt(sizeof(long) * 8, v); - } - Scalar(long long v) : m_type(e_slonglong), m_float(static_cast<float>(0)) { - m_integer = llvm::APInt(sizeof(long long) * 8, v, true); - } + Scalar() : m_type(e_void), m_float(0.0f) {} + Scalar(int v) : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {} + Scalar(unsigned int v) + : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {} + Scalar(long v) : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {} + Scalar(unsigned long v) + : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {} + Scalar(long long v) + : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {} Scalar(unsigned long long v) - : m_type(e_ulonglong), m_float(static_cast<float>(0)) { - m_integer = llvm::APInt(sizeof(long long) * 8, v); - } - Scalar(float v) : m_type(e_float), m_float(v) { m_float = llvm::APFloat(v); } - Scalar(double v) : m_type(e_double), m_float(v) { - m_float = llvm::APFloat(v); + : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {} + Scalar(float v) : m_type(e_float), m_float(v) {} + Scalar(double v) : m_type(e_float), m_float(v) {} + Scalar(long double v) : m_type(e_float), m_float(double(v)) { + bool ignore; + m_float.convert(llvm::APFloat::x87DoubleExtended(), + llvm::APFloat::rmNearestTiesToEven, &ignore); } - Scalar(long double v) - : m_type(e_long_double), - m_float(llvm::APFloat::x87DoubleExtended(), - llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, - (reinterpret_cast<type128 *>(&v))->x)) {} - Scalar(llvm::APInt v) : m_type(), m_float(static_cast<float>(0)) { - m_integer = llvm::APInt(v); - m_type = GetBestTypeForBitSize(m_integer.getBitWidth(), true); - } - // Scalar(const RegisterValue& reg_value); - virtual ~Scalar(); - - /// Return the most efficient Scalar::Type for the requested bit size. - static Type GetBestTypeForBitSize(size_t bit_size, bool sign); + Scalar(llvm::APInt v) + : m_type(e_int), m_integer(std::move(v), false), m_float(0.0f) {} + Scalar(llvm::APSInt v) + : m_type(e_int), m_integer(std::move(v)), m_float(0.0f) {} bool SignExtend(uint32_t bit_pos); @@ -129,34 +103,26 @@ public: void GetValue(Stream *s, bool show_type) const; - bool IsValid() const { - return (m_type >= e_sint) && (m_type <= e_long_double); - } + bool IsValid() const { return (m_type >= e_int) && (m_type <= e_float); } /// Convert to an integer with \p bits and the given signedness. void TruncOrExtendTo(uint16_t bits, bool sign); - bool Promote(Scalar::Type type); + bool IntegralPromote(uint16_t bits, bool sign); + bool FloatPromote(const llvm::fltSemantics &semantics); + bool IsSigned() const; bool MakeSigned(); bool MakeUnsigned(); static const char *GetValueTypeAsCString(Scalar::Type value_type); - static Scalar::Type - GetValueTypeForSignedIntegerWithByteSize(size_t byte_size); - - static Scalar::Type - GetValueTypeForUnsignedIntegerWithByteSize(size_t byte_size); - - static Scalar::Type GetValueTypeForFloatWithByteSize(size_t byte_size); - // All operators can benefits from the implicit conversions that will happen // automagically by the compiler, so no temporary objects will need to be // created. As a result, we currently don't need a variety of overloaded set // value accessors. - Scalar &operator+=(const Scalar &rhs); + Scalar &operator+=(Scalar rhs); Scalar &operator<<=(const Scalar &rhs); // Shift left Scalar &operator>>=(const Scalar &rhs); // Shift right (arithmetic) Scalar &operator&=(const Scalar &rhs); @@ -217,72 +183,37 @@ public: Status SetValueFromCString(const char *s, lldb::Encoding encoding, size_t byte_size); - Status SetValueFromData(DataExtractor &data, lldb::Encoding encoding, + Status SetValueFromData(const DataExtractor &data, lldb::Encoding encoding, size_t byte_size); - static bool UIntValueIsValidForSize(uint64_t uval64, size_t total_byte_size) { - if (total_byte_size > 8) - return false; - - if (total_byte_size == 8) - return true; - - const uint64_t max = (static_cast<uint64_t>(1) - << static_cast<uint64_t>(total_byte_size * 8)) - - 1; - return uval64 <= max; - } - - static bool SIntValueIsValidForSize(int64_t sval64, size_t total_byte_size) { - if (total_byte_size > 8) - return false; - - if (total_byte_size == 8) - return true; - - const int64_t max = (static_cast<int64_t>(1) - << static_cast<uint64_t>(total_byte_size * 8 - 1)) - - 1; - const int64_t min = ~(max); - return min <= sval64 && sval64 <= max; - } - protected: - typedef char schar_t; - typedef unsigned char uchar_t; - typedef short sshort_t; - typedef unsigned short ushort_t; - typedef int sint_t; - typedef unsigned int uint_t; - typedef long slong_t; - typedef unsigned long ulong_t; - typedef long long slonglong_t; - typedef unsigned long long ulonglong_t; - typedef float float_t; - typedef double double_t; - typedef long double long_double_t; - - // Classes that inherit from Scalar can see and modify these Scalar::Type m_type; - llvm::APInt m_integer; + llvm::APSInt m_integer; llvm::APFloat m_float; template <typename T> T GetAs(T fail_value) const; + static Type PromoteToMaxType(Scalar &lhs, Scalar &rhs); + + using PromotionKey = std::tuple<Type, unsigned, bool>; + PromotionKey GetPromoKey() const; + + static PromotionKey GetFloatPromoKey(const llvm::fltSemantics &semantics); + private: friend const Scalar operator+(const Scalar &lhs, const Scalar &rhs); - friend const Scalar operator-(const Scalar &lhs, const Scalar &rhs); - friend const Scalar operator/(const Scalar &lhs, const Scalar &rhs); - friend const Scalar operator*(const Scalar &lhs, const Scalar &rhs); - friend const Scalar operator&(const Scalar &lhs, const Scalar &rhs); - friend const Scalar operator|(const Scalar &lhs, const Scalar &rhs); - friend const Scalar operator%(const Scalar &lhs, const Scalar &rhs); - friend const Scalar operator^(const Scalar &lhs, const Scalar &rhs); + friend const Scalar operator-(Scalar lhs, Scalar rhs); + friend const Scalar operator/(Scalar lhs, Scalar rhs); + friend const Scalar operator*(Scalar lhs, Scalar rhs); + friend const Scalar operator&(Scalar lhs, Scalar rhs); + friend const Scalar operator|(Scalar lhs, Scalar rhs); + friend const Scalar operator%(Scalar lhs, Scalar rhs); + friend const Scalar operator^(Scalar lhs, Scalar rhs); friend const Scalar operator<<(const Scalar &lhs, const Scalar &rhs); friend const Scalar operator>>(const Scalar &lhs, const Scalar &rhs); - friend bool operator==(const Scalar &lhs, const Scalar &rhs); + friend bool operator==(Scalar lhs, Scalar rhs); friend bool operator!=(const Scalar &lhs, const Scalar &rhs); - friend bool operator<(const Scalar &lhs, const Scalar &rhs); + friend bool operator<(Scalar lhs, Scalar rhs); friend bool operator<=(const Scalar &lhs, const Scalar &rhs); friend bool operator>(const Scalar &lhs, const Scalar &rhs); friend bool operator>=(const Scalar &lhs, const Scalar &rhs); @@ -302,18 +233,18 @@ private: // Differentiate among members functions, non-member functions, and // friend functions const Scalar operator+(const Scalar &lhs, const Scalar &rhs); -const Scalar operator-(const Scalar &lhs, const Scalar &rhs); -const Scalar operator/(const Scalar &lhs, const Scalar &rhs); -const Scalar operator*(const Scalar &lhs, const Scalar &rhs); -const Scalar operator&(const Scalar &lhs, const Scalar &rhs); -const Scalar operator|(const Scalar &lhs, const Scalar &rhs); -const Scalar operator%(const Scalar &lhs, const Scalar &rhs); -const Scalar operator^(const Scalar &lhs, const Scalar &rhs); +const Scalar operator-(Scalar lhs, Scalar rhs); +const Scalar operator/(Scalar lhs, Scalar rhs); +const Scalar operator*(Scalar lhs, Scalar rhs); +const Scalar operator&(Scalar lhs, Scalar rhs); +const Scalar operator|(Scalar lhs, Scalar rhs); +const Scalar operator%(Scalar lhs, Scalar rhs); +const Scalar operator^(Scalar lhs, Scalar rhs); const Scalar operator<<(const Scalar &lhs, const Scalar &rhs); const Scalar operator>>(const Scalar &lhs, const Scalar &rhs); -bool operator==(const Scalar &lhs, const Scalar &rhs); +bool operator==(Scalar lhs, Scalar rhs); bool operator!=(const Scalar &lhs, const Scalar &rhs); -bool operator<(const Scalar &lhs, const Scalar &rhs); +bool operator<(Scalar lhs, Scalar rhs); bool operator<=(const Scalar &lhs, const Scalar &rhs); bool operator>(const Scalar &lhs, const Scalar &rhs); bool operator>=(const Scalar &lhs, const Scalar &rhs); diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/StringExtractorGDBRemote.h b/contrib/llvm-project/lldb/include/lldb/Utility/StringExtractorGDBRemote.h index 715f3cb2541d..3b6ed8030985 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/StringExtractorGDBRemote.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/StringExtractorGDBRemote.h @@ -76,6 +76,7 @@ public: eServerPacketType_QSetSTDERR, eServerPacketType_QSetWorkingDir, eServerPacketType_QStartNoAckMode, + eServerPacketType_qPathComplete, eServerPacketType_qPlatform_shell, eServerPacketType_qPlatform_mkdir, eServerPacketType_qPlatform_chmod, @@ -161,11 +162,13 @@ public: eServerPacketType__m, eServerPacketType_notify, // '%' notification - eServerPacketType_jTraceStart, - eServerPacketType_jTraceBufferRead, - eServerPacketType_jTraceMetaRead, - eServerPacketType_jTraceStop, - eServerPacketType_jTraceConfigRead, + eServerPacketType_jTraceStart, // deprecated + eServerPacketType_jTraceBufferRead, // deprecated + eServerPacketType_jTraceMetaRead, // deprecated + eServerPacketType_jTraceStop, // deprecated + eServerPacketType_jTraceConfigRead, // deprecated + + eServerPacketType_jLLDBTraceSupportedType, }; ServerPacketType GetServerPacketType() const; diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/StringList.h b/contrib/llvm-project/lldb/include/lldb/Utility/StringList.h index 591a15861593..34930abeac3c 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/StringList.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/StringList.h @@ -102,7 +102,7 @@ public: StringList &operator<<(const std::string &s); - StringList &operator<<(StringList strings); + StringList &operator<<(const StringList &strings); // Copy assignment for a vector of strings StringList &operator=(const std::vector<std::string> &rhs); diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/StructuredData.h b/contrib/llvm-project/lldb/include/lldb/Utility/StructuredData.h index 14c82e669676..4d03af18e527 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/StructuredData.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/StructuredData.h @@ -271,9 +271,9 @@ public: return false; } - void Push(ObjectSP item) { m_items.push_back(item); } + void Push(const ObjectSP &item) { m_items.push_back(item); } - void AddItem(ObjectSP item) { m_items.push_back(item); } + void AddItem(const ObjectSP &item) { m_items.push_back(item); } void Serialize(llvm::json::OStream &s) const override; @@ -493,7 +493,7 @@ public: void AddItem(llvm::StringRef key, ObjectSP value_sp) { ConstString key_cs(key); - m_dict[key_cs] = value_sp; + m_dict[key_cs] = std::move(value_sp); } void AddIntegerItem(llvm::StringRef key, uint64_t value) { @@ -547,7 +547,7 @@ public: void *m_object; }; - static ObjectSP ParseJSON(std::string json_text); + static ObjectSP ParseJSON(const std::string &json_text); static ObjectSP ParseJSONFromFile(const FileSpec &file, Status &error); }; diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Timer.h b/contrib/llvm-project/lldb/include/lldb/Utility/Timer.h index f97315b2db0f..edc064b23b57 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/Timer.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/Timer.h @@ -25,6 +25,7 @@ public: class Category { public: explicit Category(const char *category_name); + llvm::StringRef GetName() { return m_name; } private: friend class Timer; @@ -73,4 +74,11 @@ private: } // namespace lldb_private +#define LLDB_SCOPED_TIMER() \ + static ::lldb_private::Timer::Category _cat(LLVM_PRETTY_FUNCTION); \ + ::lldb_private::Timer _scoped_timer(_cat, LLVM_PRETTY_FUNCTION) +#define LLDB_SCOPED_TIMERF(...) \ + static ::lldb_private::Timer::Category _cat(LLVM_PRETTY_FUNCTION); \ + ::lldb_private::Timer _scoped_timer(_cat, __VA_ARGS__) + #endif // LLDB_UTILITY_TIMER_H diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/TraceOptions.h b/contrib/llvm-project/lldb/include/lldb/Utility/TraceOptions.h index 97aad33899be..c9a8d12ce125 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/TraceOptions.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/TraceOptions.h @@ -15,6 +15,19 @@ #include "lldb/Utility/StructuredData.h" namespace lldb_private { + +/// This struct represents a tracing technology. +struct TraceTypeInfo { + /// The name of the technology, e.g. intel-pt or arm-coresight. + /// + /// In order for a Trace plug-in (see \a lldb_private::Trace.h) to support the + /// trace technology given by this struct, it should match its name with this + /// field. + std::string name; + /// A description for the technology. + std::string description; +}; + class TraceOptions { public: TraceOptions() : m_trace_params(new StructuredData::Dictionary()) {} @@ -57,4 +70,12 @@ private: }; } +namespace llvm { +namespace json { + +bool fromJSON(const Value &value, lldb_private::TraceTypeInfo &info, Path path); + +} // namespace json +} // namespace llvm + #endif // LLDB_UTILITY_TRACEOPTIONS_H diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/UUID.h b/contrib/llvm-project/lldb/include/lldb/Utility/UUID.h index 5327719094c0..f2107d9b135b 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/UUID.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/UUID.h @@ -11,6 +11,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Endian.h" #include <stddef.h> #include <stdint.h> #include <string> @@ -23,6 +24,22 @@ class UUID { public: UUID() = default; + // Reference: + // https://crashpad.chromium.org/doxygen/structcrashpad_1_1CodeViewRecordPDB70.html + struct CvRecordPdb70 { + struct { + llvm::support::ulittle32_t Data1; + llvm::support::ulittle16_t Data2; + llvm::support::ulittle16_t Data3; + uint8_t Data4[8]; + } Uuid; + llvm::support::ulittle32_t Age; + // char PDBFileName[]; + }; + + /// Create a UUID from CvRecordPdb70. + static UUID fromCvRecord(CvRecordPdb70 debug_info); + /// Creates a UUID from the data pointed to by the bytes argument. No special /// significance is attached to any of the values. static UUID fromData(const void *bytes, uint32_t num_bytes) { diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/UnimplementedError.h b/contrib/llvm-project/lldb/include/lldb/Utility/UnimplementedError.h new file mode 100644 index 000000000000..c6fab0a9483c --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Utility/UnimplementedError.h @@ -0,0 +1,28 @@ +//===-- UnimplementedError.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_UTILITY_UNIMPLEMENTEDERROR_H +#define LLDB_UTILITY_UNIMPLEMENTEDERROR_H + +#include "llvm/Support/Errc.h" +#include "llvm/Support/Error.h" + +namespace lldb_private { +class UnimplementedError : public llvm::ErrorInfo<UnimplementedError> { +public: + static char ID; + + void log(llvm::raw_ostream &OS) const override { OS << "Not implemented"; } + + std::error_code convertToErrorCode() const override { + return llvm::errc::not_supported; + }; +}; +} // namespace lldb_private + +#endif // LLDB_UTILITY_UNIMPLEMENTEDERROR_H diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/XcodeSDK.h b/contrib/llvm-project/lldb/include/lldb/Utility/XcodeSDK.h index 307fe7f46798..878b131a1814 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/XcodeSDK.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/XcodeSDK.h @@ -65,11 +65,11 @@ public: /// The merge function follows a strict order to maintain monotonicity: /// 1. SDK with the higher SDKType wins. /// 2. The newer SDK wins. - void Merge(XcodeSDK other); + void Merge(const XcodeSDK &other); - XcodeSDK &operator=(XcodeSDK other); + XcodeSDK &operator=(const XcodeSDK &other); XcodeSDK(const XcodeSDK&) = default; - bool operator==(XcodeSDK other); + bool operator==(const XcodeSDK &other); /// Return parsed SDK type and version number. Info Parse() const; diff --git a/contrib/llvm-project/lldb/include/lldb/lldb-defines.h b/contrib/llvm-project/lldb/include/lldb/lldb-defines.h index fea8079779a1..487cd0b01d5c 100644 --- a/contrib/llvm-project/lldb/include/lldb/lldb-defines.h +++ b/contrib/llvm-project/lldb/include/lldb/lldb-defines.h @@ -95,6 +95,7 @@ #define LLDB_INVALID_SIGNAL_NUMBER INT32_MAX #define LLDB_INVALID_OFFSET UINT64_MAX // Must match max of lldb::offset_t #define LLDB_INVALID_LINE_NUMBER UINT32_MAX +#define LLDB_INVALID_COLUMN_NUMBER 0 #define LLDB_INVALID_QUEUE_ID 0 /// CPU Type definitions @@ -119,6 +120,7 @@ #define LLDB_OPT_SET_9 (1U << 8) #define LLDB_OPT_SET_10 (1U << 9) #define LLDB_OPT_SET_11 (1U << 10) +#define LLDB_OPT_SET_12 (1U << 11) #define LLDB_OPT_SET_FROM_TO(A, B) \ (((1U << (B)) - 1) ^ (((1U << (A)) - 1) >> 1)) diff --git a/contrib/llvm-project/lldb/include/lldb/lldb-enumerations.h b/contrib/llvm-project/lldb/include/lldb/lldb-enumerations.h index c9def56ff109..b3f8198b1146 100644 --- a/contrib/llvm-project/lldb/include/lldb/lldb-enumerations.h +++ b/contrib/llvm-project/lldb/include/lldb/lldb-enumerations.h @@ -126,6 +126,9 @@ FLAGS_ENUM(LaunchFlags){ eLaunchFlagShellExpandArguments = (1u << 10), ///< Perform shell-style argument expansion eLaunchFlagCloseTTYOnExit = (1u << 11), ///< Close the open TTY on exit + eLaunchFlagInheritTCCFromParent = + (1u << 12), ///< Don't make the inferior responsible for its own TCC + ///< permissions but instead inherit them from its parent. }; /// Thread Run Modes. @@ -526,6 +529,7 @@ enum CommandArgumentType { eArgTypeExpression, eArgTypeExpressionPath, eArgTypeExprFormat, + eArgTypeFileLineColumn, eArgTypeFilename, eArgTypeFormat, eArgTypeFrameIndex, @@ -592,6 +596,7 @@ enum CommandArgumentType { eArgRawInput, eArgTypeCommand, eArgTypeColumnNum, + eArgTypeModuleUUID, eArgTypeLastArg // Always keep this entry as the last entry in this // enumeration!! }; @@ -764,10 +769,11 @@ enum BasicType { eBasicTypeOther }; +/// Deprecated enum TraceType { eTraceTypeNone = 0, - // Hardware Trace generated by the processor. + /// Intel Processor Trace eTraceTypeProcessorTrace }; @@ -964,7 +970,7 @@ enum GdbSignal { eGdbSignalBreakpoint = 0x96 }; -/// Used with SBHost::GetPath (lldb::PathType) to find files that are +/// Used with SBHostOS::GetLLDBPath (lldb::PathType) to find files that are /// related to LLDB on the current host machine. Most files are /// relative to LLDB or are in known locations. enum PathType { @@ -1075,7 +1081,12 @@ FLAGS_ENUM(CommandFlags){ /// /// Verifies that there is a paused process in m_exe_ctx, if there isn't, /// the command will fail with an appropriate error message. - eCommandProcessMustBePaused = (1u << 7)}; + eCommandProcessMustBePaused = (1u << 7), + /// eCommandProcessMustBeTraced + /// + /// Verifies that the process is being traced by a Trace plug-in, if it + /// isn't the command will fail with an appropriate error message. + eCommandProcessMustBeTraced = (1u << 8)}; /// Whether a summary should cap how much data it returns to users or not. enum TypeSummaryCapping { diff --git a/contrib/llvm-project/lldb/include/lldb/lldb-forward.h b/contrib/llvm-project/lldb/include/lldb/lldb-forward.h index 4fd2a07dd616..a297a928a3f4 100644 --- a/contrib/llvm-project/lldb/include/lldb/lldb-forward.h +++ b/contrib/llvm-project/lldb/include/lldb/lldb-forward.h @@ -192,7 +192,6 @@ class Status; class StopInfo; class Stoppoint; class StoppointCallbackContext; -class StoppointLocation; class Stream; class StreamFile; class StreamString; @@ -227,6 +226,9 @@ class ThreadPlanStepRange; class ThreadPlanStepThrough; class ThreadPlanTracer; class ThreadSpec; +class ThreadTrace; +class Trace; +class TraceSessionFileParser; class TraceOptions; class Type; class TypeAndOrName; @@ -402,8 +404,9 @@ typedef std::weak_ptr<lldb_private::StackFrame> StackFrameWP; typedef std::shared_ptr<lldb_private::StackFrameList> StackFrameListSP; typedef std::shared_ptr<lldb_private::StackFrameRecognizer> StackFrameRecognizerSP; +typedef std::unique_ptr<lldb_private::StackFrameRecognizerManager> + StackFrameRecognizerManagerUP; typedef std::shared_ptr<lldb_private::StopInfo> StopInfoSP; -typedef std::shared_ptr<lldb_private::StoppointLocation> StoppointLocationSP; typedef std::shared_ptr<lldb_private::Stream> StreamSP; typedef std::weak_ptr<lldb_private::Stream> StreamWP; typedef std::shared_ptr<lldb_private::StreamFile> StreamFileSP; @@ -430,7 +433,9 @@ typedef std::shared_ptr<lldb_private::Thread> ThreadSP; typedef std::weak_ptr<lldb_private::Thread> ThreadWP; typedef std::shared_ptr<lldb_private::ThreadCollection> ThreadCollectionSP; typedef std::shared_ptr<lldb_private::ThreadPlan> ThreadPlanSP; +typedef std::weak_ptr<lldb_private::ThreadPlan> ThreadPlanWP; typedef std::shared_ptr<lldb_private::ThreadPlanTracer> ThreadPlanTracerSP; +typedef std::shared_ptr<lldb_private::Trace> TraceSP; typedef std::shared_ptr<lldb_private::TraceOptions> TraceOptionsSP; typedef std::shared_ptr<lldb_private::Type> TypeSP; typedef std::weak_ptr<lldb_private::Type> TypeWP; diff --git a/contrib/llvm-project/lldb/include/lldb/lldb-private-interfaces.h b/contrib/llvm-project/lldb/include/lldb/lldb-private-interfaces.h index 1568e7a3cb51..df33f8af0e14 100644 --- a/contrib/llvm-project/lldb/include/lldb/lldb-private-interfaces.h +++ b/contrib/llvm-project/lldb/include/lldb/lldb-private-interfaces.h @@ -18,6 +18,13 @@ #include <memory> #include <set> +namespace llvm { +namespace json { +class Object; +class Value; +} +} // namespace llvm + namespace lldb_private { typedef lldb::ABISP (*ABICreateInstance)(lldb::ProcessSP process_sp, const ArchSpec &arch); @@ -69,7 +76,7 @@ typedef lldb::PlatformSP (*PlatformCreateInstance)(bool force, const ArchSpec *arch); typedef lldb::ProcessSP (*ProcessCreateInstance)( lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, - const FileSpec *crash_file_path); + const FileSpec *crash_file_path, bool can_connect); typedef lldb::ScriptInterpreterSP (*ScriptInterpreterCreateInstance)( Debugger &debugger); typedef SymbolFile *(*SymbolFileCreateInstance)(lldb::ObjectFileSP objfile_sp); @@ -104,6 +111,11 @@ typedef lldb::REPLSP (*REPLCreateInstance)(Status &error, const char *repl_options); typedef int (*ComparisonFunction)(const void *, const void *); typedef void (*DebuggerInitializeCallback)(Debugger &debugger); +typedef llvm::Expected<lldb::TraceSP> (*TraceCreateInstance)( + const llvm::json::Value &trace_session_file, + llvm::StringRef session_file_dir, lldb_private::Debugger &debugger); +typedef lldb::CommandObjectSP (*TraceGetStartCommand)( + CommandInterpreter &interpreter); } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/lldb-private-types.h b/contrib/llvm-project/lldb/include/lldb/lldb-private-types.h index fb8c2db2e21c..c7e652650da7 100644 --- a/contrib/llvm-project/lldb/include/lldb/lldb-private-types.h +++ b/contrib/llvm-project/lldb/include/lldb/lldb-private-types.h @@ -107,33 +107,6 @@ struct OptionValidator { virtual const char *LongConditionString() const = 0; }; -struct OptionDefinition { - /// Used to mark options that can be used together. If - /// `(1 << n & usage_mask) != 0` then this option belongs to option set n. - uint32_t usage_mask; - /// This option is required (in the current usage level). - bool required; - /// Full name for this option. - const char *long_option; - /// Single character for this option. - int short_option; - /// no_argument, required_argument or optional_argument - int option_has_arg; - /// If non-NULL, option is valid iff |validator->IsValid()|, otherwise - /// always valid. - OptionValidator *validator; - /// If not empty, an array of enum values. - OptionEnumValues enum_values; - /// The kind of completion for this option. - /// Contains values of the CommandCompletions::CommonCompletionTypes enum. - uint32_t completion_type; - /// Type of argument this option takes. - lldb::CommandArgumentType argument_type; - /// Full text explaining what this options does and what (if any) argument to - /// pass it. - const char *usage_text; -}; - typedef struct type128 { uint64_t x[2]; } type128; typedef struct type256 { uint64_t x[4]; } type256; |