diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2021-08-22 19:00:43 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2021-11-13 20:39:49 +0000 |
commit | fe6060f10f634930ff71b7c50291ddc610da2475 (patch) | |
tree | 1483580c790bd4d27b6500a7542b5ee00534d3cc /contrib/llvm-project/lldb | |
parent | b61bce17f346d79cecfd8f195a64b10f77be43b1 (diff) | |
parent | 344a3780b2e33f6ca763666c380202b18aab72a3 (diff) |
Diffstat (limited to 'contrib/llvm-project/lldb')
954 files changed, 20608 insertions, 12449 deletions
diff --git a/contrib/llvm-project/lldb/bindings/headers.swig b/contrib/llvm-project/lldb/bindings/headers.swig index 6e1668ea4c42..3c2cd85f504d 100644 --- a/contrib/llvm-project/lldb/bindings/headers.swig +++ b/contrib/llvm-project/lldb/bindings/headers.swig @@ -62,7 +62,6 @@ #include "lldb/API/SBThreadCollection.h" #include "lldb/API/SBThreadPlan.h" #include "lldb/API/SBTrace.h" -#include "lldb/API/SBTraceOptions.h" #include "lldb/API/SBType.h" #include "lldb/API/SBTypeCategory.h" #include "lldb/API/SBTypeEnumMember.h" diff --git a/contrib/llvm-project/lldb/bindings/interface/SBBreakpoint.i b/contrib/llvm-project/lldb/bindings/interface/SBBreakpoint.i index 37fcc7fbab48..a7048309edd9 100644 --- a/contrib/llvm-project/lldb/bindings/interface/SBBreakpoint.i +++ b/contrib/llvm-project/lldb/bindings/interface/SBBreakpoint.i @@ -184,7 +184,7 @@ public: %feature("docstring", " Set the name of the script function to be called when the breakpoint is hit. - To use this variant, the function should take (frame, bp_loc, extra_args, dict) and + To use this variant, the function should take (frame, bp_loc, extra_args, internal_dict) and when the breakpoint is hit the extra_args will be passed to the callback function.") SetScriptCallbackFunction; SBError SetScriptCallbackFunction (const char *callback_function_name, diff --git a/contrib/llvm-project/lldb/bindings/interface/SBBreakpointLocation.i b/contrib/llvm-project/lldb/bindings/interface/SBBreakpointLocation.i index fc37475ba745..354737b98c6a 100644 --- a/contrib/llvm-project/lldb/bindings/interface/SBBreakpointLocation.i +++ b/contrib/llvm-project/lldb/bindings/interface/SBBreakpointLocation.i @@ -74,13 +74,13 @@ public: %feature("docstring", " Set the callback to the given Python function name. - The function takes three arguments (frame, bp_loc, dict).") SetScriptCallbackFunction; + The function takes three arguments (frame, bp_loc, internal_dict).") SetScriptCallbackFunction; void SetScriptCallbackFunction (const char *callback_function_name); %feature("docstring", " Set the name of the script function to be called when the breakpoint is hit. - To use this variant, the function should take (frame, bp_loc, extra_args, dict) and + To use this variant, the function should take (frame, bp_loc, extra_args, internal_dict) and when the breakpoint is hit the extra_args will be passed to the callback function.") SetScriptCallbackFunction; SBError SetScriptCallbackFunction (const char *callback_function_name, diff --git a/contrib/llvm-project/lldb/bindings/interface/SBCommandInterpreterRunOptions.i b/contrib/llvm-project/lldb/bindings/interface/SBCommandInterpreterRunOptions.i index 1a618a228bbe..28437abb60c6 100644 --- a/contrib/llvm-project/lldb/bindings/interface/SBCommandInterpreterRunOptions.i +++ b/contrib/llvm-project/lldb/bindings/interface/SBCommandInterpreterRunOptions.i @@ -18,6 +18,7 @@ A default SBCommandInterpreterRunOptions object has: * StopOnCrash: false * EchoCommands: true * PrintResults: true +* PrintErrors: true * AddToHistory: true ") SBCommandInterpreterRunOptions; @@ -59,6 +60,12 @@ public: SetPrintResults (bool); bool + GetPrintErrors () const; + + void + SetPrintErrors (bool); + + bool GetAddToHistory () const; void diff --git a/contrib/llvm-project/lldb/bindings/interface/SBLaunchInfo.i b/contrib/llvm-project/lldb/bindings/interface/SBLaunchInfo.i index d76656ddd493..535ed3b79060 100644 --- a/contrib/llvm-project/lldb/bindings/interface/SBLaunchInfo.i +++ b/contrib/llvm-project/lldb/bindings/interface/SBLaunchInfo.i @@ -135,6 +135,16 @@ public: void SetDetachOnError(bool enable); + + const char * + GetScriptedProcessClassName() const; + + void SetScriptedProcessClassName(const char *class_name); + + lldb::SBStructuredData + GetScriptedProcessDictionary() const; + + void SetScriptedProcessDictionary(lldb::SBStructuredData dict); }; } // namespace lldb diff --git a/contrib/llvm-project/lldb/bindings/interface/SBMemoryRegionInfo.i b/contrib/llvm-project/lldb/bindings/interface/SBMemoryRegionInfo.i index 6a2ad6a3e364..3460dc0d06e2 100644 --- a/contrib/llvm-project/lldb/bindings/interface/SBMemoryRegionInfo.i +++ b/contrib/llvm-project/lldb/bindings/interface/SBMemoryRegionInfo.i @@ -46,6 +46,42 @@ public: const char * GetName (); + %feature("autodoc", " + GetRegionEnd(SBMemoryRegionInfo self) -> lldb::addr_t + Returns whether this memory region has a list of modified (dirty) + pages available or not. When calling GetNumDirtyPages(), you will + have 0 returned for both \"dirty page list is not known\" and + \"empty dirty page list\" (that is, no modified pages in this + memory region). You must use this method to disambiguate.") HasDirtyMemoryPageList; + bool + HasDirtyMemoryPageList(); + + %feature("autodoc", " + GetNumDirtyPages(SBMemoryRegionInfo self) -> uint32_t + Return the number of dirty (modified) memory pages in this + memory region, if available. You must use the + SBMemoryRegionInfo::HasDirtyMemoryPageList() method to + determine if a dirty memory list is available; it will depend + on the target system can provide this information.") GetNumDirtyPages; + uint32_t + GetNumDirtyPages(); + + %feature("autodoc", " + GetDirtyPageAddressAtIndex(SBMemoryRegionInfo self, uint32_t idx) -> lldb::addr_t + Return the address of a modified, or dirty, page of memory. + If the provided index is out of range, or this memory region + does not have dirty page information, LLDB_INVALID_ADDRESS + is returned.") GetDirtyPageAddressAtIndex; + addr_t + GetDirtyPageAddressAtIndex(uint32_t idx); + + %feature("autodoc", " + GetPageSize(SBMemoryRegionInfo self) -> int + Return the size of pages in this memory region. 0 will be returned + if this information was unavailable.") GetPageSize(); + int + GetPageSize(); + bool operator == (const lldb::SBMemoryRegionInfo &rhs) const; diff --git a/contrib/llvm-project/lldb/bindings/interface/SBProcess.i b/contrib/llvm-project/lldb/bindings/interface/SBProcess.i index e30b89d1ed39..14566a2942d0 100644 --- a/contrib/llvm-project/lldb/bindings/interface/SBProcess.i +++ b/contrib/llvm-project/lldb/bindings/interface/SBProcess.i @@ -400,9 +400,6 @@ public: lldb::SBError SaveCore(const char *file_name); - lldb::SBTrace - StartTrace(SBTraceOptions &options, lldb::SBError &error); - lldb::SBError GetMemoryRegionInfo(lldb::addr_t load_addr, lldb::SBMemoryRegionInfo ®ion_info); @@ -420,6 +417,25 @@ public: lldb::SBProcessInfo GetProcessInfo(); + %feature("autodoc", " + Allocates a block of memory within the process, with size and + access permissions specified in the arguments. The permisssions + argument is an or-combination of zero or more of + lldb.ePermissionsWritable, lldb.ePermissionsReadable, and + lldb.ePermissionsExecutable. Returns the address + of the allocated buffer in the process, or + lldb.LLDB_INVALID_ADDRESS if the allocation failed.") AllocateMemory; + + lldb::addr_t + AllocateMemory(size_t size, uint32_t permissions, lldb::SBError &error); + + %feature("autodoc", " + Deallocates the block of memory (previously allocated using + AllocateMemory) given in the argument.") DeallocateMemory; + + lldb::SBError + DeallocateMemory(lldb::addr_t ptr); + STRING_EXTENSION(SBProcess) #ifdef SWIGPYTHON diff --git a/contrib/llvm-project/lldb/bindings/interface/SBProcessInfo.i b/contrib/llvm-project/lldb/bindings/interface/SBProcessInfo.i index 009842599bf8..17b2761a344e 100644 --- a/contrib/llvm-project/lldb/bindings/interface/SBProcessInfo.i +++ b/contrib/llvm-project/lldb/bindings/interface/SBProcessInfo.i @@ -62,6 +62,12 @@ public: lldb::pid_t GetParentProcessID (); + + %feature("docstring", + "Return the target triple (arch-vendor-os) for the described process." + ) GetTriple; + const char * + GetTriple (); }; } // namespace lldb diff --git a/contrib/llvm-project/lldb/bindings/interface/SBStructuredData.i b/contrib/llvm-project/lldb/bindings/interface/SBStructuredData.i index 5aba35229855..ba5b7e075065 100644 --- a/contrib/llvm-project/lldb/bindings/interface/SBStructuredData.i +++ b/contrib/llvm-project/lldb/bindings/interface/SBStructuredData.i @@ -58,5 +58,8 @@ This class wraps the event type generated by StructuredData features." lldb::SBError SetFromJSON(lldb::SBStream &stream); + + lldb::SBError + SetFromJSON(const char *json); }; } diff --git a/contrib/llvm-project/lldb/bindings/interface/SBTarget.i b/contrib/llvm-project/lldb/bindings/interface/SBTarget.i index f874726b42d8..3f9e4cdc6d67 100644 --- a/contrib/llvm-project/lldb/bindings/interface/SBTarget.i +++ b/contrib/llvm-project/lldb/bindings/interface/SBTarget.i @@ -938,6 +938,16 @@ public: lldb::addr_t GetStackRedZoneSize(); + %feature("docstring", " + Returns true if the module has been loaded in this `SBTarget`. + A module can be loaded either by the dynamic loader or by being manually + added to the target (see `SBTarget.AddModule` and the `target module add` command). + + :rtype: bool + ") IsLoaded; + bool + IsLoaded (const lldb::SBModule &module) const; + lldb::SBLaunchInfo GetLaunchInfo () const; @@ -964,6 +974,12 @@ public: STRING_EXTENSION_LEVEL(SBTarget, lldb::eDescriptionLevelBrief) + lldb::SBTrace + GetTrace (); + + lldb::SBTrace + CreateTrace (lldb::SBError &error); + #ifdef SWIGPYTHON %pythoncode %{ class modules_access(object): diff --git a/contrib/llvm-project/lldb/bindings/interface/SBThread.i b/contrib/llvm-project/lldb/bindings/interface/SBThread.i index 463584d2cab1..d847d38f0d66 100644 --- a/contrib/llvm-project/lldb/bindings/interface/SBThread.i +++ b/contrib/llvm-project/lldb/bindings/interface/SBThread.i @@ -104,6 +104,9 @@ public: eStopReasonSignal 1 unix signal number eStopReasonException N exception data eStopReasonExec 0 + eStopReasonFork 1 pid of the child process + eStopReasonVFork 1 pid of the child process + eStopReasonVForkDone 0 eStopReasonPlanComplete 0") GetStopReasonDataAtIndex; uint64_t GetStopReasonDataAtIndex(uint32_t idx); diff --git a/contrib/llvm-project/lldb/bindings/interface/SBThreadPlan.i b/contrib/llvm-project/lldb/bindings/interface/SBThreadPlan.i index 94ae1a42dd3b..9e1053525354 100644 --- a/contrib/llvm-project/lldb/bindings/interface/SBThreadPlan.i +++ b/contrib/llvm-project/lldb/bindings/interface/SBThreadPlan.i @@ -73,6 +73,9 @@ public: eStopReasonSignal 1 unix signal number eStopReasonException N exception data eStopReasonExec 0 + eStopReasonFork 1 pid of the child process + eStopReasonVFork 1 pid of the child process + eStopReasonVForkDone 0 eStopReasonPlanComplete 0") GetStopReasonDataAtIndex; uint64_t GetStopReasonDataAtIndex(uint32_t idx); diff --git a/contrib/llvm-project/lldb/bindings/interface/SBTrace.i b/contrib/llvm-project/lldb/bindings/interface/SBTrace.i index 6d4b7e6be27d..0f5bf0ecc8d9 100644 --- a/contrib/llvm-project/lldb/bindings/interface/SBTrace.i +++ b/contrib/llvm-project/lldb/bindings/interface/SBTrace.i @@ -14,25 +14,19 @@ namespace lldb { class LLDB_API SBTrace { public: SBTrace(); - size_t GetTraceData(SBError &error, void *buf, - size_t size, size_t offset, - lldb::tid_t thread_id); - size_t GetMetaData(SBError &error, void *buf, - size_t size, size_t offset, - lldb::tid_t thread_id); + const char *GetStartConfigurationHelp(); - void StopTrace(SBError &error, - lldb::tid_t thread_id); + SBError Start(const SBStructuredData &configuration); - void GetTraceConfig(SBTraceOptions &options, - SBError &error); + SBError Start(const SBThread &thread, const SBStructuredData &configuration); - lldb::user_id_t GetTraceUID(); + SBError Stop(); + + SBError Stop(const SBThread &thread); explicit operator bool() const; bool IsValid(); - }; -} // namespace lldb
\ No newline at end of file +} // namespace lldb diff --git a/contrib/llvm-project/lldb/bindings/interface/SBTraceOptions.i b/contrib/llvm-project/lldb/bindings/interface/SBTraceOptions.i deleted file mode 100644 index 4a1878b5b76f..000000000000 --- a/contrib/llvm-project/lldb/bindings/interface/SBTraceOptions.i +++ /dev/null @@ -1,44 +0,0 @@ -//===-- SWIG Interface for SBTraceOptions -----------------------*- 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 -// -//===----------------------------------------------------------------------===// - -namespace lldb { - -%feature("docstring", -"Represents the possible options when doing processor tracing. - -See :py:class:`SBProcess.StartTrace`." -) SBTraceOptions; -class LLDB_API SBTraceOptions { -public: - SBTraceOptions(); - - lldb::TraceType getType() const; - - uint64_t getTraceBufferSize() const; - - lldb::SBStructuredData getTraceParams(lldb::SBError &error); - - uint64_t getMetaDataBufferSize() const; - - void setTraceParams(lldb::SBStructuredData ¶ms); - - void setType(lldb::TraceType type); - - void setTraceBufferSize(uint64_t size); - - void setMetaDataBufferSize(uint64_t size); - - void setThreadID(lldb::tid_t thread_id); - - lldb::tid_t getThreadID(); - - explicit operator bool() const; - - bool IsValid(); -}; -} diff --git a/contrib/llvm-project/lldb/bindings/interface/SBType.i b/contrib/llvm-project/lldb/bindings/interface/SBType.i index e7b3fd11e338..500bc99ca8cd 100644 --- a/contrib/llvm-project/lldb/bindings/interface/SBType.i +++ b/contrib/llvm-project/lldb/bindings/interface/SBType.i @@ -111,8 +111,24 @@ protected: }; %feature("docstring", -"Represents a data type in lldb. The FindFirstType() method of SBTarget/SBModule -returns a SBType. +"Represents a data type in lldb. + +The actual characteristics of each type are defined by the semantics of the +programming language and the specific language implementation that was used +to compile the target program. See the language-specific notes in the +documentation of each method. + +SBType instances can be obtained by a variety of methods. +`SBTarget.FindFirstType` and `SBModule.FindFirstType` can be used to create +`SBType` representations of types in executables/libraries with debug +information. For some languages such as C, C++ and Objective-C it is possible +to create new types by evaluating expressions that define a new type. + +Note that most `SBType` properties are computed independently of any runtime +information so for dynamic languages the functionality can be very limited. +`SBValue` can be used to represent runtime values which then can be more +accurately queried for certain information such as byte size. + SBType supports the eq/ne operator. For example,:: @@ -181,7 +197,7 @@ SBType supports the eq/ne operator. For example,:: # id_type and int_type should be the same type! self.assertTrue(id_type == int_type) -...") SBType; +") SBType; class SBType { public: @@ -196,132 +212,649 @@ public: explicit operator bool() const; + + %feature("docstring", + "Returns the number of bytes a variable with the given types occupies in memory. + + Returns ``0`` if the size can't be determined. + + If a type occupies ``N`` bytes + ``M`` bits in memory, this function returns + the rounded up amount of bytes (i.e., if ``M`` is ``0``, + this function returns ``N`` and otherwise ``N + 1``). + + Language-specific behaviour: + + * C: The output is expected to match the value of ``sizeof(Type)``. If + ``sizeof(Type)`` is not a valid expression for the given type, the + function returns ``0``. + * C++: Same as in C. + * Objective-C: Same as in C. For Objective-C classes this always returns + `0`` as the actual size depends on runtime information. + ") GetByteSize; uint64_t GetByteSize(); + + %feature("docstring", + "Returns true if this type is a pointer type. + + Language-specific behaviour: + + * C: Returns true for C pointer types (or typedefs of these types). + * C++: Pointer types include the C pointer types as well as pointers to data + mebers or member functions. + * Objective-C: Pointer types include the C pointer types. ``id``, ``Class`` + and pointers to blocks are also considered pointer types. + ") IsPointerType; bool IsPointerType(); + %feature("docstring", + "Returns true if this type is a reference type. + + Language-specific behaviour: + + * C: Returns false for all types. + * C++: Both l-value and r-value references are considered reference types. + * Objective-C: Returns false for all types. + ") IsReferenceType; bool IsReferenceType(); + %feature("docstring", + "Returns true if this type is a function type. + + Language-specific behaviour: + + * C: Returns true for types that represent functions. Note that function + pointers are not function types (but their `GetPointeeType()` are function + types). + * C++: Same as in C. + * Objective-C: Returns false for all types. + ") IsPolymorphicClass; bool IsFunctionType (); + %feature("docstring", + "Returns true if this type is a polymorphic type. + + Language-specific behaviour: + + * C: Returns false for all types. + * C++: Returns true if the type is a class type that contains at least one + virtual member function or if at least one of its base classes is + considered a polymorphic type. + * Objective-C: Returns false for all types. + ") IsPolymorphicClass; bool IsPolymorphicClass (); + %feature("docstring", + "Returns true if this type is an array type. + + Language-specific behaviour: + + * C: Returns true if the types is an array type. This includes incomplete + array types ``T[]`` and array types with integer (``T[1]``) or variable + length (``T[some_variable]``). Pointer types are not considered arrays. + * C++: Includes C's array types and dependent array types (i.e., array types + in templates which size depends on template arguments). + * Objective-C: Same as in C. + ") IsArrayType; bool IsArrayType (); + %feature("docstring", + "Returns true if this type is a vector type. + + Language-specific behaviour: + + * C: Returns true if the types is a vector type created with + GCC's ``vector_size`` or Clang's ``ext_vector_type`` feature. + * C++: Same as in C. + * Objective-C: Same as in C. + ") IsVectorType; bool IsVectorType (); + %feature("docstring", + "Returns true if this type is a typedef. + + Language-specific behaviour: + + * C: Returns true if the type is a C typedef. + * C++: Same as in C. Also treats type aliases as typedefs. + * Objective-C: Same as in C. + ") IsTypedefType; bool IsTypedefType (); + %feature("docstring", + "Returns true if this type is an anonymous type. + + Language-specific behaviour: + + * C: Returns true for anonymous unions. Also returns true for + anonymous structs (which are a GNU language extension). + * C++: Same as in C. + * Objective-C: Same as in C. + ") IsAnonymousType; bool IsAnonymousType (); + %feature("docstring", + "Returns true if this type is a scoped enum. + + Language-specific behaviour: + + * C: Returns false for all types. + * C++: Return true only for C++11 scoped enums. + * Objective-C: Returns false for all types. + ") IsScopedEnumerationType; bool IsScopedEnumerationType (); + %feature("docstring", + "Returns a type that represents a pointer to this type. + + If the type system of the current language can't represent a pointer to this + type or this type is invalid, an invalid `SBType` is returned. + + Language-specific behaviour: + + * C: Returns the pointer type of this type. + * C++: Same as in C. + * Objective-C: Same as in C. + ") GetPointerType; lldb::SBType GetPointerType(); + %feature("docstring", + "Returns the underlying pointee type. + + If this type is a pointer type as specified by `IsPointerType` then this + returns the underlying type. If this is not a pointer type or an invalid + `SBType` then this returns an invalid `SBType`. + + Language-specific behaviour: + + * C: Returns the underlying type for for C pointer types or typedefs of + these types). For example, ``int *`` will return ``int``. + * C++: Same as in C. Returns an `SBType` representation for data members/ + member functions in case the `SBType` is a pointer to data member or + pointer to member function. + * Objective-C: Same as in C. The pointee type of ``id`` and ``Class`` is + an invalid `SBType`. The pointee type of pointers Objective-C types is an + `SBType` for the non-pointer type of the respective type. For example, + ``NSString *`` will return ``NSString`` as a pointee type. + ") GetPointeeType; lldb::SBType GetPointeeType(); + %feature("docstring", + "Returns a type that represents a reference to this type. + + If the type system of the current language can't represent a reference to + this type, an invalid `SBType` is returned. + + Language-specific behaviour: + + * C: Currently assumes the type system is C++ and returns an l-value + reference type. For example, ``int`` will return ``int&``. This behavior + is likely to change in the future and shouldn't be relied on. + * C++: Same as in C. + * Objective-C: Same as in C. + ") GetReferenceType; lldb::SBType GetReferenceType(); + %feature("docstring", + "Returns the underlying type of a typedef. + + If this type is a typedef as designated by `IsTypedefType`, then the + underlying type is being returned. Otherwise an invalid `SBType` is + returned. + + Language-specific behaviour: + + * C: Returns the underlying type of a typedef type. + * C++: Same as in C. For type aliases, the underlying type is returned. + * Objective-C: Same as in C. + ") GetTypedefedType; lldb::SBType SBType::GetTypedefedType(); + %feature("docstring", + "Returns the underlying type of a reference type. + + If this type is a reference as designated by `IsReferenceType`, then the + underlying type is being returned. Otherwise an invalid `SBType` is + returned. + + Language-specific behaviour: + + * C: Always returns an invalid type. + * C++: For l-value and r-value references the underlying type is returned. + For example, ``int &`` will return ``int``. + * Objective-C: Same as in C. + ") GetDereferencedType; lldb::SBType GetDereferencedType(); + %feature("docstring", + "Returns the unqualified version of this type. + + Language-specific behaviour: + + * C: If this type with any const or volatile specifier removed. + * C++: Same as in C. + * Objective-C: Same as in C. + ") GetUnqualifiedType; lldb::SBType GetUnqualifiedType(); lldb::SBType GetCanonicalType(); + %feature("docstring", + "Returns the underlying integer type if this is an enumeration type. + + If this type is an invalid `SBType` or not an enumeration type an invalid + `SBType` is returned. + + Language-specific behaviour: + + * C: Returns the underlying type for enums. + * C++: Same as in C but also returns the underlying type for scoped enums. + * Objective-C: Same as in C. + ") GetEnumerationIntegerType; lldb::SBType GetEnumerationIntegerType(); + %feature("docstring", + "Returns the array element type if this type is an array type. + + Otherwise returns an invalid `SBType` if this type is invalid or not an + array type. + + Language-specific behaviour: + + * C: If this is an array type (see `IsArrayType`) such as ``T[]``, returns + the element type. + * C++: Same as in C. + * Objective-C: Same as in C. + + See also `IsArrayType`. + ") GetArrayElementType; lldb::SBType GetArrayElementType (); + %feature("docstring", + "Returns the array type with the given constant size. + + Language-specific behaviour: + + * C: Returns a constant-size array `T[size]` for any non-void type. + * C++: Same as in C. + * Objective-C: Same as in C. + + See also `IsArrayType` and `GetArrayElementType`. + ") GetArrayType; lldb::SBType GetArrayType (uint64_t size); + %feature("docstring", + "Returns the vector element type if this type is a vector type. + + Otherwise returns an invalid `SBType` if this type is invalid or not a + vector type. + + Language-specific behaviour: + + * C: If this is a vector type (see `IsVectorType`), returns the element + type. + * C++: Same as in C. + * Objective-C: Same as in C. + + See also `IsVectorType`. + ") GetVectorElementType; lldb::SBType GetVectorElementType (); + %feature("docstring", + "Returns the `BasicType` value that is most appropriate to this type. + + Returns `eBasicTypeInvalid` if no appropriate `BasicType` was found or this + type is invalid. See the `BasicType` documentation for the language-specific m + aning of each `BasicType` value. + + **Overload behaviour:** When called with a `BasicType` parameter, the + following behaviour applies: + + Returns the `SBType` that represents the passed `BasicType` value. Returns + an invalid `SBType` if no fitting `SBType` could be created. + + Language-specific behaviour: + + * C: Returns the respective builtin type. Note that some types + (e.g. ``__uint128_t``) might even be successfully created even if they are + not available on the target platform. C++ and Objective-C specific types + might also be created even if the target program is not written in C++ or + Objective-C. + * C++: Same as in C. + * Objective-C: Same as in C. + "); lldb::BasicType GetBasicType(); lldb::SBType GetBasicType (lldb::BasicType type); + %feature("docstring", + "Returns the number of fields of this type. + + Returns ``0`` if this type does not have fields. + + Language-specific behaviour: + + * C: Returns the number of fields if the type is a struct. If the type + contains an anonymous struct/union it only counts as a single field (even + if the struct/union contains several fields). + * C++: Returns the number of non-static fields if the type is a + struct/class. If the type contains an anonymous struct/union it only + counts as a single field (even if the struct/union contains several + fields). The fields of any base classes are not included in the count. + * Objective-C: Same as in C for structs. For Objective-C classes the number + of ivars is returned. + + See also `GetFieldAtIndex`. + ") GetNumberOfFields; uint32_t GetNumberOfFields (); + %feature("docstring", + "Returns the number of base/parent classes of this type. + + Returns ``0`` if this type doesn't have any base classes. + + Language-specific behaviour: + + * C: Returns always ``0``. + * C++: The number of direct non-virtual base classes if this type is + a class. + * Objective-C: The number of super classes for Objective-C classes. + As Objective-C doesn't have multiple inheritance this is usually returns 1 + except for NSObject. + ") GetNumberOfDirectBaseClasses; uint32_t GetNumberOfDirectBaseClasses (); + %feature("docstring", + "Returns the number of virtual base/parent classes of this type + + Returns ``0`` if this type doesn't have any base classes. + + Language-specific behaviour: + + * C: Returns always ``0``. + * C++: The number of direct virtual base classes if this type is a + class. + * Objective-C: Returns always ``0``. + ") GetNumberOfVirtualBaseClasses; uint32_t GetNumberOfVirtualBaseClasses (); + %feature("docstring", + "Returns the field at the given index. + + Returns an invalid `SBType` if the index is out of range or the current + type doesn't have any fields. + + Language-specific behaviour: + + * C: Returns the field with the given index for struct types. Fields are + ordered/indexed starting from ``0`` for the first field in a struct (as + declared in the definition). + * C++: Returns the non-static field with the given index for struct types. + Fields are ordered/indexed starting from ``0`` for the first field in a + struct (as declared in the definition). + * Objective-C: Same as in C for structs. For Objective-C classes the ivar + with the given index is returned. ivars are indexed starting from ``0``. + ") GetFieldAtIndex; lldb::SBTypeMember GetFieldAtIndex (uint32_t idx); + %feature("docstring", + "Returns the direct base class as indexed by `GetNumberOfDirectBaseClasses`. + + Returns an invalid SBTypeMember if the index is invalid or this SBType is + invalid. + ") GetDirectBaseClassAtIndex; lldb::SBTypeMember GetDirectBaseClassAtIndex (uint32_t idx); + %feature("docstring", + "Returns the virtual base class as indexed by + `GetNumberOfVirtualBaseClasses`. + + Returns an invalid SBTypeMember if the index is invalid or this SBType is + invalid. + ") GetVirtualBaseClassAtIndex; lldb::SBTypeMember GetVirtualBaseClassAtIndex (uint32_t idx); lldb::SBTypeEnumMemberList GetEnumMembers(); + %feature("docstring", + "Returns the `SBModule` this `SBType` belongs to. + Returns no `SBModule` if this type does not belong to any specific + `SBModule` or this `SBType` is invalid. An invalid `SBModule` might also + indicate that once came from an `SBModule` but LLDB could no longer + determine the original module. + ") GetModule; lldb::SBModule GetModule(); + %feature("autodoc", "GetName() -> string") GetName; + %feature("docstring", + "Returns the name of this type. + + Returns an empty string if an error occurred or this type is invalid. + + Use this function when trying to match a specific type by name in a script. + The names returned by this function try to uniquely identify a name but + conflicts can occur (for example, if a C++ program contains two different + classes with the same name in different translation units. `GetName` can + return the same name for both class types.) + + + Language-specific behaviour: + + * C: The name of the type. For structs the ``struct`` prefix is omitted. + * C++: Returns the qualified name of the type (including anonymous/inline + namespaces and all template arguments). + * Objective-C: Same as in C. + ") GetName; const char* GetName(); + %feature("autodoc", "GetDisplayTypeName() -> string") GetDisplayTypeName; + %feature("docstring", + "Returns the name of this type in a user-friendly format. + + Returns an empty string if an error occurred or this type is invalid. + + Use this function when displaying a type name to the user. + + Language-specific behaviour: + + * C: Returns the type name. For structs the ``struct`` prefix is omitted. + * C++: Returns the qualified name. Anonymous/inline namespaces are omitted. + Template arguments that match their default value might also be hidden + (this functionality depends on whether LLDB can determine the template's + default arguments). + * Objective-C: Same as in C. + ") GetDisplayTypeName; const char * GetDisplayTypeName (); + %feature("autodoc", "GetTypeClass() -> TypeClass") GetTypeClass; + %feature("docstring", + "Returns the `TypeClass` for this type. + + Returns an `eTypeClassInvalid` if this `SBType` is invalid. + + See `TypeClass` for the language-specific meaning of each `TypeClass` value. + ") GetTypeClass; lldb::TypeClass GetTypeClass (); + %feature("docstring", + "Returns the number of template arguments of this type. + + Returns ``0`` if this type is not a template. + + Language-specific behaviour: + + * C: Always returns ``0``. + * C++: If this type is a class template instantiation then this returns the + number of template parameters that were used in this instantiation. This i + cludes both explicit and implicit template parameters. + * Objective-C: Always returns ``0``. + ") GetNumberOfTemplateArguments; uint32_t GetNumberOfTemplateArguments (); + %feature("docstring", + "Returns the type of the template argument with the given index. + + Returns an invalid `SBType` if there is no template argument with the given + index or this type is not a template. The first template argument has the + index ``0``. + + Language-specific behaviour: + + * C: Always returns an invalid SBType. + * C++: If this type is a class template instantiation and the template + parameter with the given index is a type template parameter, then this + returns the type of that parameter. Otherwise returns an invalid `SBType`. + * Objective-C: Always returns an invalid SBType. + ") GetTemplateArgumentType; lldb::SBType GetTemplateArgumentType (uint32_t idx); + %feature("docstring", + "Returns the kind of the template argument with the given index. + + Returns `eTemplateArgumentKindNull` if there is no template argument + with the given index or this type is not a template. The first template + argument has the index ``0``. + + Language-specific behaviour: + + * C: Always returns `eTemplateArgumentKindNull`. + * C++: If this type is a class template instantiation then this returns + the appropriate `TemplateArgument` value for the parameter with the given + index. See the documentation of `TemplateArgument` for how certain C++ + template parameter kinds are mapped to `TemplateArgument` values. + * Objective-C: Always returns `eTemplateArgumentKindNull`. + ") GetTemplateArgumentKind; lldb::TemplateArgumentKind GetTemplateArgumentKind (uint32_t idx); + %feature("docstring", + "Returns the return type if this type represents a function. + + Returns an invalid `SBType` if this type is not a function type or invalid. + + Language-specific behaviour: + + * C: For functions return the return type. Returns an invalid `SBType` if + this type is a function pointer type. + * C++: Same as in C for functions and instantiated template functions. + Member functions are also considered functions. For functions that have + their return type specified by a placeholder type specifier (``auto``) + this returns the deduced return type. + * Objective-C: Same as in C for functions. For Objective-C methods this + returns the return type of the method. + ") GetFunctionReturnType; lldb::SBType GetFunctionReturnType (); + %feature("docstring", + "Returns the list of argument types if this type represents a function. + + Returns an invalid `SBType` if this type is not a function type or invalid. + + Language-specific behaviour: + + * C: For functions return the types of each parameter. Returns an invalid + `SBType` if this type is a function pointer. For variadic functions this + just returns the list of parameters before the variadic arguments. + * C++: Same as in C for functions and instantiated template functions. + Member functions are also considered functions. + * Objective-C: Always returns an invalid SBType for Objective-C methods. + ") GetFunctionArgumentTypes; lldb::SBTypeList GetFunctionArgumentTypes (); + %feature("docstring", + "Returns the number of member functions of this type. + + Returns ``0`` if an error occurred or this type is invalid. + + Language-specific behaviour: + + * C: Always returns ``0``. + * C++: If this type represents a struct/class, then the number of + member functions (static and non-static) is returned. The count includes + constructors and destructors (both explicit and implicit). Member + functions of base classes are not included in the count. + * Objective-C: If this type represents a struct/class, then the + number of methods is returned. Methods in categories or super classes + are not counted. + ") GetNumberOfMemberFunctions; uint32_t GetNumberOfMemberFunctions (); + %feature("docstring", + "Returns the member function of this type with the given index. + + Returns an invalid `SBTypeMemberFunction` if the index is invalid or this + type is invalid. + + Language-specific behaviour: + + * C: Always returns an invalid `SBTypeMemberFunction`. + * C++: Returns the member function or constructor/destructor with the given + index. + * Objective-C: Returns the method with the given index. + + See `GetNumberOfMemberFunctions` for what functions can be queried by this + function. + ") GetMemberFunctionAtIndex; lldb::SBTypeMemberFunction GetMemberFunctionAtIndex (uint32_t idx); bool IsTypeComplete (); + %feature("docstring", + "Returns the `TypeFlags` values for this type. + + See the respective `TypeFlags` values for what values can be set. Returns an + integer in which each `TypeFlags` value is represented by a bit. Specific + flags can be checked via Python's bitwise operators. For example, the + `eTypeIsInteger` flag can be checked like this: + + ``(an_sb_type.GetTypeFlags() & lldb.eTypeIsInteger) != 0`` + + If this type is invalid this returns ``0``. + + See the different values for `TypeFlags` for the language-specific meanings + of each `TypeFlags` value. + ") GetTypeFlags; uint32_t GetTypeFlags (); diff --git a/contrib/llvm-project/lldb/bindings/interfaces.swig b/contrib/llvm-project/lldb/bindings/interfaces.swig index 2df7a05b4f48..c9a6d0f06056 100644 --- a/contrib/llvm-project/lldb/bindings/interfaces.swig +++ b/contrib/llvm-project/lldb/bindings/interfaces.swig @@ -69,7 +69,6 @@ %include "./interface/SBThreadCollection.i" %include "./interface/SBThreadPlan.i" %include "./interface/SBTrace.i" -%include "./interface/SBTraceOptions.i" %include "./interface/SBType.i" %include "./interface/SBTypeCategory.i" %include "./interface/SBTypeEnumMember.i" diff --git a/contrib/llvm-project/lldb/bindings/lua/lua-swigsafecast.swig b/contrib/llvm-project/lldb/bindings/lua/lua-swigsafecast.swig index a3ed37279546..0b67c41434e9 100644 --- a/contrib/llvm-project/lldb/bindings/lua/lua-swigsafecast.swig +++ b/contrib/llvm-project/lldb/bindings/lua/lua-swigsafecast.swig @@ -15,6 +15,12 @@ PushSBClass (lua_State* L, lldb::SBBreakpointLocation* breakpoint_location_sb) } void +PushSBClass (lua_State* L, lldb::SBWatchpoint* watchpoint_sb) +{ + SWIG_NewPointerObj(L, watchpoint_sb, SWIGTYPE_p_lldb__SBWatchpoint, 0); +} + +void PushSBClass (lua_State* L, lldb::SBStructuredData* structured_data_sb) { SWIG_NewPointerObj(L, structured_data_sb, SWIGTYPE_p_lldb__SBStructuredData, 0); diff --git a/contrib/llvm-project/lldb/bindings/lua/lua-wrapper.swig b/contrib/llvm-project/lldb/bindings/lua/lua-wrapper.swig index 90c22920ddc1..e070bae23683 100644 --- a/contrib/llvm-project/lldb/bindings/lua/lua-wrapper.swig +++ b/contrib/llvm-project/lldb/bindings/lua/lua-wrapper.swig @@ -53,5 +53,40 @@ LLDBSwigLuaBreakpointCallbackFunction return stop; } +// This function is called from Lua::CallWatchpointCallback +SWIGEXPORT llvm::Expected<bool> +LLDBSwigLuaWatchpointCallbackFunction +( + lua_State *L, + lldb::StackFrameSP stop_frame_sp, + lldb::WatchpointSP wp_sp +) +{ + lldb::SBFrame sb_frame(stop_frame_sp); + lldb::SBWatchpoint sb_wp(wp_sp); + int nargs = 2; + + // Push the Lua wrappers + PushSBClass(L, &sb_frame); + PushSBClass(L, &sb_wp); + + // Call into the Lua callback passing 'sb_frame' and 'sb_wp'. + // Expects a boolean return. + if (lua_pcall(L, nargs, 1, 0) != LUA_OK) { + llvm::Error E = llvm::make_error<llvm::StringError>( + llvm::formatv("{0}\n", lua_tostring(L, -1)), + llvm::inconvertibleErrorCode()); + // Pop error message from the stack. + lua_pop(L, 1); + return std::move(E); + } + + // Boolean return from the callback + bool stop = lua_toboolean(L, -1); + lua_pop(L, 1); + + return stop; +} + %} diff --git a/contrib/llvm-project/lldb/bindings/python/python-wrapper.swig b/contrib/llvm-project/lldb/bindings/python/python-wrapper.swig index 443ddfb8dd20..4c39e9c2c776 100644 --- a/contrib/llvm-project/lldb/bindings/python/python-wrapper.swig +++ b/contrib/llvm-project/lldb/bindings/python/python-wrapper.swig @@ -39,6 +39,17 @@ private: // This function is called by lldb_private::ScriptInterpreterPython::BreakpointCallbackFunction(...) // and is used when a script command is attached to a breakpoint for execution. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wreturn-type-c-linkage" + +// Disable warning C4190: 'LLDBSwigPythonBreakpointCallbackFunction' has +// C-linkage specified, but returns UDT 'llvm::Expected<bool>' which is +// incompatible with C +#if _MSC_VER +#pragma warning (push) +#pragma warning (disable : 4190) +#endif + SWIGEXPORT llvm::Expected<bool> LLDBSwigPythonBreakpointCallbackFunction ( @@ -85,6 +96,12 @@ LLDBSwigPythonBreakpointCallbackFunction return result.get().get() != Py_False; } +#if _MSC_VER +#pragma warning (pop) +#endif + +#pragma clang diagnostic pop + // This function is called by lldb_private::ScriptInterpreterPython::WatchpointCallbackFunction(...) // and is used when a script command is attached to a watchpoint for execution. @@ -259,6 +276,72 @@ LLDBSwigPythonCreateCommandObject } SWIGEXPORT void* +LLDBSwigPythonCreateScriptedProcess +( + const char *python_class_name, + const char *session_dictionary_name, + const lldb::TargetSP& target_sp, + lldb_private::StructuredDataImpl *args_impl, + std::string &error_string +) +{ + if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name) + Py_RETURN_NONE; + + + PyErr_Cleaner py_err_cleaner(true); + + auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name); + auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name, dict); + + if (!pfunc.IsAllocated()) { + error_string.append("could not find script class: "); + error_string.append(python_class_name); + return nullptr; + } + + // I do not want the SBTarget to be deallocated when going out of scope + // because python has ownership of it and will manage memory for this + // object by itself + PythonObject target_arg(PyRefType::Owned, SBTypeToSWIGWrapper(new lldb::SBTarget(target_sp))); + + if (!target_arg.IsAllocated()) + Py_RETURN_NONE; + + llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo(); + if (!arg_info) { + llvm::handleAllErrors( + arg_info.takeError(), + [&](PythonException &E) { + error_string.append(E.ReadBacktrace()); + }, + [&](const llvm::ErrorInfoBase &E) { + error_string.append(E.message()); + }); + Py_RETURN_NONE; + } + + PythonObject result = {}; + if (arg_info.get().max_positional_args == 2) { + if (args_impl != nullptr) { + error_string.assign("args passed, but __init__ does not take an args dictionary"); + Py_RETURN_NONE; + } + result = pfunc(target_arg, dict); + } else if (arg_info.get().max_positional_args >= 3) { + PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(new lldb::SBStructuredData(args_impl))); + result = pfunc(target_arg, args_arg, dict); + } else { + error_string.assign("wrong number of arguments in __init__, should be 2 or 3 (not including self)"); + Py_RETURN_NONE; + } + + if (result.IsAllocated()) + return result.release(); + Py_RETURN_NONE; +} + +SWIGEXPORT void* LLDBSwigPythonCreateScriptedThreadPlan ( const char *python_class_name, @@ -786,6 +869,40 @@ LLDBSwigPython_GetValueSynthProviderInstance } SWIGEXPORT void* +LLDBSWIGPython_CastPyObjectToSBData +( + PyObject* data +) +{ + lldb::SBData* sb_ptr = nullptr; + + int valid_cast = SWIG_ConvertPtr(data, (void**)&sb_ptr, SWIGTYPE_p_lldb__SBData, 0); + + if (valid_cast == -1) + return NULL; + + return sb_ptr; +} + + +SWIGEXPORT void* +LLDBSWIGPython_CastPyObjectToSBError +( + PyObject* data +) +{ + lldb::SBError* sb_ptr = nullptr; + + int valid_cast = SWIG_ConvertPtr(data, (void**)&sb_ptr, SWIGTYPE_p_lldb__SBError, 0); + + if (valid_cast == -1) + return NULL; + + return sb_ptr; +} + + +SWIGEXPORT void* LLDBSWIGPython_CastPyObjectToSBValue ( PyObject* data diff --git a/contrib/llvm-project/lldb/docs/design/overview.rst b/contrib/llvm-project/lldb/docs/design/overview.rst index 72eac56d6c3e..1555ea35bfba 100644 --- a/contrib/llvm-project/lldb/docs/design/overview.rst +++ b/contrib/llvm-project/lldb/docs/design/overview.rst @@ -72,7 +72,7 @@ Core ---- The Core source files contain basic functionality that is required in the -debugger as well as the class represeting the debugger it self (Debugger). A +debugger as well as the class representing the debugger itself (Debugger). A wide variety of classes are implemented: - Address (section offset addressing) @@ -172,11 +172,11 @@ Utility This module contains the lowest layers of LLDB. A lot of these classes don't really have anything to do with debugging -- they are just there because the -higher layers of the debugger use these clasess to implement their +higher layers of the debugger use these classes to implement their functionality. Others are data structures used in many other parts of the -debugger (TraceOptions). Most of the functionality in this module could be -useful in an application that is not a debugger; however, providing a general -purpose C++ library is an explicit non-goal of this module. +debugger. Most of the functionality in this module could be useful in an +application that is not a debugger; however, providing a general purpose C++ +library is an explicit non-goal of this module.. This module provides following functionality: diff --git a/contrib/llvm-project/lldb/docs/design/reproducers.rst b/contrib/llvm-project/lldb/docs/design/reproducers.rst index d8ad3dd7866d..99e34d812dee 100644 --- a/contrib/llvm-project/lldb/docs/design/reproducers.rst +++ b/contrib/llvm-project/lldb/docs/design/reproducers.rst @@ -182,13 +182,6 @@ Reproducers are tested in the following ways: unsupported by adding ``UNSUPPORTED: lldb-repro`` to the top of the shell test or adding the ``skipIfReproducer`` decorator for the API tests. -Additional testing is possible: - - - It's possible to unconditionally capture reproducers while running the - entire test suite by setting the ``LLDB_CAPTURE_REPRODUCER`` environment - variable. Assuming no bugs in reproducers, this can also help to reproduce - and investigate test failures. - Knows Issues ------------ diff --git a/contrib/llvm-project/lldb/docs/design/structureddataplugins.md b/contrib/llvm-project/lldb/docs/design/structureddataplugins.md deleted file mode 100644 index 79c410800b2c..000000000000 --- a/contrib/llvm-project/lldb/docs/design/structureddataplugins.md +++ /dev/null @@ -1,442 +0,0 @@ -# Structured Data Plugins - -This document describes an infrastructural feature called Structured Data -plugins. See the DarwinLog documentation for a description of one such plugin -that makes use of this feature. - -StructuredDataPlugin instances have the following characteristics: - -* Each plugin instance is bound to a single Process instance. - -* Each StructuredData feature has a type name that identifies the - feature. For instance, the type name for the DarwinLog feature is - "DarwinLog". This feature type name is used in various places. - -* The process monitor reports the list of supported StructuredData - features advertised by the process monitor. Process goes through the - list of supported feature type names, and asks each known - StructuredDataPlugin if it can handle the feature. The first plugin - that supports the feature is mapped to that Process instance for - that feature. Plugins are only mapped when the process monitor - advertises that a feature is supported. - -* The feature may send asynchronous messages in StructuredData format - to the Process instance. Process instances route the asynchronous - structured data messages to the plugin mapped to that feature type, - if one exists. - -* Plugins can request that the Process instance forward on - configuration data to the process monitor if the plugin needs/wants - to configure the feature. Plugins may call the new Process method - - ```C++ - virtual Error - ConfigureStructuredData(ConstString type_name, - const StructuredData::ObjectSP &config_sp) - ``` - - where `type_name` is the feature name and `config_sp` points to the - configuration structured data, which may be nullptr. - -* Plugins for features present in a process are notified when modules - are loaded into the Process instance via this StructuredDataPlugin - method: - - ```C++ - virtual void - ModulesDidLoad(Process &process, ModuleList &module_list); - ``` - -* Plugins may optionally broadcast their received structured data as - an LLDB process-level event via the following new Process call: - - ```C++ - void - BroadcastStructuredData(const StructuredData::ObjectSP &object_sp, - const lldb::StructuredDataPluginSP &plugin_sp); - ``` - - IDE clients might use this feature to receive information about the - process as it is running to monitor memory usage, CPU usage, and - logging. - - Internally, the event type created is an instance of - EventDataStructuredData. - -* In the case where a plugin chooses to broadcast a received - StructuredData event, the command-line LLDB Debugger instance - listens for them. The Debugger instance then gives the plugin an - opportunity to display info to either the debugger output or error - stream at a time that is safe to write to them. The plugin can - choose to display something appropriate regarding the structured - data that time. - -* Plugins can provide a ProcessLaunchInfo filter method when the - plugin is registered. If such a filter method is provided, then - when a process is about to be launched for debugging, the filter - callback is invoked, given both the launch info and the target. The - plugin may then alter the launch info if needed to better support - the feature of the plugin. - -* The plugin is entirely independent of the type of Process-derived - class that it is working with. The only requirements from the - process monitor are the following feature-agnostic elements: - - * Provide a way to discover features supported by the process - monitor for the current process. - - * Specify the list of supported feature type names to Process. - The process monitor does this by calling the following new - method on Process: - - ```C++ - void - MapSupportedStructuredDataPlugins(const StructuredData::Array - &supported_type_names) - ``` - - The `supported_type_names` specifies an array of string entries, - where each entry specifies the name of a StructuredData feature. - - * Provide a way to forward on configuration data for a feature type - to the process monitor. This is the manner by which LLDB can - configure a feature, perhaps based on settings or commands from - the user. The following virtual method on Process (described - earlier) does the job: - - ```C++ - virtual Error - ConfigureStructuredData(ConstString type_name, - const StructuredData::ObjectSP &config_sp) - ``` - - * Listen for asynchronous structured data packets from the process - monitor, and forward them on to Process via this new Process - member method: - - ```C++ - bool - RouteAsyncStructuredData(const StructuredData::ObjectSP object_sp) - ``` - -* StructuredData producers must send their top-level data as a - Dictionary type, with a key called 'type' specifying a string value, - where the value is equal to the StructuredData feature/type name - previously advertised. Everything else about the content of the - dictionary is entirely up to the feature. - -* StructuredDataPlugin commands show up under `plugin structured-data - plugin-name`. - -* StructuredDataPlugin settings show up under - `plugin.structured-data.{plugin-name}`. - -## StructuredDataDarwinLog feature - -The DarwinLog feature supports logging `os_log`*() and `NSLog`() messages -to the command-line lldb console, as well as making those messages -available to LLDB clients via the event system. Starting with fall -2016 OSes, Apple platforms introduce a new fire-hose, stream-style -logging system where the bulk of the log processing happens on the log -consumer side. This reduces logging impact on the system when there -are no consumers, making it cheaper to include logging at all times. -However, it also increases the work needed on the consumer end when -log messages are desired. - -The debugserver binary has been modified to support collection of -`os_log`*()/`NSLog`() messages, selection of which messages appear in the -stream, and fine-grained filtering of what gets passed on to the LLDB -client. DarwinLog also tracks the activity chain (i.e. `os_activity`() -hierarchy) in effect at the time the log messages were issued. The -user is able to configure a number of aspects related to the -formatting of the log message header fields. - -The DarwinLog support is written in a way which should support the -lldb client side on non-Apple clients talking to an Apple device or -macOS system; hence, the plugin support is built into all LLDB -clients, not just those built on an Apple platform. - -StructuredDataDarwinLog implements the 'DarwinLog' feature type, and -the plugin name for it shows up as `darwin-log`. - -The user interface to the darwin-log support is via the following: - -* `plugin structured-data darwin-log enable` command - - This is the main entry point for enabling the command. It can be - set before launching a process or while the process is running. - If the user wants to squelch seeing info-level or debug-level - messages, which is the default behavior, then the enable command - must be made prior to launching the process; otherwise, the - info-level and debug-level messages will always show up. Also, - there is a similar "echo os_log()/NSLog() messages to target - process stderr" mechanism which is properly disabled when enabling - the DarwinLog support prior to launch. This cannot be squelched - if enabling DarwinLog after launch. - - See the help for this command. There are a number of options - to shrink or expand the number of messages that are processed - on the remote side and sent over to the client, and other - options to control the formatting of messages displayed. - - This command is sticky. Once enabled, it will stay enabled for - future process launches. - -* `plugin structured-data darwin-log disable` command - - Executing this command disables os_log() capture in the currently - running process and signals LLDB to stop attempting to launch - new processes with DarwinLog support enabled. - -* `settings set - plugin.structured-data.darwin-log.enable-on-startup true` - - and - - `settings set - plugin.structured-data.darwin-log.auto-enable-options -- `{options} - - When `enable-on-startup` is set to `true`, then LLDB will automatically - enable DarwinLog on startup of relevant processes. It will use the - content provided in the auto-enable-options settings as the - options to pass to the enable command. - - Note the `--` required after auto-enable-command. That is necessary - for raw commands like settings set. The `--` will not become part - of the options for the enable command. - -### Message flow and related performance considerations - -`os_log`()-style collection is not free. The more data that must be -processed, the slower it will be. There are several knobs available -to the developer to limit how much data goes through the pipe, and how -much data ultimately goes over the wire to the LLDB client. The -user's goal should be to ensure he or she only collects as many log -messages are needed, but no more. - -The flow of data looks like the following: - -1. Data comes into debugserver from the low-level OS facility that - receives log messages. The data that comes through this pipe can - be limited or expanded by the `--debug`, `--info` and - `--all-processes` options of the `plugin structured-data darwin-log - enable` command options. Exclude as many categories as possible - here (also the default). The knobs here are very coarse - for - example, whether to include `os_log_info()`-level or - `os_log_debug()`-level info, or to include callstacks in the log - message event data. - -2. The debugserver process filters the messages that arrive through a - message log filter that may be fully customized by the user. It - works similar to a rules-based packet filter: a set of rules are - matched against the log message, each rule tried in sequential - order. The first rule that matches then either accepts or rejects - the message. If the log message does not match any rule, then the - message gets the no-match (i.e. fall-through) action. The no-match - action defaults to accepting but may be set to reject. - - Filters can be added via the enable command's '`--filter` - {filter-spec}' option. Filters are added in order, and multiple - `--filter` entries can be provided to the enable command. - - Filters take the following form: -``` - {action} {attribute} {op} - - {action} := - accept | - reject - - {attribute} := - category | // The log message category - subsystem | // The log message subsystem - activity | // The child-most activity in force - // at the time the message was logged. - activity-chain | // The complete activity chain, specified - // as {parent-activity}:{child-activity}: - // {grandchild-activity} - message | // The fully expanded message contents. - // Note this one is expensive because it - // requires expanding the message. Avoid - // this if possible, or add it further - // down the filter chain. - - {op} := - match {exact-match-text} | - regex {search-regex} // uses C++ std::regex - // ECMAScript variant. -``` - e.g. - `--filter "accept subsystem match com.example.mycompany.myproduct"` - `--filter "accept subsystem regex com.example.+"` - `--filter "reject category regex spammy-system-[[:digit:]]+"` - -3. Messages that are accepted by the log message filter get sent to - the lldb client, where they are mapped to the - StructuredDataDarwinLog plugin. By default, command-line lldb will - issue a Process-level event containing the log message content, and - will request the plugin to print the message if the plugin is - enabled to do so. - -### Log message display - -Several settings control aspects of displaying log messages in -command-line LLDB. See the `enable` command's help for a description -of these. - - -## StructuredDataDarwinLog feature - -The DarwinLog feature supports logging `os_log`*() and `NSLog`() messages -to the command-line lldb console, as well as making those messages -available to LLDB clients via the event system. Starting with fall -2016 OSes, Apple platforms introduce a new fire-hose, stream-style -logging system where the bulk of the log processing happens on the log -consumer side. This reduces logging impact on the system when there -are no consumers, making it cheaper to include logging at all times. -However, it also increases the work needed on the consumer end when -log messages are desired. - -The debugserver binary has been modified to support collection of -`os_log`*()/`NSLog`() messages, selection of which messages appear in the -stream, and fine-grained filtering of what gets passed on to the LLDB -client. DarwinLog also tracks the activity chain (i.e. `os_activity`() -hierarchy) in effect at the time the log messages were issued. The -user is able to configure a number of aspects related to the -formatting of the log message header fields. - -The DarwinLog support is written in a way which should support the -lldb client side on non-Apple clients talking to an Apple device or -macOS system; hence, the plugin support is built into all LLDB -clients, not just those built on an Apple platform. - -StructuredDataDarwinLog implements the 'DarwinLog' feature type, and -the plugin name for it shows up as `darwin-log`. - -The user interface to the darwin-log support is via the following: - -* `plugin structured-data darwin-log enable` command - - This is the main entry point for enabling the command. It can be - set before launching a process or while the process is running. - If the user wants to squelch seeing info-level or debug-level - messages, which is the default behavior, then the enable command - must be made prior to launching the process; otherwise, the - info-level and debug-level messages will always show up. Also, - there is a similar "echo os_log()/NSLog() messages to target - process stderr" mechanism which is properly disabled when enabling - the DarwinLog support prior to launch. This cannot be squelched - if enabling DarwinLog after launch. - - See the help for this command. There are a number of options - to shrink or expand the number of messages that are processed - on the remote side and sent over to the client, and other - options to control the formatting of messages displayed. - - This command is sticky. Once enabled, it will stay enabled for - future process launches. - -* `plugin structured-data darwin-log disable` command - - Executing this command disables os_log() capture in the currently - running process and signals LLDB to stop attempting to launch - new processes with DarwinLog support enabled. - -* `settings set - plugin.structured-data.darwin-log.enable-on-startup true` - - and - - `settings set - plugin.structured-data.darwin-log.auto-enable-options -- `{options} - - When `enable-on-startup` is set to `true`, then LLDB will automatically - enable DarwinLog on startup of relevant processes. It will use the - content provided in the auto-enable-options settings as the - options to pass to the enable command. - - Note the `--` required after auto-enable-command. That is necessary - for raw commands like settings set. The `--` will not become part - of the options for the enable command. - -### Message flow and related performance considerations - -`os_log`()-style collection is not free. The more data that must be -processed, the slower it will be. There are several knobs available -to the developer to limit how much data goes through the pipe, and how -much data ultimately goes over the wire to the LLDB client. The -user's goal should be to ensure he or she only collects as many log -messages are needed, but no more. - -The flow of data looks like the following: - -1. Data comes into debugserver from the low-level OS facility that - receives log messages. The data that comes through this pipe can - be limited or expanded by the `--debug`, `--info` and - `--all-processes` options of the `plugin structured-data darwin-log - enable` command options. Exclude as many categories as possible - here (also the default). The knobs here are very coarse - for - example, whether to include `os_log_info()`-level or - `os_log_debug()`-level info, or to include callstacks in the log - message event data. - -2. The debugserver process filters the messages that arrive through a - message log filter that may be fully customized by the user. It - works similar to a rules-based packet filter: a set of rules are - matched against the log message, each rule tried in sequential - order. The first rule that matches then either accepts or rejects - the message. If the log message does not match any rule, then the - message gets the no-match (i.e. fall-through) action. The no-match - action defaults to accepting but may be set to reject. - - Filters can be added via the enable command's '`--filter` - {filter-spec}' option. Filters are added in order, and multiple - `--filter` entries can be provided to the enable command. - - Filters take the following form: -``` - {action} {attribute} {op} - - {action} := - accept | - reject - - {attribute} := - category | // The log message category - subsystem | // The log message subsystem - activity | // The child-most activity in force - // at the time the message was logged. - activity-chain | // The complete activity chain, specified - // as {parent-activity}:{child-activity}: - // {grandchild-activity} - message | // The fully expanded message contents. - // Note this one is expensive because it - // requires expanding the message. Avoid - // this if possible, or add it further - // down the filter chain. - - {op} := - match {exact-match-text} | - regex {search-regex} // uses C++ std::regex - // ECMAScript variant. -``` - e.g. - `--filter "accept subsystem match com.example.mycompany.myproduct"` - `--filter "accept subsystem regex com.example.+"` - `--filter "reject category regex spammy-system-[[:digit:]]+"` - -3. Messages that are accepted by the log message filter get sent to - the lldb client, where they are mapped to the - StructuredDataDarwinLog plugin. By default, command-line lldb will - issue a Process-level event containing the log message content, and - will request the plugin to print the message if the plugin is - enabled to do so. - -### Log message display - -Several settings control aspects of displaying log messages in -command-line LLDB. See the `enable` command's help for a description -of these. - - - diff --git a/contrib/llvm-project/lldb/docs/python_api_enums.rst b/contrib/llvm-project/lldb/docs/python_api_enums.rst index b00ac47bd1fa..58100b2aa9a2 100644 --- a/contrib/llvm-project/lldb/docs/python_api_enums.rst +++ b/contrib/llvm-project/lldb/docs/python_api_enums.rst @@ -125,6 +125,9 @@ Miscellaneous constants Enumerators *********** + +.. _State: + State ----- @@ -177,6 +180,9 @@ State as the debugger is concerned while other processes or threads get the chance to run. + +.. _LaunchFlag: + LaunchFlag ---------- @@ -235,6 +241,9 @@ LaunchFlag Don't make the inferior responsible for its own TCC permissions but instead inherit them from its parent. + +.. _RunMode: + RunMode ------- .. py:data:: eOnlyThisThread @@ -242,6 +251,8 @@ RunMode .. py:data:: eOnlyDuringStepping +.. _ByteOrder: + ByteOrder --------- @@ -250,6 +261,9 @@ ByteOrder .. py:data:: eByteOrderPDP .. py:data:: eByteOrderLittle + +.. _Encoding: + Encoding -------- @@ -259,6 +273,9 @@ Encoding .. py:data:: eEncodingIEEE754 .. py:data:: eEncodingVector + +.. _Format: + Format ------ @@ -305,6 +322,9 @@ Format .. py:data:: eFormatVoid .. py:data:: eFormatUnicode8 + +.. _DescriptionLevel: + DescriptionLevel ---------------- @@ -313,6 +333,9 @@ DescriptionLevel .. py:data:: eDescriptionLevelVerbose .. py:data:: eDescriptionLevelInitial + +.. _ScriptLanguage: + ScriptLanguage -------------- @@ -322,6 +345,9 @@ ScriptLanguage .. py:data:: eScriptLanguageUnknown .. py:data:: eScriptLanguageDefault + +.. _RegisterKind: + RegisterKind ------------ @@ -331,6 +357,9 @@ RegisterKind .. py:data:: eRegisterKindProcessPlugin .. py:data:: eRegisterKindLLDB + +.. _StopReason: + StopReason ---------- @@ -342,10 +371,16 @@ StopReason .. py:data:: eStopReasonSignal .. py:data:: eStopReasonException .. py:data:: eStopReasonExec +.. py:data:: eStopReasonFork +.. py:data:: eStopReasonVFork +.. py:data:: eStopReasonVForkDone .. py:data:: eStopReasonPlanComplete .. py:data:: eStopReasonThreadExiting .. py:data:: eStopReasonInstrumentation + +.. _ReturnStatus: + ReturnStatus ------------ @@ -358,6 +393,9 @@ ReturnStatus .. py:data:: eReturnStatusFailed .. py:data:: eReturnStatusQuit + +.. _Expression: + Expression ---------- @@ -374,6 +412,9 @@ The results of expression evaluation. .. py:data:: eExpressionStoppedForDebug .. py:data:: eExpressionThreadVanished + +.. _SearchDepth: + SearchDepth ----------- @@ -385,6 +426,9 @@ SearchDepth .. py:data:: eSearchDepthBlock .. py:data:: eSearchDepthAddress + +.. _ConnectionStatus: + ConnectionStatus ---------------- @@ -416,6 +460,9 @@ ConnectionStatus Interrupted read. + +.. _ErrorType: + ErrorType --------- @@ -441,6 +488,8 @@ ErrorType Standard Win32 error codes. +.. _ValueType: + ValueType --------- @@ -477,8 +526,11 @@ ValueType Thread local storage variable. -InputReader ------------ + +.. _InputReaderGranularity: + +InputReaderGranularity +---------------------- Token size/granularities for Input Readers. @@ -488,6 +540,9 @@ Token size/granularities for Input Readers. .. py:data:: eInputReaderGranularityLine .. py:data:: eInputReaderGranularityAll + +.. _SymbolContextItem: + SymbolContextItem ----------------- @@ -496,7 +551,7 @@ limit the amount of information that gets parsed to only the information that is requested. These bits also can indicate what actually did get resolved during query function calls. -Each definition corresponds to a one of the member variables +Each definition corresponds to one of the member variables in this class, and requests that that item be resolved, or indicates that the member did get resolved. @@ -549,12 +604,18 @@ indicates that the member did get resolved. from being used during frame PC lookups and many other potential address to symbol context lookups. + +.. _Permissions: + Permissions ----------- .. py:data:: ePermissionsWritable .. py:data:: ePermissionsReadable .. py:data:: ePermissionsExecutable + +.. _InputReader: + InputReader ----------- @@ -590,6 +651,9 @@ InputReader Reader was just popped off the stack and is done. + +.. _BreakpointEventType: + BreakpointEventType ------------------- @@ -607,6 +671,9 @@ BreakpointEventType .. py:data:: eBreakpointEventTypeThreadChanged .. py:data:: eBreakpointEventTypeAutoContinueChanged + +.. _WatchpointEventType: + WatchpointEventType ------------------- @@ -621,6 +688,7 @@ WatchpointEventType .. py:data:: eWatchpointEventTypeThreadChanged .. py:data:: eWatchpointEventTypeTypeChanged + .. _LanguageType: LanguageType @@ -666,6 +734,9 @@ LanguageType .. py:data:: eLanguageTypeExtRenderScript .. py:data:: eNumLanguageTypes + +.. _InstrumentationRuntimeType: + InstrumentationRuntimeType -------------------------- @@ -676,6 +747,9 @@ InstrumentationRuntimeType .. py:data:: eInstrumentationRuntimeTypeSwiftRuntimeReporting .. py:data:: eNumInstrumentationRuntimeTypes + +.. _DynamicValueType: + DynamicValueType ---------------- @@ -683,6 +757,9 @@ DynamicValueType .. py:data:: eDynamicCanRunTarget .. py:data:: eDynamicDontRunTarget + +.. _StopShowColumn: + StopShowColumn -------------- @@ -691,6 +768,9 @@ StopShowColumn .. py:data:: eStopShowColumnCaret .. py:data:: eStopShowColumnNone + +.. _AccessType: + AccessType ---------- @@ -700,6 +780,9 @@ AccessType .. py:data:: eAccessProtected .. py:data:: eAccessPackage + +.. _CommandArgumentType: + CommandArgumentType ------------------- @@ -793,6 +876,8 @@ CommandArgumentType .. py:data:: eArgTypeModuleUUID .. py:data:: eArgTypeLastArg +.. _SymbolType: + SymbolType ---------- @@ -827,6 +912,9 @@ SymbolType .. py:data:: eSymbolTypeObjCIVar .. py:data:: eSymbolTypeReExported + +.. _SectionType: + SectionType ----------- @@ -891,6 +979,9 @@ SectionType .. py:data:: eSectionTypeDWARFDebugLocListsDwo .. py:data:: eSectionTypeDWARFDebugTuIndex + +.. _EmulatorInstructionOption: + EmulatorInstructionOption ------------------------- @@ -898,6 +989,9 @@ EmulatorInstructionOption .. py:data:: eEmulateInstructionOptionAutoAdvancePC .. py:data:: eEmulateInstructionOptionIgnoreConditions + +.. _FunctionNameType: + FunctionNameType ---------------- @@ -909,6 +1003,9 @@ FunctionNameType .. py:data:: eFunctionNameTypeSelector .. py:data:: eFunctionNameTypeAny + +.. _BasicType: + BasicType --------- @@ -946,12 +1043,18 @@ BasicType .. py:data:: eBasicTypeNullPtr .. py:data:: eBasicTypeOther + +.. _TraceType: + TraceType --------- .. py:data:: eTraceTypeNone .. py:data:: eTraceTypeProcessorTrace + +.. _StructuredDataType: + StructuredDataType ------------------ @@ -965,6 +1068,9 @@ StructuredDataType .. py:data:: eStructuredDataTypeString .. py:data:: eStructuredDataTypeDictionary + +.. _TypeClass: + TypeClass --------- @@ -990,6 +1096,9 @@ TypeClass .. py:data:: eTypeClassOther .. py:data:: eTypeClassAny + +.. _TemplateArgument: + TemplateArgument ---------------- @@ -1004,6 +1113,9 @@ TemplateArgument .. py:data:: eTemplateArgumentKindNullPtr .. py:data:: eTemplateArgumentKindUncommonValue + +.. _TypeOption: + TypeOption ---------- @@ -1022,6 +1134,10 @@ all of these are applicable to all formatter types. .. py:data:: eTypeOptionHideEmptyAggregates .. py:data:: eTypeOptionFrontEndWantsDereference + + +.. _FrameCompare: + FrameCompare ------------ @@ -1053,6 +1169,9 @@ A to frame B the following cases arise: .. py:data:: eFrameCompareYounger .. py:data:: eFrameCompareOlder + +.. _FilePermissions: + FilePermissions --------------- @@ -1083,12 +1202,18 @@ FilePermissions .. py:data:: eFilePermissionsFileDefault = eFilePermissionsUserRW, .. py:data:: eFilePermissionsDirectoryDefault + +.. _QueueItem: + QueueItem --------- .. py:data:: eQueueItemKindUnknown .. py:data:: eQueueItemKindFunction .. py:data:: eQueueItemKindBlock + +.. _QueueKind: + QueueKind --------- @@ -1100,6 +1225,9 @@ multiple threads). .. py:data:: eQueueKindSerial .. py:data:: eQueueKindConcurrent + +.. _ExpressionEvaluationPhase: + ExpressionEvaluationPhase ------------------------- @@ -1112,6 +1240,9 @@ expression evaluation at the various points in its lifecycle. .. py:data:: eExpressionEvaluationExecution .. py:data:: eExpressionEvaluationComplete + +.. _WatchpointKind: + WatchpointKind -------------- @@ -1121,6 +1252,9 @@ Indicates what types of events cause the watchpoint to fire. Used by Native .. py:data:: eWatchpointKindWrite .. py:data:: eWatchpointKindRead + +.. _GdbSignal: + GdbSignal --------- @@ -1131,6 +1265,8 @@ GdbSignal .. py:data:: eGdbSignalSoftware .. py:data:: eGdbSignalBreakpoint +.. _PathType: + PathType -------- @@ -1176,6 +1312,9 @@ relative to LLDB or are in known locations. Find path to Clang builtin headers. + +.. _MemberFunctionKind: + MemberFunctionKind ------------------ @@ -1196,6 +1335,9 @@ MemberFunctionKind A function that applies to a type rather than any instance, + +.. _TypeFlags: + TypeFlags --------- @@ -1212,6 +1354,9 @@ TypeFlags .. py:data:: eTypeIsComplex .. py:data:: eTypeInstanceIsPointer + +.. _CommandFlags: + CommandFlags --------------- @@ -1225,6 +1370,9 @@ CommandFlags .. py:data:: eCommandProcessMustBePaused .. py:data:: eCommandProcessMustBeTraced + +.. _TypeSummary: + TypeSummary ----------- @@ -1233,6 +1381,9 @@ Whether a summary should cap how much data it returns to users or not. .. py:data:: eTypeSummaryCapped .. py:data:: eTypeSummaryUncapped + +.. _CommandInterpreterResult: + CommandInterpreterResult ------------------------ diff --git a/contrib/llvm-project/lldb/include/lldb/API/LLDB.h b/contrib/llvm-project/lldb/include/lldb/API/LLDB.h index f7390cfabf01..eacbbeafcf1c 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/LLDB.h +++ b/contrib/llvm-project/lldb/include/lldb/API/LLDB.h @@ -65,7 +65,6 @@ #include "lldb/API/SBThreadCollection.h" #include "lldb/API/SBThreadPlan.h" #include "lldb/API/SBTrace.h" -#include "lldb/API/SBTraceOptions.h" #include "lldb/API/SBType.h" #include "lldb/API/SBTypeCategory.h" #include "lldb/API/SBTypeEnumMember.h" diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBBlock.h b/contrib/llvm-project/lldb/include/lldb/API/SBBlock.h index be1ae18e9db5..2570099f7652 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBBlock.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBBlock.h @@ -87,7 +87,7 @@ private: void AppendVariables(bool can_create, bool get_parent_variables, lldb_private::VariableList *var_list); - lldb_private::Block *m_opaque_ptr; + lldb_private::Block *m_opaque_ptr = nullptr; }; } // namespace lldb diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBBroadcaster.h b/contrib/llvm-project/lldb/include/lldb/API/SBBroadcaster.h index 69a516a8bfb1..046473d4223b 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBBroadcaster.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBBroadcaster.h @@ -63,6 +63,7 @@ public: protected: friend class SBCommandInterpreter; friend class SBCommunication; + friend class SBDebugger; friend class SBEvent; friend class SBListener; friend class SBProcess; @@ -76,7 +77,7 @@ protected: private: lldb::BroadcasterSP m_opaque_sp; - lldb_private::Broadcaster *m_opaque_ptr; + lldb_private::Broadcaster *m_opaque_ptr = nullptr; }; } // namespace lldb diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBCommandInterpreterRunOptions.h b/contrib/llvm-project/lldb/include/lldb/API/SBCommandInterpreterRunOptions.h index 3c00513faaa7..efaacd39eb0f 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBCommandInterpreterRunOptions.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBCommandInterpreterRunOptions.h @@ -56,6 +56,10 @@ public: void SetPrintResults(bool); + bool GetPrintErrors() const; + + void SetPrintErrors(bool); + bool GetAddToHistory() const; void SetAddToHistory(bool); diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBCommandReturnObject.h b/contrib/llvm-project/lldb/include/lldb/API/SBCommandReturnObject.h index 4ee296eb1797..5738c911ae12 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBCommandReturnObject.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBCommandReturnObject.h @@ -9,7 +9,7 @@ #ifndef LLDB_API_SBCOMMANDRETURNOBJECT_H #define LLDB_API_SBCOMMANDRETURNOBJECT_H -#include <stdio.h> +#include <cstdio> #include <memory> @@ -105,9 +105,6 @@ public: void SetError(const char *error_cstr); - // ref() is internal for LLDB only. - lldb_private::CommandReturnObject &ref() const; - protected: friend class SBCommandInterpreter; friend class SBOptions; @@ -119,6 +116,8 @@ protected: lldb_private::CommandReturnObject &operator*() const; private: + lldb_private::CommandReturnObject &ref() const; + std::unique_ptr<lldb_private::SBCommandReturnObjectImpl> m_opaque_up; }; diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBCommunication.h b/contrib/llvm-project/lldb/include/lldb/API/SBCommunication.h index 84c341c0dfef..e407d859d885 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBCommunication.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBCommunication.h @@ -75,8 +75,8 @@ private: SBCommunication(const SBCommunication &) = delete; const SBCommunication &operator=(const SBCommunication &) = delete; - lldb_private::Communication *m_opaque; - bool m_opaque_owned; + lldb_private::Communication *m_opaque = nullptr; + bool m_opaque_owned = false; }; } // namespace lldb diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBCompileUnit.h b/contrib/llvm-project/lldb/include/lldb/API/SBCompileUnit.h index 0c05ef44e31c..d965b9d966b9 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBCompileUnit.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBCompileUnit.h @@ -87,7 +87,7 @@ private: void reset(lldb_private::CompileUnit *lldb_object_ptr); - lldb_private::CompileUnit *m_opaque_ptr; + lldb_private::CompileUnit *m_opaque_ptr = nullptr; }; } // namespace lldb diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBData.h b/contrib/llvm-project/lldb/include/lldb/API/SBData.h index 95c8086d5d47..85c8110e181c 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBData.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBData.h @@ -11,6 +11,10 @@ #include "lldb/API/SBDefines.h" +namespace lldb_private { +class ScriptInterpreter; +} // namespace lldb_private + namespace lldb { class LLDB_API SBData { @@ -147,6 +151,8 @@ private: friend class SBTarget; friend class SBValue; + friend class lldb_private::ScriptInterpreter; + lldb::DataExtractorSP m_opaque_sp; }; diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBDebugger.h b/contrib/llvm-project/lldb/include/lldb/API/SBDebugger.h index b3bfa230139c..ef62141f579d 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBDebugger.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBDebugger.h @@ -9,7 +9,7 @@ #ifndef LLDB_API_SBDEBUGGER_H #define LLDB_API_SBDEBUGGER_H -#include <stdio.h> +#include <cstdio> #include "lldb/API/SBDefines.h" #include "lldb/API/SBPlatform.h" @@ -33,6 +33,8 @@ public: class LLDB_API SBDebugger { public: + FLAGS_ANONYMOUS_ENUM(){eBroadcastBitProgress = (1 << 0)}; + SBDebugger(); SBDebugger(const lldb::SBDebugger &rhs); @@ -41,6 +43,42 @@ public: ~SBDebugger(); + static const char *GetBroadcasterClass(); + + lldb::SBBroadcaster GetBroadcaster(); + + /// Get progress data from a SBEvent whose type is eBroadcastBitProgress. + /// + /// \param [in] event + /// The event to extract the progress information from. + /// + /// \param [out] progress_id + /// The unique integer identifier for the progress to report. + /// + /// \param [out] completed + /// The amount of work completed. If \a completed is zero, then this event + /// is a progress started event. If \a completed is equal to \a total, then + /// this event is a progress end event. Otherwise completed indicates the + /// current progress update. + /// + /// \param [out] total + /// The total amount of work units that need to be completed. If this value + /// is UINT64_MAX, then an indeterminate progress indicator should be + /// displayed. + /// + /// \param [out] is_debugger_specific + /// Set to true if this progress is specific to this debugger only. Many + /// progress events are not specific to a debugger instance, like any + /// progress events for loading information in modules since LLDB has a + /// global module cache that all debuggers use. + /// + /// \return The message for the progress. If the returned value is NULL, then + /// \a event was not a eBroadcastBitProgress event. + static const char *GetProgressFromEvent(const lldb::SBEvent &event, + uint64_t &progress_id, + uint64_t &completed, uint64_t &total, + bool &is_debugger_specific); + lldb::SBDebugger &operator=(const lldb::SBDebugger &rhs); static void Initialize(); diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBDefines.h b/contrib/llvm-project/lldb/include/lldb/API/SBDefines.h index a5b639c6dc73..3ab10ad8e061 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBDefines.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBDefines.h @@ -76,7 +76,6 @@ class LLDB_API SBThread; class LLDB_API SBThreadCollection; class LLDB_API SBThreadPlan; class LLDB_API SBTrace; -class LLDB_API SBTraceOptions; class LLDB_API SBType; class LLDB_API SBTypeCategory; class LLDB_API SBTypeEnumMember; diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBError.h b/contrib/llvm-project/lldb/include/lldb/API/SBError.h index e1960ef9a983..f8289e2fcbb3 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBError.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBError.h @@ -11,6 +11,10 @@ #include "lldb/API/SBDefines.h" +namespace lldb_private { +class ScriptInterpreter; +} // namespace lldb_private + namespace lldb { class LLDB_API SBError { @@ -72,6 +76,8 @@ protected: friend class SBWatchpoint; friend class SBFile; + friend class lldb_private::ScriptInterpreter; + lldb_private::Status *get(); lldb_private::Status *operator->(); diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBEvent.h b/contrib/llvm-project/lldb/include/lldb/API/SBEvent.h index a7975bf9abae..2ce1b60372b7 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBEvent.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBEvent.h @@ -11,7 +11,7 @@ #include "lldb/API/SBDefines.h" -#include <stdio.h> +#include <cstdio> #include <vector> namespace lldb { @@ -79,7 +79,7 @@ protected: private: mutable lldb::EventSP m_event_sp; - mutable lldb_private::Event *m_opaque_ptr; + mutable lldb_private::Event *m_opaque_ptr = nullptr; }; } // namespace lldb diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBExecutionContext.h b/contrib/llvm-project/lldb/include/lldb/API/SBExecutionContext.h index d8447aeb1a2f..06ece6fbc0fa 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBExecutionContext.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBExecutionContext.h @@ -12,7 +12,7 @@ #include "lldb/API/SBDefines.h" -#include <stdio.h> +#include <cstdio> #include <vector> namespace lldb { diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBFunction.h b/contrib/llvm-project/lldb/include/lldb/API/SBFunction.h index bd643a62206f..71b372a818e4 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBFunction.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBFunction.h @@ -74,7 +74,7 @@ private: SBFunction(lldb_private::Function *lldb_object_ptr); - lldb_private::Function *m_opaque_ptr; + lldb_private::Function *m_opaque_ptr = nullptr; }; } // namespace lldb diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBInstruction.h b/contrib/llvm-project/lldb/include/lldb/API/SBInstruction.h index 7d07e168cf03..b9d781550b5d 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBInstruction.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBInstruction.h @@ -12,7 +12,7 @@ #include "lldb/API/SBData.h" #include "lldb/API/SBDefines.h" -#include <stdio.h> +#include <cstdio> // There's a lot to be fixed here, but need to wait for underlying insn // implementation to be revised & settle down first. diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBInstructionList.h b/contrib/llvm-project/lldb/include/lldb/API/SBInstructionList.h index ae8988004e26..b9c6c66ebd85 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBInstructionList.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBInstructionList.h @@ -11,7 +11,7 @@ #include "lldb/API/SBDefines.h" -#include <stdio.h> +#include <cstdio> namespace lldb { diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBLaunchInfo.h b/contrib/llvm-project/lldb/include/lldb/API/SBLaunchInfo.h index 04ebb5707688..eb4f4a65833c 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBLaunchInfo.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBLaunchInfo.h @@ -171,6 +171,14 @@ public: void SetDetachOnError(bool enable); + const char *GetScriptedProcessClassName() const; + + void SetScriptedProcessClassName(const char *class_name); + + lldb::SBStructuredData GetScriptedProcessDictionary() const; + + void SetScriptedProcessDictionary(lldb::SBStructuredData dict); + protected: friend class SBPlatform; friend class SBTarget; diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBListener.h b/contrib/llvm-project/lldb/include/lldb/API/SBListener.h index 2144e7956b13..eaa8b59d0c49 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBListener.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBListener.h @@ -100,7 +100,7 @@ private: void reset(lldb::ListenerSP listener_sp); lldb::ListenerSP m_opaque_sp; - lldb_private::Listener *m_unused_ptr; + lldb_private::Listener *m_unused_ptr = nullptr; }; } // namespace lldb diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBMemoryRegionInfo.h b/contrib/llvm-project/lldb/include/lldb/API/SBMemoryRegionInfo.h index d82c70606559..122226b9a0c5 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBMemoryRegionInfo.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBMemoryRegionInfo.h @@ -73,6 +73,40 @@ public: /// region. If no name can be determined the returns nullptr. const char *GetName(); + /// Returns whether this memory region has a list of memory pages + /// that have been modified -- that are dirty. + /// + /// \return + /// True if the dirty page list is available. + bool HasDirtyMemoryPageList(); + + /// Returns the number of modified pages -- dirty pages -- in this + /// memory region. + /// + /// \return + /// The number of dirty page entries will be returned. If + /// there are no dirty pages in this memory region, 0 will + /// be returned. 0 will also be returned if the dirty page + /// list is not available for this memory region -- you must + /// use HasDirtyMemoryPageList() to check for that. + uint32_t GetNumDirtyPages(); + + /// Returns the address of a memory page that has been modified in + /// this region. + /// + /// \return + /// Returns the address for his dirty page in the list. + /// If this memory region does not have a dirty page list, + /// LLDB_INVALID_ADDRESS is returned. + addr_t GetDirtyPageAddressAtIndex(uint32_t idx); + + /// Returns the size of a memory page in this region. + /// + /// \return + /// Returns the size of the memory pages in this region, + /// or 0 if this information is unavailable. + int GetPageSize(); + bool operator==(const lldb::SBMemoryRegionInfo &rhs) const; bool operator!=(const lldb::SBMemoryRegionInfo &rhs) const; diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBProcess.h b/contrib/llvm-project/lldb/include/lldb/API/SBProcess.h index a90ec2a29a39..73a8d918f4d6 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBProcess.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBProcess.h @@ -14,7 +14,7 @@ #include "lldb/API/SBProcessInfo.h" #include "lldb/API/SBQueue.h" #include "lldb/API/SBTarget.h" -#include <stdio.h> +#include <cstdio> namespace lldb { @@ -224,31 +224,6 @@ public: SBStructuredData GetExtendedCrashInformation(); - /// Start Tracing with the given SBTraceOptions. - /// - /// \param[in] options - /// Class containing trace options like trace buffer size, meta - /// data buffer size, TraceType and any custom parameters - /// {formatted as a JSON Dictionary}. In case of errors in - /// formatting, an error would be reported. - /// It must be noted that tracing options such as buffer sizes - /// or other custom parameters passed maybe invalid for some - /// trace technologies. In such cases the trace implementations - /// could choose to either throw an error or could round off to - /// the nearest valid options to start tracing if the passed - /// value is not supported. To obtain the actual used trace - /// options please use the GetTraceConfig API. For the custom - /// parameters, only the parameters recognized by the target - /// would be used and others would be ignored. - /// - /// \param[out] error - /// An error explaining what went wrong. - /// - /// \return - /// A SBTrace instance, which should be used - /// to get the trace data or other trace related operations. - lldb::SBTrace StartTrace(SBTraceOptions &options, lldb::SBError &error); - uint32_t GetNumSupportedHardwareWatchpoints(lldb::SBError &error) const; /// Load a shared library into this process. @@ -301,13 +276,13 @@ public: /// paths till you find a matching library. /// /// \param[in] image_spec - /// The name of the shared library that you want to load. + /// The name of the shared library that you want to load. /// If image_spec is a relative path, the relative path will be /// appended to the search paths. /// If the image_spec is an absolute path, just the basename is used. /// /// \param[in] paths - /// A list of paths to search for the library whose basename is + /// A list of paths to search for the library whose basename is /// local_spec. /// /// \param[out] loaded_path @@ -325,7 +300,7 @@ public: /// library can't be opened. uint32_t LoadImageUsingPaths(const lldb::SBFileSpec &image_spec, SBStringList &paths, - lldb::SBFileSpec &loaded_path, + lldb::SBFileSpec &loaded_path, lldb::SBError &error); lldb::SBError UnloadImage(uint32_t image_token); @@ -395,6 +370,45 @@ public: /// valid. lldb::SBProcessInfo GetProcessInfo(); + /// Allocate memory within the process. + /// + /// This function will allocate memory in the process's address space. + /// + /// \param[in] size + /// The size of the allocation requested. + /// + /// \param[in] permissions + /// Or together any of the lldb::Permissions bits. The + /// permissions on a given memory allocation can't be changed + /// after allocation. Note that a block that isn't set writable + /// can still be written from lldb, just not by the process + /// itself. + /// + /// \param[out] error + /// An error object that gets filled in with any errors that + /// might occur when trying allocate. + /// + /// \return + /// The address of the allocated buffer in the process, or + /// LLDB_INVALID_ADDRESS if the allocation failed. + lldb::addr_t AllocateMemory(size_t size, uint32_t permissions, + lldb::SBError &error); + + /// Deallocate memory in the process. + /// + /// This function will deallocate memory in the process's address + /// space that was allocated with AllocateMemory. + /// + /// \param[in] ptr + /// A return value from AllocateMemory, pointing to the memory you + /// want to deallocate. + /// + /// \return + /// An error object describes any errors that occurred while + /// deallocating. + /// + lldb::SBError DeallocateMemory(lldb::addr_t ptr); + protected: friend class SBAddress; friend class SBBreakpoint; diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBProcessInfo.h b/contrib/llvm-project/lldb/include/lldb/API/SBProcessInfo.h index 0cc5f6a2f9f6..36fae9e842a6 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBProcessInfo.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBProcessInfo.h @@ -50,6 +50,9 @@ public: lldb::pid_t GetParentProcessID(); + /// Return the target triple (arch-vendor-os) for the described process. + const char *GetTriple(); + private: friend class SBProcess; diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBSourceManager.h b/contrib/llvm-project/lldb/include/lldb/API/SBSourceManager.h index c8302dbda3c0..e95cfa66e1c5 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBSourceManager.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBSourceManager.h @@ -11,7 +11,7 @@ #include "lldb/API/SBDefines.h" -#include <stdio.h> +#include <cstdio> namespace lldb { diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBStream.h b/contrib/llvm-project/lldb/include/lldb/API/SBStream.h index f44b87bb4c98..291109cbe93c 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBStream.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBStream.h @@ -9,7 +9,7 @@ #ifndef LLDB_API_SBSTREAM_H #define LLDB_API_SBSTREAM_H -#include <stdio.h> +#include <cstdio> #include "lldb/API/SBDefines.h" @@ -72,6 +72,7 @@ protected: friend class SBFunction; friend class SBInstruction; friend class SBInstructionList; + friend class SBLaunchInfo; friend class SBLineEntry; friend class SBMemoryRegionInfo; friend class SBModule; @@ -104,7 +105,7 @@ private: SBStream(const SBStream &) = delete; const SBStream &operator=(const SBStream &) = delete; std::unique_ptr<lldb_private::Stream> m_opaque_up; - bool m_is_file; + bool m_is_file = false; }; } // namespace lldb diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBStructuredData.h b/contrib/llvm-project/lldb/include/lldb/API/SBStructuredData.h index 44a86bdabe25..07075abbf1d0 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBStructuredData.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBStructuredData.h @@ -21,7 +21,7 @@ public: SBStructuredData(const lldb::SBStructuredData &rhs); SBStructuredData(const lldb::EventSP &event_sp); - + SBStructuredData(lldb_private::StructuredDataImpl *impl); ~SBStructuredData(); @@ -34,6 +34,8 @@ public: lldb::SBError SetFromJSON(lldb::SBStream &stream); + lldb::SBError SetFromJSON(const char *json); + void Clear(); lldb::SBError GetAsJSON(lldb::SBStream &stream) const; @@ -42,7 +44,7 @@ public: /// Return the type of data in this data structure lldb::StructuredDataType GetType() const; - + /// Return the size (i.e. number of elements) in this data structure /// if it is an array or dictionary type. For other types, 0 will be // returned. @@ -51,7 +53,7 @@ public: /// Fill keys with the keys in this object and return true if this data /// structure is a dictionary. Returns false otherwise. bool GetKeys(lldb::SBStringList &keys) const; - + /// Return the value corresponding to a key if this data structure /// is a dictionary type. lldb::SBStructuredData GetValueForKey(const char *key) const; @@ -88,7 +90,7 @@ public: size_t GetStringValue(char *dst, size_t dst_len) const; protected: - friend class SBTraceOptions; + friend class SBLaunchInfo; friend class SBDebugger; friend class SBTarget; friend class SBProcess; @@ -97,6 +99,7 @@ protected: friend class SBBreakpoint; friend class SBBreakpointLocation; friend class SBBreakpointName; + friend class SBTrace; StructuredDataImplUP m_impl_up; }; diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBSymbol.h b/contrib/llvm-project/lldb/include/lldb/API/SBSymbol.h index 66f73c82a73a..5935ccfed024 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBSymbol.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBSymbol.h @@ -78,7 +78,7 @@ private: void SetSymbol(lldb_private::Symbol *lldb_object_ptr); - lldb_private::Symbol *m_opaque_ptr; + lldb_private::Symbol *m_opaque_ptr = nullptr; }; } // namespace lldb diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBTarget.h b/contrib/llvm-project/lldb/include/lldb/API/SBTarget.h index 30f4005dfc0f..5a6908f040b1 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBTarget.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBTarget.h @@ -643,7 +643,7 @@ public: lldb::SBBreakpoint BreakpointCreateByAddress(addr_t address); lldb::SBBreakpoint BreakpointCreateBySBAddress(SBAddress &address); - + /// Create a breakpoint using a scripted resolver. /// /// \param[in] class_name @@ -651,16 +651,16 @@ public: /// /// \param[in] extra_args /// This is an SBStructuredData object that will get passed to the - /// constructor of the class in class_name. You can use this to - /// reuse the same class, parametrizing with entries from this + /// constructor of the class in class_name. You can use this to + /// reuse the same class, parametrizing with entries from this /// dictionary. /// /// \param module_list - /// If this is non-empty, this will be used as the module filter in the + /// If this is non-empty, this will be used as the module filter in the /// SearchFilter created for this breakpoint. /// /// \param file_list - /// If this is non-empty, this will be used as the comp unit filter in the + /// If this is non-empty, this will be used as the comp unit filter in the /// SearchFilter created for this breakpoint. /// /// \return @@ -834,10 +834,27 @@ public: lldb::addr_t GetStackRedZoneSize(); + bool IsLoaded(const lldb::SBModule &module) const; + lldb::SBLaunchInfo GetLaunchInfo() const; void SetLaunchInfo(const lldb::SBLaunchInfo &launch_info); + /// Get a \a SBTrace object the can manage the processor trace information of + /// this target. + /// + /// \return + /// The trace object. The returned SBTrace object might not be valid, so it + /// should be checked with a call to "bool SBTrace::IsValid()". + lldb::SBTrace GetTrace(); + + /// Create a \a Trace object for the current target using the using the + /// default supported tracing technology for this process. + /// + /// \param[out] error + /// An error if a Trace already exists or the trace couldn't be created. + lldb::SBTrace CreateTrace(SBError &error); + protected: friend class SBAddress; friend class SBBlock; diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBThread.h b/contrib/llvm-project/lldb/include/lldb/API/SBThread.h index 894120c6d986..ac1b8407a220 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBThread.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBThread.h @@ -11,7 +11,7 @@ #include "lldb/API/SBDefines.h" -#include <stdio.h> +#include <cstdio> namespace lldb { @@ -66,6 +66,9 @@ public: /// eStopReasonSignal 1 unix signal number /// eStopReasonException N exception data /// eStopReasonExec 0 + /// eStopReasonFork 1 pid of the child process + /// eStopReasonVFork 1 pid of the child process + /// eStopReasonVForkDone 0 /// eStopReasonPlanComplete 0 uint64_t GetStopReasonDataAtIndex(uint32_t idx); @@ -217,6 +220,7 @@ private: friend class lldb_private::QueueImpl; friend class SBQueueItem; friend class SBThreadPlan; + friend class SBTrace; void SetThread(const lldb::ThreadSP &lldb_object_sp); diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBThreadPlan.h b/contrib/llvm-project/lldb/include/lldb/API/SBThreadPlan.h index 0dc48437a668..0d166b35ae4a 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBThreadPlan.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBThreadPlan.h @@ -11,14 +11,12 @@ #include "lldb/API/SBDefines.h" -#include <stdio.h> +#include <cstdio> namespace lldb { class LLDB_API SBThreadPlan { - friend class lldb_private::ThreadPlan; - public: SBThreadPlan(); @@ -60,6 +58,9 @@ public: /// eStopReasonSignal 1 unix signal number /// eStopReasonException N exception data /// eStopReasonExec 0 + /// eStopReasonFork 1 pid of the child process + /// eStopReasonVFork 1 pid of the child process + /// eStopReasonVForkDone 0 /// eStopReasonPlanComplete 0 uint64_t GetStopReasonDataAtIndex(uint32_t idx); diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBTrace.h b/contrib/llvm-project/lldb/include/lldb/API/SBTrace.h index 053abaeada19..1685caaf4efa 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBTrace.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBTrace.h @@ -18,97 +18,88 @@ namespace lldb { class LLDB_API SBTrace { public: + /// Default constructor for an invalid Trace object. SBTrace(); - /// Obtain the trace data as raw bytes. + + SBTrace(const lldb::TraceSP &trace_sp); + + /// \return + /// A description of the parameters to use for the \a SBTrace::Start + /// method, or \b null if the object is invalid. + const char *GetStartConfigurationHelp(); + + /// Start tracing all current and future threads in a live process using a + /// provided configuration. This is referred as "process tracing" in the + /// documentation. /// - /// \param[out] error - /// An error explaining what went wrong. + /// This is equivalent to the command "process trace start". /// - /// \param[in] buf - /// Buffer to write the trace data to. + /// This operation fails if it is invoked twice in a row without + /// first stopping the process trace with \a SBTrace::Stop(). /// - /// \param[in] size - /// The size of the buffer used to read the data. This is - /// also the size of the data intended to read. It is also - /// possible to partially read the trace data for some trace - /// technologies by specifying a smaller buffer. + /// If a thread is already being traced explicitly, e.g. with \a + /// SBTrace::Start(const SBThread &thread, const SBStructuredData + /// &configuration), it is left unaffected by this operation. /// - /// \param[in] offset - /// The start offset to begin reading the trace data. + /// \param[in] configuration + /// Dictionary object with custom fields for the corresponding trace + /// technology. /// - /// \param[in] thread_id - /// Tracing could be started for the complete process or a - /// single thread, in the first case the traceid obtained would - /// map to all the threads existing within the process and the - /// ones spawning later. The thread_id parameter can be used in - /// such a scenario to select the trace data for a specific - /// thread. + /// Full details for the trace start parameters that can be set can be + /// retrieved by calling \a SBTrace::GetStartConfigurationHelp(). /// /// \return - /// The size of the trace data effectively read by the API call. - size_t GetTraceData(SBError &error, void *buf, size_t size, size_t offset = 0, - lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID); - - /// Obtain any meta data as raw bytes for the tracing instance. - /// The input parameter definition is similar to the previous - /// function. - size_t GetMetaData(SBError &error, void *buf, size_t size, size_t offset = 0, - lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID); + /// An error explaining any failures. + SBError Start(const SBStructuredData &configuration); - /// Stop the tracing instance. Stopping the trace will also - /// lead to deletion of any gathered trace data. - /// - /// \param[out] error - /// An error explaining what went wrong. - /// - /// \param[in] thread_id - /// The trace id could map to a tracing instance for a thread - /// or could also map to a group of threads being traced with - /// the same trace options. A thread_id is normally optional - /// except in the case of tracing a complete process and tracing - /// needs to switched off on a particular thread. - /// A situation could occur where initially a thread (lets say - /// thread A) is being individually traced with a particular - /// trace id and then tracing is started on the complete - /// process, in this case thread A will continue without any - /// change. All newly spawned threads would be traced with the - /// trace id of the process. - /// Now if the StopTrace API is called for the whole process, - /// thread A will not be stopped and must be stopped separately. - void StopTrace(SBError &error, - lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID); + /// Start tracing a specific thread in a live process using a provided + /// configuration. This is referred as "thread tracing" in the documentation. + /// + /// This is equivalent to the command "thread trace start". + /// + /// If the thread is already being traced by a "process tracing" operation, + /// e.g. with \a SBTrace::Start(const SBStructuredData &configuration), this + /// operation fails. + /// + /// \param[in] configuration + /// Dictionary object with custom fields for the corresponding trace + /// technology. + /// + /// Full details for the trace start parameters that can be set can be + /// retrieved by calling \a SBTrace::GetStartConfigurationHelp(). + /// + /// \return + /// An error explaining any failures. + SBError Start(const SBThread &thread, const SBStructuredData &configuration); - /// Get the trace configuration being used for the trace instance. - /// The threadid in the SBTraceOptions needs to be set when the - /// configuration used by a specific thread is being requested. + /// Stop tracing all threads in a live process. /// - /// \param[out] options - /// The trace options actually used by the trace instance - /// would be filled by the API. + /// If a "process tracing" operation is active, e.g. \a SBTrace::Start(const + /// SBStructuredData &configuration), this effectively prevents future threads + /// from being traced. /// - /// \param[out] error - /// An error explaining what went wrong. - void GetTraceConfig(SBTraceOptions &options, SBError &error); + /// This is equivalent to the command "process trace stop". + /// + /// \return + /// An error explaining any failures. + SBError Stop(); - lldb::user_id_t GetTraceUID(); + /// Stop tracing a specific thread in a live process regardless of whether the + /// thread was traced explicitly or as part of a "process tracing" operation. + /// + /// This is equivalent to the command "thread trace stop". + /// + /// \return + /// An error explaining any failures. + SBError Stop(const SBThread &thread); explicit operator bool() const; bool IsValid(); protected: - typedef std::shared_ptr<TraceImpl> TraceImplSP; - - friend class SBProcess; - - void SetTraceUID(lldb::user_id_t uid); - - TraceImplSP m_trace_impl_sp; - - lldb::ProcessSP GetSP() const; - - void SetSP(const ProcessSP &process_sp); - + lldb::TraceSP m_opaque_sp; + /// deprecated lldb::ProcessWP m_opaque_wp; }; } // namespace lldb diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBTraceOptions.h b/contrib/llvm-project/lldb/include/lldb/API/SBTraceOptions.h deleted file mode 100644 index 22d71fbd3828..000000000000 --- a/contrib/llvm-project/lldb/include/lldb/API/SBTraceOptions.h +++ /dev/null @@ -1,59 +0,0 @@ -//===-- SBTraceOptions ------------------------------------------*- 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_API_SBTRACEOPTIONS_H -#define LLDB_API_SBTRACEOPTIONS_H - -#include "lldb/API/SBDefines.h" - -namespace lldb { - -class LLDB_API SBTraceOptions { -public: - SBTraceOptions(); - - lldb::TraceType getType() const; - - uint64_t getTraceBufferSize() const; - - /// The trace parameters consist of any custom parameters - /// apart from the generic parameters such as - /// TraceType, trace_buffer_size and meta_data_buffer_size. - /// The returned parameters would be formatted as a JSON Dictionary. - lldb::SBStructuredData getTraceParams(lldb::SBError &error); - - uint64_t getMetaDataBufferSize() const; - - /// SBStructuredData is meant to hold any custom parameters - /// apart from meta buffer size and trace size. They should - /// be formatted as a JSON Dictionary. - void setTraceParams(lldb::SBStructuredData ¶ms); - - void setType(lldb::TraceType type); - - void setTraceBufferSize(uint64_t size); - - void setMetaDataBufferSize(uint64_t size); - - void setThreadID(lldb::tid_t thread_id); - - lldb::tid_t getThreadID(); - - explicit operator bool() const; - - bool IsValid(); - -protected: - friend class SBProcess; - friend class SBTrace; - - lldb::TraceOptionsSP m_traceoptions_sp; -}; -} - -#endif // LLDB_API_SBTRACEOPTIONS_H diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/Breakpoint.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/Breakpoint.h index ddb70b719d6e..f2e2a0d22784 100644 --- a/contrib/llvm-project/lldb/include/lldb/Breakpoint/Breakpoint.h +++ b/contrib/llvm-project/lldb/include/lldb/Breakpoint/Breakpoint.h @@ -481,16 +481,16 @@ public: /// Meant to be used by the BreakpointLocation class. /// /// \return - /// A pointer to this breakpoint's BreakpointOptions. - BreakpointOptions *GetOptions(); + /// A reference to this breakpoint's BreakpointOptions. + BreakpointOptions &GetOptions(); /// Returns the BreakpointOptions structure set at the breakpoint level. /// /// Meant to be used by the BreakpointLocation class. /// /// \return - /// A pointer to this breakpoint's BreakpointOptions. - const BreakpointOptions *GetOptions() const; + /// A reference to this breakpoint's BreakpointOptions. + const BreakpointOptions &GetOptions() const; /// Invoke the callback action when the breakpoint is hit. /// @@ -617,14 +617,6 @@ protected: void DecrementIgnoreCount(); - // BreakpointLocation::IgnoreCountShouldStop & - // Breakpoint::IgnoreCountShouldStop can only be called once per stop, and - // BreakpointLocation::IgnoreCountShouldStop should be tested first, and if - // it returns false we should continue, otherwise we should test - // Breakpoint::IgnoreCountShouldStop. - - bool IgnoreCountShouldStop(); - private: // To call from CopyFromBreakpoint. Breakpoint(Target &new_target, const Breakpoint &bp_to_copy_from); @@ -648,8 +640,7 @@ private: // to skip certain breakpoint hits. For instance, exception breakpoints use // this to limit the stop to certain exception classes, while leaving the // condition & callback free for user specification. - std::unique_ptr<BreakpointOptions> - m_options_up; // Settable breakpoint options + BreakpointOptions m_options; // Settable breakpoint options BreakpointLocationList m_locations; // The list of locations currently found for this breakpoint. std::string m_kind_description; diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointLocation.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointLocation.h index 4e1c57a40435..a6d1232162fc 100644 --- a/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointLocation.h +++ b/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointLocation.h @@ -202,8 +202,8 @@ public: /// hasn't been done already /// /// \return - /// A pointer to the breakpoint options. - BreakpointOptions *GetLocationOptions(); + /// A reference to the breakpoint options. + BreakpointOptions &GetLocationOptions(); /// Use this to access breakpoint options from this breakpoint location. /// This will return the options that have a setting for the specified @@ -214,10 +214,10 @@ public: /// \return /// A pointer to the containing breakpoint's options if this /// location doesn't have its own copy. - const BreakpointOptions *GetOptionsSpecifyingKind( - BreakpointOptions::OptionKind kind) const; + const BreakpointOptions & + GetOptionsSpecifyingKind(BreakpointOptions::OptionKind kind) const; - bool ValidForThisThread(Thread *thread); + bool ValidForThisThread(Thread &thread); /// Invoke the callback action when the breakpoint is hit. /// @@ -230,6 +230,12 @@ public: /// \b true if the target should stop at this breakpoint and \b /// false not. bool InvokeCallback(StoppointCallbackContext *context); + + /// Report whether the callback for this location is synchronous or not. + /// + /// \return + /// \b true if the callback is synchronous and \b false if not. + bool IsCallbackSynchronous(); /// Returns whether we should resolve Indirect functions in setting the /// breakpoint site for this location. @@ -291,6 +297,10 @@ protected: void DecrementIgnoreCount(); + /// BreakpointLocation::IgnoreCountShouldStop can only be called once + /// per stop. This method checks first against the loc and then the owner. + /// It also takes care of decrementing the ignore counters. + /// If it returns false we should continue, otherwise stop. bool IgnoreCountShouldStop(); private: diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h index ffdb81e363e0..34bd30986487 100644 --- a/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h +++ b/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h @@ -136,7 +136,7 @@ public: /// return /// \b true if the collection contains at least one location that /// would be valid for this thread, false otherwise. - bool ValidForThisThread(Thread *thread); + bool ValidForThisThread(Thread &thread); /// Tell whether ALL the breakpoints in the location collection are internal. /// diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointOptions.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointOptions.h index 85b8e025a8e5..7b78265920a2 100644 --- a/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointOptions.h +++ b/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointOptions.h @@ -43,9 +43,7 @@ public: | eCondition | eAutoContinue) }; struct CommandData { - CommandData() - : user_source(), script_source(), - interpreter(lldb::eScriptLanguageNone), stop_on_error(true) {} + CommandData() : user_source(), script_source() {} CommandData(const StringList &user_source, lldb::ScriptLanguage interp) : user_source(user_source), script_source(), interpreter(interp), @@ -63,9 +61,10 @@ public: StringList user_source; std::string script_source; - enum lldb::ScriptLanguage - interpreter; // eScriptLanguageNone means command interpreter. - bool stop_on_error; + enum lldb::ScriptLanguage interpreter = + lldb::eScriptLanguageNone; // eScriptLanguageNone means command + // interpreter. + bool stop_on_error = true; private: enum class OptionNames : uint32_t { diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointResolver.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointResolver.h index d067b1eea6ff..7aa43b9f45df 100644 --- a/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointResolver.h +++ b/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointResolver.h @@ -204,7 +204,8 @@ protected: /// filter the results to find the first breakpoint >= (line, column). void SetSCMatchesByLine(SearchFilter &filter, SymbolContextList &sc_list, bool skip_prologue, llvm::StringRef log_ident, - uint32_t line = 0, uint32_t column = 0); + uint32_t line = 0, + llvm::Optional<uint16_t> column = llvm::None); void SetSCMatchesByLine(SearchFilter &, SymbolContextList &, bool, const char *) = delete; diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h index 222fc6fcd45d..bd8d0394d4d2 100644 --- a/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h +++ b/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h @@ -10,6 +10,7 @@ #define LLDB_BREAKPOINT_BREAKPOINTRESOLVERFILELINE_H #include "lldb/Breakpoint/BreakpointResolver.h" +#include "lldb/Core/SourceLocationSpec.h" namespace lldb_private { @@ -21,10 +22,8 @@ namespace lldb_private { class BreakpointResolverFileLine : public BreakpointResolver { public: BreakpointResolverFileLine(const lldb::BreakpointSP &bkpt, - const FileSpec &resolver, - uint32_t line_no, uint32_t column, - lldb::addr_t m_offset, bool check_inlines, - bool skip_prologue, bool exact_match); + lldb::addr_t offset, bool skip_prologue, + const SourceLocationSpec &location_spec); static BreakpointResolver * CreateFromStructuredData(const lldb::BreakpointSP &bkpt, @@ -60,13 +59,8 @@ protected: void FilterContexts(SymbolContextList &sc_list, bool is_relative); friend class Breakpoint; - FileSpec m_file_spec; ///< This is the file spec we are looking for. - uint32_t m_line_number; ///< This is the line number that we are looking for. - uint32_t m_column; ///< This is the column that we are looking for. - bool m_inlines; ///< This determines whether the resolver looks for inlined - ///< functions or not. + SourceLocationSpec m_location_spec; bool m_skip_prologue; - bool m_exact_match; private: BreakpointResolverFileLine(const BreakpointResolverFileLine &) = delete; diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointSite.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointSite.h index fc32c04ffe35..e4c850206fd8 100644 --- a/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointSite.h +++ b/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointSite.h @@ -148,7 +148,7 @@ public: /// return /// \b true if the collection contains at least one location that /// would be valid for this thread, false otherwise. - bool ValidForThisThread(Thread *thread); + bool ValidForThisThread(Thread &thread); /// Print a description of this breakpoint site to the stream \a s. /// GetDescription tells you about the breakpoint site's owners. Use diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/Stoppoint.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/Stoppoint.h index 36df77c4e91a..6bb1b6a705bc 100644 --- a/contrib/llvm-project/lldb/include/lldb/Breakpoint/Stoppoint.h +++ b/contrib/llvm-project/lldb/include/lldb/Breakpoint/Stoppoint.h @@ -33,7 +33,7 @@ public: void SetID(lldb::break_id_t bid); protected: - lldb::break_id_t m_bid; + lldb::break_id_t m_bid = LLDB_INVALID_BREAK_ID; private: // For Stoppoint only diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/StoppointCallbackContext.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/StoppointCallbackContext.h index db02ddd494fb..6da8d10d3f33 100644 --- a/contrib/llvm-project/lldb/include/lldb/Breakpoint/StoppointCallbackContext.h +++ b/contrib/llvm-project/lldb/include/lldb/Breakpoint/StoppointCallbackContext.h @@ -37,13 +37,14 @@ public: void Clear(); // Member variables - Event *event; // This is the event, the callback can modify this to indicate - // the meaning of the breakpoint hit + Event *event = nullptr; // This is the event, the callback can modify this to + // indicate the meaning of the breakpoint hit ExecutionContextRef exe_ctx_ref; // This tells us where we have stopped, what thread. - bool is_synchronous; // Is the callback being executed synchronously with the - // breakpoint, - // or asynchronously as the event is retrieved? + bool is_synchronous = + false; // Is the callback being executed synchronously with the + // breakpoint, + // or asynchronously as the event is retrieved? }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/StoppointHitCounter.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/StoppointHitCounter.h index 26f816da6430..ae9ec6b3c807 100644 --- a/contrib/llvm-project/lldb/include/lldb/Breakpoint/StoppointHitCounter.h +++ b/contrib/llvm-project/lldb/include/lldb/Breakpoint/StoppointHitCounter.h @@ -9,7 +9,7 @@ #ifndef LLDB_BREAKPOINT_STOPPOINT_HIT_COUNTER_H #define LLDB_BREAKPOINT_STOPPOINT_HIT_COUNTER_H -#include <assert.h> +#include <cassert> #include <cstdint> #include <limits> diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/WatchpointList.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/WatchpointList.h index 283f991b178a..bf87495d79db 100644 --- a/contrib/llvm-project/lldb/include/lldb/Breakpoint/WatchpointList.h +++ b/contrib/llvm-project/lldb/include/lldb/Breakpoint/WatchpointList.h @@ -14,6 +14,7 @@ #include <vector> #include "lldb/Core/Address.h" +#include "lldb/Utility/Iterable.h" #include "lldb/lldb-private.h" namespace lldb_private { @@ -37,6 +38,11 @@ public: /// Destructor, currently does nothing. ~WatchpointList(); + typedef std::list<lldb::WatchpointSP> wp_collection; + typedef LockingAdaptedIterable<wp_collection, lldb::WatchpointSP, + vector_adapter, std::recursive_mutex> + WatchpointIterable; + /// Add a Watchpoint to the list. /// /// \param[in] wp_sp @@ -184,8 +190,11 @@ public: /// The locker object that is set. void GetListMutex(std::unique_lock<std::recursive_mutex> &lock); + WatchpointIterable Watchpoints() const { + return WatchpointIterable(m_watchpoints, m_mutex); + } + protected: - typedef std::list<lldb::WatchpointSP> wp_collection; typedef std::vector<lldb::watch_id_t> id_vector; id_vector GetWatchpointIDs() const; @@ -198,7 +207,7 @@ protected: wp_collection m_watchpoints; mutable std::recursive_mutex m_mutex; - lldb::watch_id_t m_next_wp_id; + lldb::watch_id_t m_next_wp_id = 0; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/WatchpointOptions.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/WatchpointOptions.h index 0a18c52d36d0..fbfcb91c4249 100644 --- a/contrib/llvm-project/lldb/include/lldb/Breakpoint/WatchpointOptions.h +++ b/contrib/llvm-project/lldb/include/lldb/Breakpoint/WatchpointOptions.h @@ -166,13 +166,13 @@ public: lldb::user_id_t watch_id); struct CommandData { - CommandData() : user_source(), script_source(), stop_on_error(true) {} + CommandData() : user_source(), script_source() {} ~CommandData() = default; StringList user_source; std::string script_source; - bool stop_on_error; + bool stop_on_error = true; }; class CommandBaton : public TypedBaton<CommandData> { @@ -191,7 +191,7 @@ private: // For WatchpointOptions only WatchpointHitCallback m_callback; // This is the callback function pointer lldb::BatonSP m_callback_baton_sp; // This is the client data for the callback - bool m_callback_is_synchronous; + bool m_callback_is_synchronous = false; std::unique_ptr<ThreadSpec> m_thread_spec_up; // Thread for which this watchpoint will take }; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Address.h b/contrib/llvm-project/lldb/include/lldb/Core/Address.h index 71e50b91d68e..ec393a1871e3 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/Address.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/Address.h @@ -14,8 +14,8 @@ #include "lldb/lldb-private-enumerations.h" #include "lldb/lldb-types.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class Block; @@ -116,7 +116,7 @@ public: /// /// Initialize with a invalid section (NULL) and an invalid offset /// (LLDB_INVALID_ADDRESS). - Address() : m_section_wp(), m_offset(LLDB_INVALID_ADDRESS) {} + Address() : m_section_wp() {} /// Copy constructor /// @@ -487,7 +487,8 @@ public: protected: // Member variables. lldb::SectionWP m_section_wp; ///< The section for the address, can be NULL. - lldb::addr_t m_offset; ///< Offset into section if \a m_section_wp is valid... + lldb::addr_t m_offset = LLDB_INVALID_ADDRESS; ///< Offset into section if \a + ///< m_section_wp is valid... // Returns true if the m_section_wp once had a reference to a valid section // shared pointer, but no longer does. This can happen if we have an address diff --git a/contrib/llvm-project/lldb/include/lldb/Core/AddressRange.h b/contrib/llvm-project/lldb/include/lldb/Core/AddressRange.h index 8ccf96a436a1..6fbdc35c9168 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/AddressRange.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/AddressRange.h @@ -13,7 +13,7 @@ #include "lldb/lldb-forward.h" #include "lldb/lldb-types.h" -#include <stddef.h> +#include <cstddef> namespace lldb_private { class SectionList; @@ -94,8 +94,7 @@ public: /// \return /// Returns \b true if \a so_addr is contained in this range, /// \b false otherwise. - // bool - // Contains (const Address &so_addr) const; + bool Contains(const Address &so_addr) const; /// Check if a section offset address is contained in this range. /// @@ -240,7 +239,7 @@ public: protected: // Member variables Address m_base_addr; ///< The section offset base address of this range. - lldb::addr_t m_byte_size; ///< The size in bytes of this address range. + lldb::addr_t m_byte_size = 0; ///< The size in bytes of this address range. }; // bool operator== (const AddressRange& lhs, const AddressRange& rhs); diff --git a/contrib/llvm-project/lldb/include/lldb/Core/AddressResolver.h b/contrib/llvm-project/lldb/include/lldb/Core/AddressResolver.h index 9ac058a97cd9..cb571bb5cb60 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/AddressResolver.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/AddressResolver.h @@ -13,7 +13,7 @@ #include "lldb/Core/SearchFilter.h" #include "lldb/lldb-defines.h" -#include <stddef.h> +#include <cstddef> #include <vector> namespace lldb_private { diff --git a/contrib/llvm-project/lldb/include/lldb/Core/AddressResolverFileLine.h b/contrib/llvm-project/lldb/include/lldb/Core/AddressResolverFileLine.h index 46bf4155e865..e768256bf618 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/AddressResolverFileLine.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/AddressResolverFileLine.h @@ -11,10 +11,10 @@ #include "lldb/Core/AddressResolver.h" #include "lldb/Core/SearchFilter.h" -#include "lldb/Utility/FileSpec.h" +#include "lldb/Core/SourceLocationSpec.h" #include "lldb/lldb-defines.h" -#include <stdint.h> +#include <cstdint> namespace lldb_private { class Address; @@ -28,8 +28,7 @@ class SymbolContext; class AddressResolverFileLine : public AddressResolver { public: - AddressResolverFileLine(const FileSpec &resolver, uint32_t line_no, - bool check_inlines); + AddressResolverFileLine(SourceLocationSpec location_spec); ~AddressResolverFileLine() override; @@ -42,10 +41,7 @@ public: void GetDescription(Stream *s) override; protected: - FileSpec m_file_spec; // This is the file spec we are looking for. - uint32_t m_line_number; // This is the line number that we are looking for. - bool m_inlines; // This determines whether the resolver looks for inlined - // functions or not. + SourceLocationSpec m_src_location_spec; private: AddressResolverFileLine(const AddressResolverFileLine &) = delete; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/AddressResolverName.h b/contrib/llvm-project/lldb/include/lldb/Core/AddressResolverName.h deleted file mode 100644 index 0ec1ef05b0ec..000000000000 --- a/contrib/llvm-project/lldb/include/lldb/Core/AddressResolverName.h +++ /dev/null @@ -1,63 +0,0 @@ -//===-- AddressResolverName.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_CORE_ADDRESSRESOLVERNAME_H -#define LLDB_CORE_ADDRESSRESOLVERNAME_H - -#include "lldb/Core/AddressResolver.h" -#include "lldb/Core/SearchFilter.h" -#include "lldb/Utility/ConstString.h" -#include "lldb/Utility/RegularExpression.h" -#include "lldb/lldb-defines.h" - -namespace lldb_private { -class Address; -class Stream; -class SymbolContext; - -/// \class AddressResolverName AddressResolverName.h -/// "lldb/Core/AddressResolverName.h" This class finds addresses for a given -/// function name, either by exact match or by regular expression. - -class AddressResolverName : public AddressResolver { -public: - AddressResolverName(const char *func_name, - AddressResolver::MatchType type = Exact); - - // Creates a function breakpoint by regular expression. Takes over control - // of the lifespan of func_regex. - AddressResolverName(RegularExpression func_regex); - - AddressResolverName(const char *class_name, const char *method, - AddressResolver::MatchType type); - - ~AddressResolverName() override; - - Searcher::CallbackReturn SearchCallback(SearchFilter &filter, - SymbolContext &context, - Address *addr) override; - - lldb::SearchDepth GetDepth() override; - - void GetDescription(Stream *s) override; - -protected: - ConstString m_func_name; - ConstString m_class_name; // FIXME: Not used yet. The idea would be to stop - // on methods of this class. - RegularExpression m_regex; - AddressResolver::MatchType m_match_type; - -private: - AddressResolverName(const AddressResolverName &) = delete; - const AddressResolverName &operator=(const AddressResolverName &) = delete; -}; - -} // namespace lldb_private - -#endif // LLDB_CORE_ADDRESSRESOLVERNAME_H diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Architecture.h b/contrib/llvm-project/lldb/include/lldb/Core/Architecture.h index 2ea8bd31ebf4..b68bf27ae0df 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/Architecture.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/Architecture.h @@ -10,6 +10,7 @@ #define LLDB_CORE_ARCHITECTURE_H #include "lldb/Core/PluginInterface.h" +#include "lldb/Target/MemoryTagManager.h" namespace lldb_private { @@ -97,6 +98,17 @@ public: Target &target) const { return addr; } + + // Returns a pointer to an object that can manage memory tags for this + // Architecture E.g. masking out tags, unpacking tag streams etc. Returns + // nullptr if the architecture does not have a memory tagging extension. + // + // The return pointer being valid does not mean that the current process has + // memory tagging enabled, just that a tagging technology exists for this + // architecture. + virtual const MemoryTagManager *GetMemoryTagManager() const { + return nullptr; + } }; } // 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 354c4bbcc283..930e927f6783 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/Communication.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/Communication.h @@ -22,8 +22,8 @@ #include <ratio> #include <string> -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class Connection; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Debugger.h b/contrib/llvm-project/lldb/include/lldb/Core/Debugger.h index 68daae1a3710..f0849c9ac950 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/Debugger.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/Debugger.h @@ -9,7 +9,7 @@ #ifndef LLDB_CORE_DEBUGGER_H #define LLDB_CORE_DEBUGGER_H -#include <stdint.h> +#include <cstdint> #include <memory> #include <vector> @@ -42,9 +42,9 @@ #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/Threading.h" -#include <assert.h> -#include <stddef.h> -#include <stdio.h> +#include <cassert> +#include <cstddef> +#include <cstdio> namespace llvm { class raw_ostream; @@ -73,6 +73,50 @@ class Debugger : public std::enable_shared_from_this<Debugger>, friend class SourceManager; // For GetSourceFileCache. public: + /// Broadcaster event bits definitions. + enum { + eBroadcastBitProgress = (1 << 0), + }; + + static ConstString GetStaticBroadcasterClass(); + + /// Get the public broadcaster for this debugger. + Broadcaster &GetBroadcaster() { return m_broadcaster; } + const Broadcaster &GetBroadcaster() const { return m_broadcaster; } + + class ProgressEventData : public EventData { + + public: + ProgressEventData(uint64_t progress_id, const std::string &message, + uint64_t completed, uint64_t total, + bool debugger_specific) + : m_message(message), m_id(progress_id), m_completed(completed), + m_total(total), m_debugger_specific(debugger_specific) {} + + static ConstString GetFlavorString(); + + ConstString GetFlavor() const override; + + void Dump(Stream *s) const override; + + static const ProgressEventData * + GetEventDataFromEvent(const Event *event_ptr); + uint64_t GetID() const { return m_id; } + uint64_t GetCompleted() const { return m_completed; } + uint64_t GetTotal() const { return m_total; } + const std::string &GetMessage() const { return m_message; } + bool IsDebuggerSpecific() const { return m_debugger_specific; } + + private: + std::string m_message; + const uint64_t m_id; + uint64_t m_completed; + const uint64_t m_total; + const bool m_debugger_specific; + ProgressEventData(const ProgressEventData &) = delete; + const ProgressEventData &operator=(const ProgressEventData &) = delete; + }; + ~Debugger() override; static lldb::DebuggerSP @@ -246,6 +290,8 @@ public: const FormatEntity::Entry *GetFrameFormatUnique() const; + uint32_t GetStopDisassemblyMaxSize() const; + const FormatEntity::Entry *GetThreadFormat() const; const FormatEntity::Entry *GetThreadStopFormat() const; @@ -344,6 +390,40 @@ public: protected: friend class CommandInterpreter; friend class REPL; + friend class Progress; + + /// Report progress events. + /// + /// Progress events will be delivered to any debuggers that have listeners + /// for the eBroadcastBitProgress. This function is called by the + /// lldb_private::Progress class to deliver the events to any debuggers that + /// qualify. + /// + /// \param [in] progress_id + /// The unique integer identifier for the progress to report. + /// + /// \param[in] message + /// The title of the progress dialog to display in the UI. + /// + /// \param [in] completed + /// The amount of work completed. If \a completed is zero, then this event + /// is a progress started event. If \a completed is equal to \a total, then + /// this event is a progress end event. Otherwise completed indicates the + /// current progress compare to the total value. + /// + /// \param [in] total + /// The total amount of work units that need to be completed. If this value + /// is UINT64_MAX, then an indeterminate progress indicator should be + /// displayed. + /// + /// \param [in] debugger_id + /// If this optional parameter has a value, it indicates the unique + /// debugger identifier that this progress should be delivered to. If this + /// optional parameter does not have a value, the progress will be + /// delivered to all debuggers. + static void ReportProgress(uint64_t progress_id, const std::string &message, + uint64_t completed, uint64_t total, + llvm::Optional<lldb::user_id_t> debugger_id); bool StartEventHandlerThread(); @@ -430,7 +510,8 @@ protected: LoadedPluginsList m_loaded_plugins; HostThread m_event_handler_thread; HostThread m_io_handler_thread; - Broadcaster m_sync_broadcaster; + Broadcaster m_sync_broadcaster; ///< Private debugger synchronization. + Broadcaster m_broadcaster; ///< Public Debugger event broadcaster. lldb::ListenerSP m_forward_listener_sp; llvm::once_flag m_clear_once; lldb::TargetSP m_dummy_target_sp; diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/Declaration.h b/contrib/llvm-project/lldb/include/lldb/Core/Declaration.h index 7f19f45411a0..f81de21bc8f8 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/Declaration.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/Declaration.h @@ -14,7 +14,7 @@ namespace lldb_private { -/// \class Declaration Declaration.h "lldb/Symbol/Declaration.h" +/// \class Declaration Declaration.h "lldb/Core/Declaration.h" /// A class that describes the declaration location of a /// lldb object. /// @@ -24,14 +24,7 @@ namespace lldb_private { class Declaration { public: /// Default constructor. - Declaration() - : m_file(), m_line(0) -#ifdef LLDB_ENABLE_DECLARATION_COLUMNS - , - m_column(0) -#endif - { - } + Declaration() : m_file() {} /// Construct with file specification, and optional line and column. /// @@ -46,23 +39,13 @@ public: /// \param[in] column /// The column number that describes where this was declared. /// Set to zero if there is no column number information. - Declaration(const FileSpec &file_spec, uint32_t line = 0, uint32_t column = 0) - : m_file(file_spec), m_line(line) -#ifdef LLDB_ENABLE_DECLARATION_COLUMNS - , - m_column(column) -#endif - { - } + Declaration(const FileSpec &file_spec, uint32_t line = 0, + uint16_t column = LLDB_INVALID_COLUMN_NUMBER) + : m_file(file_spec), m_line(line), m_column(column) {} /// Construct with a pointer to another Declaration object. Declaration(const Declaration *decl_ptr) - : m_file(), m_line(0) -#ifdef LLDB_ENABLE_DECLARATION_COLUMNS - , - m_column(0) -#endif - { + : m_file(), m_line(0), m_column(LLDB_INVALID_COLUMN_NUMBER) { if (decl_ptr) *this = *decl_ptr; } @@ -74,9 +57,7 @@ public: void Clear() { m_file.Clear(); m_line = 0; -#ifdef LLDB_ENABLE_DECLARATION_COLUMNS m_column = 0; -#endif } /// Compare two declaration objects. @@ -118,18 +99,6 @@ public: void Dump(Stream *s, bool show_fullpaths) const; bool DumpStopContext(Stream *s, bool show_fullpaths) const; - /// Get accessor for the declaration column number. - /// - /// \return - /// Non-zero indicates a valid column number, zero indicates no - /// column information is available. - uint32_t GetColumn() const { -#ifdef LLDB_ENABLE_DECLARATION_COLUMNS - return m_column; -#else - return 0; -#endif - } /// Get accessor for file specification. /// @@ -150,7 +119,32 @@ public: /// line information is available. uint32_t GetLine() const { return m_line; } - bool IsValid() const { return m_file && m_line != 0; } + /// Get accessor for the declaration column number. + /// + /// \return + /// Non-zero indicates a valid column number, zero indicates no + /// column information is available. + uint16_t GetColumn() const { return m_column; } + + /// Convert to boolean operator. + /// + /// This allows code to check a Declaration object to see if it + /// contains anything valid using code such as: + /// + /// \code + /// Declaration decl(...); + /// if (decl) + /// { ... + /// \endcode + /// + /// \return + /// A \b true if both the file_spec and the line are valid, + /// \b false otherwise. + explicit operator bool() const { return IsValid(); } + + bool IsValid() const { + return m_file && m_line != 0 && m_line != LLDB_INVALID_LINE_NUMBER; + } /// Get the memory cost of this object. /// @@ -162,17 +156,6 @@ public: /// \see ConstString::StaticMemorySize () size_t MemorySize() const; - /// Set accessor for the declaration column number. - /// - /// \param[in] column - /// Non-zero indicates a valid column number, zero indicates no - /// column information is available. - void SetColumn(uint32_t column) { -#ifdef LLDB_ENABLE_DECLARATION_COLUMNS - m_column = col; -#endif - } - /// Set accessor for the declaration file specification. /// /// \param[in] file_spec @@ -186,16 +169,23 @@ public: /// line information is available. void SetLine(uint32_t line) { m_line = line; } + /// Set accessor for the declaration column number. + /// + /// \param[in] column + /// Non-zero indicates a valid column number, zero indicates no + /// column information is available. + void SetColumn(uint16_t column) { m_column = column; } + protected: - /// Member variables. - FileSpec m_file; ///< The file specification that points to the - ///< source file where the declaration occurred. - uint32_t m_line; ///< Non-zero values indicates a valid line number, - ///< zero indicates no line number information is available. -#ifdef LLDB_ENABLE_DECLARATION_COLUMNS - uint32_t m_column; ///< Non-zero values indicates a valid column number, - ///< zero indicates no column information is available. -#endif + /// The file specification that points to the source file where the + /// declaration occurred. + FileSpec m_file; + /// Non-zero values indicates a valid line number, zero indicates no line + /// number information is available. + uint32_t m_line = 0; + /// Non-zero values indicates a valid column number, zero indicates no column + /// information is available. + uint16_t m_column = LLDB_INVALID_COLUMN_NUMBER; }; bool operator==(const Declaration &lhs, const Declaration &rhs); diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Disassembler.h b/contrib/llvm-project/lldb/include/lldb/Core/Disassembler.h index 9a694de0f60a..622c23ff6492 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/Disassembler.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/Disassembler.h @@ -34,9 +34,9 @@ #include <string> #include <vector> -#include <stddef.h> -#include <stdint.h> -#include <stdio.h> +#include <cstddef> +#include <cstdint> +#include <cstdio> namespace llvm { template <typename T> class SmallVectorImpl; @@ -394,10 +394,12 @@ public: lldb::addr_t value; }; - static lldb::DisassemblerSP - DisassembleRange(const ArchSpec &arch, const char *plugin_name, - const char *flavor, Target &target, - const AddressRange &disasm_range, bool prefer_file_cache); + static lldb::DisassemblerSP DisassembleRange(const ArchSpec &arch, + const char *plugin_name, + const char *flavor, + Target &target, + const AddressRange &disasm_range, + bool force_live_memory = false); static lldb::DisassemblerSP DisassembleBytes(const ArchSpec &arch, const char *plugin_name, @@ -426,7 +428,8 @@ public: Stream &strm); size_t ParseInstructions(Target &target, Address address, Limit limit, - Stream *error_strm_ptr, bool prefer_file_cache); + Stream *error_strm_ptr, + bool force_live_memory = false); virtual size_t DecodeInstructions(const Address &base_addr, const DataExtractor &data, @@ -451,10 +454,10 @@ protected: struct SourceLine { FileSpec file; - uint32_t line; - uint32_t column; + uint32_t line = LLDB_INVALID_LINE_NUMBER; + uint32_t column = 0; - SourceLine() : file(), line(LLDB_INVALID_LINE_NUMBER), column(0) {} + SourceLine() : file() {} bool operator==(const SourceLine &rhs) const { return file == rhs.file && line == rhs.line && rhs.column == column; @@ -473,14 +476,12 @@ protected: // index of the "current" source line, if we want to highlight that when // displaying the source lines. (as opposed to the surrounding source // lines provided to give context) - size_t current_source_line; + size_t current_source_line = -1; // Whether to print a blank line at the end of the source lines. - bool print_source_context_end_eol; + bool print_source_context_end_eol = true; - SourceLinesToDisplay() - : lines(), current_source_line(-1), print_source_context_end_eol(true) { - } + SourceLinesToDisplay() : lines() {} }; // Get the function's declaration line number, hopefully a line number diff --git a/contrib/llvm-project/lldb/include/lldb/Core/DumpDataExtractor.h b/contrib/llvm-project/lldb/include/lldb/Core/DumpDataExtractor.h index 2a9d778e0a6a..12188609e8c0 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/DumpDataExtractor.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/DumpDataExtractor.h @@ -12,8 +12,8 @@ #include "lldb/lldb-enumerations.h" #include "lldb/lldb-types.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class DataExtractor; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/EmulateInstruction.h b/contrib/llvm-project/lldb/include/lldb/Core/EmulateInstruction.h index a575488ba966..f50fee095a8b 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/EmulateInstruction.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/EmulateInstruction.h @@ -21,8 +21,8 @@ #include "lldb/lldb-private-types.h" #include "lldb/lldb-types.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class OptionValueDictionary; @@ -182,8 +182,8 @@ public: } InfoType; struct Context { - ContextType type; - enum InfoType info_type; + ContextType type = eContextInvalid; + enum InfoType info_type = eInfoTypeNoArgs; union { struct RegisterPlusOffset { RegisterInfo reg; // base register @@ -237,7 +237,7 @@ public: uint32_t isa; } info; - Context() : type(eContextInvalid), info_type(eInfoTypeNoArgs) {} + Context() = default; void SetRegisterPlusOffset(RegisterInfo base_reg, int64_t signed_offset) { info_type = eInfoTypeRegisterPlusOffset; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/FileLineResolver.h b/contrib/llvm-project/lldb/include/lldb/Core/FileLineResolver.h index 68e252e93bc9..16b1db1b50c4 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/FileLineResolver.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/FileLineResolver.h @@ -14,7 +14,7 @@ #include "lldb/Utility/FileSpec.h" #include "lldb/lldb-defines.h" -#include <stdint.h> +#include <cstdint> namespace lldb_private { class Address; @@ -28,8 +28,8 @@ class FileLineResolver : public Searcher { public: FileLineResolver() : m_file_spec(), - m_line_number(UINT32_MAX), // Set this to zero for all lines in a file - m_sc_list(), m_inlines(true) {} + // Set this to zero for all lines in a file + m_sc_list() {} FileLineResolver(const FileSpec &resolver, uint32_t line_no, bool check_inlines); @@ -52,10 +52,11 @@ public: protected: FileSpec m_file_spec; // This is the file spec we are looking for. - uint32_t m_line_number; // This is the line number that we are looking for. + uint32_t m_line_number = + UINT32_MAX; // This is the line number that we are looking for. SymbolContextList m_sc_list; - bool m_inlines; // This determines whether the resolver looks for inlined - // functions or not. + bool m_inlines = true; // This determines whether the resolver looks for + // inlined functions or not. private: FileLineResolver(const FileLineResolver &) = delete; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/FileSpecList.h b/contrib/llvm-project/lldb/include/lldb/Core/FileSpecList.h index 3e412a7e1a32..cab8e9b9b43f 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/FileSpecList.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/FileSpecList.h @@ -14,7 +14,7 @@ #include <vector> -#include <stddef.h> +#include <cstddef> namespace lldb_private { class Stream; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/FormatEntity.h b/contrib/llvm-project/lldb/include/lldb/Core/FormatEntity.h index 91999f64ab5f..ecae8500df40 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/FormatEntity.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/FormatEntity.h @@ -9,26 +9,27 @@ #ifndef LLDB_CORE_FORMATENTITY_H #define LLDB_CORE_FORMATENTITY_H -#include "lldb/Utility/CompletionRequest.h" -#include "lldb/Utility/FileSpec.h" -#include "lldb/Utility/Status.h" #include "lldb/lldb-enumerations.h" #include "lldb/lldb-types.h" #include <algorithm> -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> #include <string> #include <vector> namespace lldb_private { class Address; +class CompletionRequest; class ExecutionContext; +class FileSpec; +class Status; class Stream; class StringList; class SymbolContext; class ValueObject; } + namespace llvm { class StringRef; } @@ -103,20 +104,51 @@ public: }; struct Definition { + /// The name/string placeholder that corresponds to this definition. const char *name; - const char *string; // Insert this exact string into the output - Entry::Type type; - uint64_t data; - uint32_t num_children; - Definition *children; // An array of "num_children" Definition entries, - bool keep_separator; + /// Insert this exact string into the output + const char *string = nullptr; + /// Entry::Type corresponding to this definition. + const Entry::Type type; + /// Data that is returned as the value of the format string. + const uint64_t data = 0; + /// The number of children of this node in the tree of format strings. + const uint32_t num_children = 0; + /// An array of "num_children" Definition entries. + const Definition *children = nullptr; + /// Whether the separator is kept during parsing or not. It's used + /// for entries with parameters. + const bool keep_separator = false; + + constexpr Definition(const char *name, const FormatEntity::Entry::Type t) + : name(name), type(t) {} + + constexpr Definition(const char *name, const char *string) + : name(name), string(string), type(Entry::Type::EscapeCode) {} + + constexpr Definition(const char *name, const FormatEntity::Entry::Type t, + const uint64_t data) + : name(name), type(t), data(data) {} + + constexpr Definition(const char *name, const FormatEntity::Entry::Type t, + const uint64_t num_children, + const Definition *children, + const bool keep_separator = false) + : name(name), type(t), num_children(num_children), children(children), + keep_separator(keep_separator) {} }; + template <size_t N> + static constexpr Definition + DefinitionWithChildren(const char *name, const FormatEntity::Entry::Type t, + const Definition (&children)[N], + bool keep_separator = false) { + return Definition(name, t, N, children, keep_separator); + } + Entry(Type t = Type::Invalid, const char *s = nullptr, const char *f = nullptr) - : string(s ? s : ""), printf_format(f ? f : ""), children(), - definition(nullptr), type(t), fmt(lldb::eFormatDefault), number(0), - deref(false) {} + : string(s ? s : ""), printf_format(f ? f : ""), children(), type(t) {} Entry(llvm::StringRef s); Entry(char ch); @@ -133,7 +165,6 @@ public: string.clear(); printf_format.clear(); children.clear(); - definition = nullptr; type = Type::Invalid; fmt = lldb::eFormatDefault; number = 0; @@ -157,8 +188,6 @@ public: } if (children != rhs.children) return false; - if (definition != rhs.definition) - return false; if (type != rhs.type) return false; if (fmt != rhs.fmt) @@ -171,11 +200,10 @@ public: std::string string; std::string printf_format; std::vector<Entry> children; - Definition *definition; Type type; - lldb::Format fmt; - lldb::addr_t number; - bool deref; + lldb::Format fmt = lldb::eFormatDefault; + lldb::addr_t number = 0; + bool deref = false; }; static bool Format(const Entry &entry, Stream &s, const SymbolContext *sc, diff --git a/contrib/llvm-project/lldb/include/lldb/Core/IOHandler.h b/contrib/llvm-project/lldb/include/lldb/Core/IOHandler.h index 2e8f3225fd5f..4a3b788e3ea1 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/IOHandler.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/IOHandler.h @@ -26,8 +26,8 @@ #include <string> #include <vector> -#include <stdint.h> -#include <stdio.h> +#include <cstdint> +#include <cstdio> namespace lldb_private { class Debugger; @@ -419,16 +419,14 @@ public: private: #if LLDB_ENABLE_LIBEDIT - static bool IsInputCompleteCallback(Editline *editline, StringList &lines, - void *baton); + bool IsInputCompleteCallback(Editline *editline, StringList &lines); - static int FixIndentationCallback(Editline *editline, const StringList &lines, - int cursor_position, void *baton); + int FixIndentationCallback(Editline *editline, const StringList &lines, + int cursor_position); - static llvm::Optional<std::string> SuggestionCallback(llvm::StringRef line, - void *baton); + llvm::Optional<std::string> SuggestionCallback(llvm::StringRef line); - static void AutoCompleteCallback(CompletionRequest &request, void *baton); + void AutoCompleteCallback(CompletionRequest &request); #endif protected: diff --git a/contrib/llvm-project/lldb/include/lldb/Core/LoadedModuleInfoList.h b/contrib/llvm-project/lldb/include/lldb/Core/LoadedModuleInfoList.h index 49400f7f4908..ad6da2bd7559 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/LoadedModuleInfoList.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/LoadedModuleInfoList.h @@ -101,14 +101,14 @@ public: lldb::addr_t m_dynamic; }; - LoadedModuleInfoList() : m_list(), m_link_map(LLDB_INVALID_ADDRESS) {} + LoadedModuleInfoList() : m_list() {} void add(const LoadedModuleInfo &mod) { m_list.push_back(mod); } void clear() { m_list.clear(); } std::vector<LoadedModuleInfo> m_list; - lldb::addr_t m_link_map; + lldb::addr_t m_link_map = LLDB_INVALID_ADDRESS; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Mangled.h b/contrib/llvm-project/lldb/include/lldb/Core/Mangled.h index c03fc1eb7599..d11d13b63cfc 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/Mangled.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/Mangled.h @@ -17,8 +17,8 @@ #include "llvm/ADT/StringRef.h" +#include <cstddef> #include <memory> -#include <stddef.h> namespace lldb_private { @@ -43,7 +43,8 @@ public: enum ManglingScheme { eManglingSchemeNone = 0, eManglingSchemeMSVC, - eManglingSchemeItanium + eManglingSchemeItanium, + eManglingSchemeRustV0 }; /// Default constructor. diff --git a/contrib/llvm-project/lldb/include/lldb/Core/MappedHash.h b/contrib/llvm-project/lldb/include/lldb/Core/MappedHash.h index a27ec82b9b86..7bd3c3a78449 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/MappedHash.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/MappedHash.h @@ -9,8 +9,8 @@ #ifndef LLDB_CORE_MAPPEDHASH_H #define LLDB_CORE_MAPPEDHASH_H -#include <assert.h> -#include <stdint.h> +#include <cassert> +#include <cstdint> #include <algorithm> #include <functional> @@ -47,19 +47,17 @@ public: uint32_t magic; // HASH_MAGIC or HASH_CIGAM magic value to allow endian detection - uint16_t version; // Version number - uint16_t hash_function; // The hash function enumeration that was used - uint32_t bucket_count; // The number of buckets in this hash table - uint32_t hashes_count; // The total number of unique hash values and hash - // data offsets in this table + uint16_t version = 1; // Version number + uint16_t hash_function = + eHashFunctionDJB; // The hash function enumeration that was used + uint32_t bucket_count = 0; // The number of buckets in this hash table + uint32_t hashes_count = 0; // The total number of unique hash values and + // hash data offsets in this table uint32_t header_data_len; // The size in bytes of the "header_data" template // member below HeaderData header_data; // - Header() - : magic(HASH_MAGIC), version(1), hash_function(eHashFunctionDJB), - bucket_count(0), hashes_count(0), header_data_len(sizeof(T)), - header_data() {} + Header() : magic(HASH_MAGIC), header_data_len(sizeof(T)), header_data() {} virtual ~Header() = default; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Module.h b/contrib/llvm-project/lldb/include/lldb/Core/Module.h index 9eb7477730c1..dd7100c4616c 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/Module.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/Module.h @@ -32,10 +32,10 @@ #include "llvm/Support/Chrono.h" #include <atomic> +#include <cstddef> +#include <cstdint> #include <memory> #include <mutex> -#include <stddef.h> -#include <stdint.h> #include <string> #include <vector> @@ -850,13 +850,10 @@ public: /// \param[in] path /// The original source file path to try and remap. /// - /// \param[out] new_path - /// The newly remapped filespec that is may or may not exist. - /// /// \return - /// /b true if \a path was successfully located and \a new_path - /// is filled in with a new source path, \b false otherwise. - bool RemapSourceFile(llvm::StringRef path, std::string &new_path) const; + /// The newly remapped filespec that is may or may not exist if + /// \a path was successfully located. + llvm::Optional<std::string> RemapSourceFile(llvm::StringRef path) const; bool RemapSourceFile(const char *, std::string &) const = delete; /// Update the ArchSpec to a more specific variant. @@ -885,10 +882,7 @@ public: /// correctly. class LookupInfo { public: - LookupInfo() - : m_name(), m_lookup_name(), m_language(lldb::eLanguageTypeUnknown), - m_name_type_mask(lldb::eFunctionNameTypeNone), - m_match_name_after_lookup(false) {} + LookupInfo() : m_name(), m_lookup_name() {} LookupInfo(ConstString name, lldb::FunctionNameType name_type_mask, lldb::LanguageType language); @@ -917,15 +911,15 @@ public: ConstString m_lookup_name; /// Limit matches to only be for this language - lldb::LanguageType m_language; + lldb::LanguageType m_language = lldb::eLanguageTypeUnknown; /// One or more bits from lldb::FunctionNameType that indicate what kind of /// names we are looking for - lldb::FunctionNameType m_name_type_mask; + lldb::FunctionNameType m_name_type_mask = lldb::eFunctionNameTypeNone; ///< If \b true, then demangled names that match will need to contain ///< "m_name" in order to be considered a match - bool m_match_name_after_lookup; + bool m_match_name_after_lookup = false; }; protected: @@ -952,7 +946,7 @@ protected: ConstString m_object_name; ///< The name an object within this module that is ///selected, or empty of the module is represented ///by \a m_file. - uint64_t m_object_offset; + uint64_t m_object_offset = 0; llvm::sys::TimePoint<> m_object_mod_time; /// DataBuffer containing the module image, if it was provided at diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ModuleList.h b/contrib/llvm-project/lldb/include/lldb/Core/ModuleList.h index 46a718f08f04..07dddd18357b 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ModuleList.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ModuleList.h @@ -27,8 +27,8 @@ #include <mutex> #include <vector> -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class ConstString; @@ -471,7 +471,7 @@ protected: collection m_modules; ///< The collection of modules. mutable std::recursive_mutex m_modules_mutex; - Notifier *m_notifier; + Notifier *m_notifier = nullptr; public: typedef LockingAdaptedIterable<collection, lldb::ModuleSP, vector_adapter, diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ModuleSpec.h b/contrib/llvm-project/lldb/include/lldb/Core/ModuleSpec.h index 9dd398a05291..8e5deebbab9a 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ModuleSpec.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ModuleSpec.h @@ -27,12 +27,11 @@ class ModuleSpec { public: ModuleSpec() : m_file(), m_platform_file(), m_symbol_file(), m_arch(), m_uuid(), - m_object_name(), m_object_offset(0), m_object_size(0), - m_source_mappings() {} + m_object_name(), m_source_mappings() {} - /// If the \param data argument is passed, its contents will be used + /// If the \c data argument is passed, its contents will be used /// as the module contents instead of trying to read them from - /// \param file_spec. + /// \c file_spec . ModuleSpec(const FileSpec &file_spec, const UUID &uuid = UUID(), lldb::DataBufferSP data = lldb::DataBufferSP()) : m_file(file_spec), m_platform_file(), m_symbol_file(), m_arch(), @@ -271,8 +270,8 @@ protected: ArchSpec m_arch; UUID m_uuid; ConstString m_object_name; - uint64_t m_object_offset; - uint64_t m_object_size; + uint64_t m_object_offset = 0; + uint64_t m_object_size = 0; llvm::sys::TimePoint<> m_object_mod_time; mutable PathMappingList m_source_mappings; lldb::DataBufferSP m_data = {}; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Opcode.h b/contrib/llvm-project/lldb/include/lldb/Core/Opcode.h index a812ae23f6b7..70f2dbdf639f 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/Opcode.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/Opcode.h @@ -14,9 +14,9 @@ #include "llvm/Support/SwapByteOrder.h" -#include <assert.h> -#include <stdint.h> -#include <string.h> +#include <cassert> +#include <cstdint> +#include <cstring> namespace lldb { class SBInstruction; @@ -38,7 +38,7 @@ public: eTypeBytes }; - Opcode() : m_byte_order(lldb::eByteOrderInvalid), m_type(eTypeInvalid) {} + Opcode() = default; Opcode(uint8_t inst, lldb::ByteOrder order) : m_byte_order(order), m_type(eType8) { @@ -252,9 +252,9 @@ protected: endian::InlHostByteOrder() == lldb::eByteOrderBig); } - lldb::ByteOrder m_byte_order; + lldb::ByteOrder m_byte_order = lldb::eByteOrderInvalid; - Opcode::Type m_type; + Opcode::Type m_type = eTypeInvalid; union { uint8_t inst8; uint16_t inst16; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/PluginManager.h b/contrib/llvm-project/lldb/include/lldb/Core/PluginManager.h index 0ac8308d1758..be91929c62e1 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/PluginManager.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/PluginManager.h @@ -19,8 +19,8 @@ #include "lldb/lldb-private-interfaces.h" #include "llvm/ADT/StringRef.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> #define LLDB_PLUGIN_DEFINE_ADV(ClassName, PluginName) \ namespace lldb_private { \ @@ -191,7 +191,8 @@ public: GetObjectFileCreateMemoryCallbackForPluginName(ConstString name); static Status SaveCore(const lldb::ProcessSP &process_sp, - const FileSpec &outfile); + const FileSpec &outfile, + lldb::SaveCoreStyle &core_style); // ObjectContainer static bool @@ -331,18 +332,20 @@ public: 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 RegisterPlugin( + ConstString name, const char *description, + TraceCreateInstanceForSessionFile create_callback_for_session_file, + TraceCreateInstanceForLiveProcess create_callback_for_live_process, + llvm::StringRef schema); - static bool UnregisterPlugin(TraceCreateInstance create_callback); + static bool + UnregisterPlugin(TraceCreateInstanceForSessionFile create_callback); - static TraceCreateInstance GetTraceCreateCallback(ConstString plugin_name); + static TraceCreateInstanceForSessionFile + GetTraceCreateCallback(ConstString plugin_name); - static lldb::CommandObjectSP - GetTraceStartCommand(llvm::StringRef plugin_name, - CommandInterpreter &interpreter); + static TraceCreateInstanceForLiveProcess + GetTraceCreateCallbackForLiveProcess(ConstString plugin_name); /// Get the JSON schema for a trace session file corresponding to the given /// plugin. @@ -366,6 +369,28 @@ public: /// number plugins, otherwise the actual schema is returned. static llvm::StringRef GetTraceSchema(size_t index); + // TraceExporter + + /// \param[in] create_thread_trace_export_command + /// This callback is used to create a CommandObject that will be listed + /// under "thread trace export". Can be \b null. + static bool RegisterPlugin( + ConstString name, const char *description, + TraceExporterCreateInstance create_callback, + ThreadTraceExportCommandCreator create_thread_trace_export_command); + + static TraceExporterCreateInstance + GetTraceExporterCreateCallback(ConstString plugin_name); + + static bool UnregisterPlugin(TraceExporterCreateInstance create_callback); + + static const char *GetTraceExporterPluginNameAtIndex(uint32_t index); + + /// Return the callback used to create the CommandObject that will be listed + /// under "thread trace export". Can be \b null. + static ThreadTraceExportCommandCreator + GetThreadTraceExportCommandCreatorAtIndex(uint32_t index); + // UnwindAssembly static bool RegisterPlugin(ConstString name, const char *description, UnwindAssemblyCreateInstance create_callback); diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Progress.h b/contrib/llvm-project/lldb/include/lldb/Core/Progress.h new file mode 100644 index 000000000000..f625d014f268 --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Core/Progress.h @@ -0,0 +1,114 @@ +//===-- Progress.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_CORE_PROGRESS_H +#define LLDB_CORE_PROGRESS_H + +#include "lldb/Utility/ConstString.h" +#include "lldb/lldb-types.h" +#include <atomic> +#include <mutex> + +namespace lldb_private { + +/// A Progress indicator helper class. +/// +/// Any potentially long running sections of code in LLDB should report +/// progress so that clients are aware of delays that might appear during +/// debugging. Delays commonly include indexing debug information, parsing +/// symbol tables for object files, downloading symbols from remote +/// repositories, and many more things. +/// +/// The Progress class helps make sure that progress is correctly reported +/// and will always send an initial progress update, updates when +/// Progress::Increment() is called, and also will make sure that a progress +/// completed update is reported even if the user doesn't explicitly cause one +/// to be sent. +/// +/// The progress is reported via a callback whose type is ProgressCallback: +/// +/// typedef void (*ProgressCallback)(uint64_t progress_id, +/// const char *message, +/// uint64_t completed, +/// uint64_t total, +/// void *baton); +/// +/// This callback will always initially be called with "completed" set to zero +/// and "total" set to the total amount specified in the contructor. This is +/// considered the progress start event. As Progress::Increment() is called, +/// the callback will be called as long as the Progress::m_completed has not +/// yet exceeded the Progress::m_total. When the callback is called with +/// Progress::m_completed == Progress::m_total, that is considered a progress +/// completed event. If Progress::m_completed is non-zero and less than +/// Progress::m_total, then this is considered a progress update event. +/// +/// This callback will be called in the destructor if Progress::m_completed is +/// not equal to Progress::m_total with the "completed" set to +/// Progress::m_total. This ensures we always send a progress completed update +/// even if the user does not. + +class Progress { +public: + /// Construct a progress object that will report information. + /// + /// The constructor will create a unique progress reporting object and + /// immediately send out a progress update by calling the installed callback + /// with completed set to zero out of the specified total. + /// + /// @param [in] title The title of this progress activity. + /// + /// @param [in] total The total units of work to be done if specified, if + /// set to UINT64_MAX then an indeterminate progress indicator should be + /// displayed. + /// + /// @param [in] debugger An optional debugger pointer to specify that this + /// progress is to be reported only to specific debuggers. + Progress(std::string title, uint64_t total = UINT64_MAX, + lldb_private::Debugger *debugger = nullptr); + + /// Destroy the progress object. + /// + /// If the progress has not yet sent a completion update, the destructor + /// will send out a notification where the completed == m_total. This ensures + /// that we always send out a progress complete notification. + ~Progress(); + + /// Increment the progress and send a notification to the intalled callback. + /// + /// If incrementing ends up exceeding m_total, m_completed will be updated + /// to match m_total and no subsequent progress notifications will be sent. + /// If no total was specified in the constructor, this function will not do + /// anything nor send any progress updates. + /// + /// @param [in] amount The amount to increment m_completed by. + void Increment(uint64_t amount = 1); + +private: + void ReportProgress(); + static std::atomic<uint64_t> g_id; + /// The title of the progress activity. + std::string m_title; + std::mutex m_mutex; + /// A unique integer identifier for progress reporting. + const uint64_t m_id; + /// How much work ([0...m_total]) that has been completed. + uint64_t m_completed; + /// Total amount of work, UINT64_MAX for non deterministic progress. + const uint64_t m_total; + /// The optional debugger ID to report progress to. If this has no value then + /// all debuggers will receive this event. + llvm::Optional<lldb::user_id_t> m_debugger_id; + /// Set to true when progress has been reported where m_completed == m_total + /// to ensure that we don't send progress updates after progress has + /// completed. + bool m_complete = false; +}; + +} // namespace lldb_private + +#endif // LLDB_CORE_PROGRESS_H diff --git a/contrib/llvm-project/lldb/include/lldb/Core/RichManglingContext.h b/contrib/llvm-project/lldb/include/lldb/Core/RichManglingContext.h index 68f80e73b724..48102ec0b1cf 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/RichManglingContext.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/RichManglingContext.h @@ -24,12 +24,12 @@ namespace lldb_private { /// providers. See Mangled::DemangleWithRichManglingInfo() class RichManglingContext { public: - RichManglingContext() : m_provider(None), m_ipd_buf_size(2048) { + RichManglingContext() { m_ipd_buf = static_cast<char *>(std::malloc(m_ipd_buf_size)); m_ipd_buf[0] = '\0'; } - ~RichManglingContext() { std::free(m_ipd_buf); } + ~RichManglingContext(); /// Use the ItaniumPartialDemangler to obtain rich mangling information from /// the given mangled name. @@ -70,15 +70,18 @@ private: enum InfoProvider { None, ItaniumPartialDemangler, PluginCxxLanguage }; /// Selects the rich mangling info provider. - InfoProvider m_provider; + InfoProvider m_provider = None; /// Reference to the buffer used for results of ParseXy() operations. llvm::StringRef m_buffer; /// Members for ItaniumPartialDemangler llvm::ItaniumPartialDemangler m_ipd; + /// Note: m_ipd_buf is a raw pointer due to being resized by realloc via + /// ItaniumPartialDemangler. It should be managed with malloc/free, not + /// new/delete. char *m_ipd_buf; - size_t m_ipd_buf_size; + size_t m_ipd_buf_size = 2048; /// Members for PluginCxxLanguage /// Cannot forward declare inner class CPlusPlusLanguage::MethodName. The @@ -86,6 +89,9 @@ private: /// dependency. Instead keep a llvm::Any and cast it on-access in the cpp. llvm::Any m_cxx_method_parser; + /// Clean up memory when using PluginCxxLanguage + void ResetCxxMethodParser(); + /// Clean up memory and set a new info provider for this instance. void ResetProvider(InfoProvider new_provider); diff --git a/contrib/llvm-project/lldb/include/lldb/Core/SearchFilter.h b/contrib/llvm-project/lldb/include/lldb/Core/SearchFilter.h index 54dc65e4410f..491e3ddc5985 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/SearchFilter.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/SearchFilter.h @@ -15,7 +15,7 @@ #include "lldb/Utility/FileSpec.h" #include "lldb/lldb-forward.h" -#include <stdint.h> +#include <cstdint> namespace lldb_private { class Address; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Section.h b/contrib/llvm-project/lldb/include/lldb/Core/Section.h index af2bb7896a5b..3d4ab154e743 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/Section.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/Section.h @@ -21,8 +21,8 @@ #include <memory> #include <vector> -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class Address; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/SourceLocationSpec.h b/contrib/llvm-project/lldb/include/lldb/Core/SourceLocationSpec.h new file mode 100644 index 000000000000..808931186dba --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Core/SourceLocationSpec.h @@ -0,0 +1,188 @@ +//===-- SourceLocationSpec.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_SOURCELOCATIONSPEC_H +#define LLDB_UTILITY_SOURCELOCATIONSPEC_H + +#include "lldb/Core/Declaration.h" +#include "lldb/lldb-defines.h" +#include "llvm/ADT/Optional.h" + +#include <string> + +namespace lldb_private { + +/// \class SourceLocationSpec SourceLocationSpec.h +/// "lldb/Core/SourceLocationSpec.h" A source location specifier class. +/// +/// A source location specifier class that holds a Declaration object containing +/// a FileSpec with line and column information. The column line is optional. +/// It also holds search flags that can be fetched by resolvers to look inlined +/// declarations and/or exact matches. +class SourceLocationSpec { +public: + /// Constructor. + /// + /// Takes a \a file_spec with a \a line number and a \a column number. If + /// \a column is null or not provided, it is set to llvm::None. + /// + /// \param[in] file_spec + /// The full or partial path to a file. + /// + /// \param[in] line + /// The line number in the source file. + /// + /// \param[in] column + /// The column number in the line of the source file. + /// + /// \param[in] check_inlines + /// Whether to look for a match in inlined declaration. + /// + /// \param[in] exact_match + /// Whether to look for an exact match. + /// + explicit SourceLocationSpec(FileSpec file_spec, uint32_t line, + llvm::Optional<uint16_t> column = llvm::None, + bool check_inlines = false, + bool exact_match = false); + + SourceLocationSpec() = delete; + + /// Convert to boolean operator. + /// + /// This allows code to check a SourceLocationSpec object to see if it + /// contains anything valid using code such as: + /// + /// \code + /// SourceLocationSpec location_spec(...); + /// if (location_spec) + /// { ... + /// \endcode + /// + /// \return + /// A pointer to this object if both the file_spec and the line are valid, + /// nullptr otherwise. + explicit operator bool() const; + + /// Logical NOT operator. + /// + /// This allows code to check a SourceLocationSpec object to see if it is + /// invalid using code such as: + /// + /// \code + /// SourceLocationSpec location_spec(...); + /// if (!location_spec) + /// { ... + /// \endcode + /// + /// \return + /// Returns \b true if the object has an invalid file_spec or line number, + /// \b false otherwise. + bool operator!() const; + + /// Equal to operator + /// + /// Tests if this object is equal to \a rhs. + /// + /// \param[in] rhs + /// A const SourceLocationSpec object reference to compare this object + /// to. + /// + /// \return + /// \b true if this object is equal to \a rhs, \b false + /// otherwise. + bool operator==(const SourceLocationSpec &rhs) const; + + /// Not equal to operator + /// + /// Tests if this object is not equal to \a rhs. + /// + /// \param[in] rhs + /// A const SourceLocationSpec object reference to compare this object + /// to. + /// + /// \return + /// \b true if this object is equal to \a rhs, \b false + /// otherwise. + bool operator!=(const SourceLocationSpec &rhs) const; + + /// Less than to operator + /// + /// Tests if this object is less than \a rhs. + /// + /// \param[in] rhs + /// A const SourceLocationSpec object reference to compare this object + /// to. + /// + /// \return + /// \b true if this object is less than \a rhs, \b false + /// otherwise. + bool operator<(const SourceLocationSpec &rhs) const; + + /// Compare two SourceLocationSpec objects. + /// + /// If \a full is true, then the file_spec, the line and column must match. + /// If \a full is false, then only the file_spec and line number for \a lhs + /// and \a rhs are compared. This allows a SourceLocationSpec object that have + /// no column information to match a SourceLocationSpec objects that have + /// column information with matching file_spec and line component. + /// + /// \param[in] lhs + /// A const reference to the Left Hand Side object to compare. + /// + /// \param[in] rhs + /// A const reference to the Right Hand Side object to compare. + /// + /// \param[in] full + /// If true, then the file_spec, the line and column must match for a + /// compare to return zero (equal to). If false, then only the file_spec + /// and line number for \a lhs and \a rhs are compared, else a full + /// comparison is done. + /// + /// \return -1 if \a lhs is less than \a rhs, 0 if \a lhs is equal to \a rhs, + /// 1 if \a lhs is greater than \a rhs + static int Compare(const SourceLocationSpec &lhs, + const SourceLocationSpec &rhs); + + static bool Equal(const SourceLocationSpec &lhs, + const SourceLocationSpec &rhs, bool full); + + /// Dump this object to a Stream. + /// + /// Dump the object to the supplied stream \a s, starting with the file name, + /// then the line number and if available the column number. + /// + /// \param[in] s + /// The stream to which to dump the object description. + void Dump(Stream &s) const; + + std::string GetString() const; + + FileSpec GetFileSpec() const { return m_declaration.GetFile(); } + + llvm::Optional<uint32_t> GetLine() const; + + llvm::Optional<uint16_t> GetColumn() const; + + bool GetCheckInlines() const { return m_check_inlines; } + + bool GetExactMatch() const { return m_exact_match; } + +protected: + Declaration m_declaration; + /// Tells if the resolver should look in inlined declaration. + bool m_check_inlines; + /// Tells if the resolver should look for an exact match. + bool m_exact_match; +}; + +/// Dump a SourceLocationSpec object to a stream +Stream &operator<<(Stream &s, const SourceLocationSpec &loc); +} // namespace lldb_private + +#endif // LLDB_UTILITY_SOURCELOCATIONSPEC_H diff --git a/contrib/llvm-project/lldb/include/lldb/Core/SourceManager.h b/contrib/llvm-project/lldb/include/lldb/Core/SourceManager.h index 7549c308f33a..5f2c1de84652 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/SourceManager.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/SourceManager.h @@ -15,10 +15,10 @@ #include "llvm/Support/Chrono.h" +#include <cstddef> #include <cstdint> #include <map> #include <memory> -#include <stddef.h> #include <string> #include <vector> diff --git a/contrib/llvm-project/lldb/include/lldb/Core/StreamAsynchronousIO.h b/contrib/llvm-project/lldb/include/lldb/Core/StreamAsynchronousIO.h index 949a798955d1..30eff55b2e51 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/StreamAsynchronousIO.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/StreamAsynchronousIO.h @@ -13,7 +13,7 @@ #include <string> -#include <stddef.h> +#include <cstddef> namespace lldb_private { class Debugger; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/StreamBuffer.h b/contrib/llvm-project/lldb/include/lldb/Core/StreamBuffer.h index 9c48ddb44d71..2e61a214302b 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/StreamBuffer.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/StreamBuffer.h @@ -11,7 +11,7 @@ #include "lldb/Utility/Stream.h" #include "llvm/ADT/SmallVector.h" -#include <stdio.h> +#include <cstdio> #include <string> namespace lldb_private { @@ -23,7 +23,7 @@ public: StreamBuffer(uint32_t flags, uint32_t addr_size, lldb::ByteOrder byte_order) : Stream(flags, addr_size, byte_order), m_packet() {} - ~StreamBuffer() override {} + ~StreamBuffer() override = default; void Flush() override { // Nothing to do when flushing a buffer based stream... diff --git a/contrib/llvm-project/lldb/include/lldb/Core/StreamFile.h b/contrib/llvm-project/lldb/include/lldb/Core/StreamFile.h index e71e31eb1d04..dba4042b6ec9 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/StreamFile.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/StreamFile.h @@ -14,8 +14,8 @@ #include "lldb/lldb-defines.h" #include "lldb/lldb-enumerations.h" -#include <stdint.h> -#include <stdio.h> +#include <cstdint> +#include <cstdio> namespace lldb_private { diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ThreadSafeValue.h b/contrib/llvm-project/lldb/include/lldb/Core/ThreadSafeValue.h index 38b8034fad53..51820ec9cd9d 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ThreadSafeValue.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ThreadSafeValue.h @@ -17,12 +17,10 @@ namespace lldb_private { template <class T> class ThreadSafeValue { public: - // Constructors and Destructors - ThreadSafeValue() : m_value(), m_mutex() {} - + ThreadSafeValue() = default; ThreadSafeValue(const T &value) : m_value(value), m_mutex() {} - ~ThreadSafeValue() {} + ~ThreadSafeValue() = default; T GetValue() const { T value; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/UserSettingsController.h b/contrib/llvm-project/lldb/include/lldb/Core/UserSettingsController.h index f40ad54ac4d6..35555f08c351 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/UserSettingsController.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/UserSettingsController.h @@ -17,8 +17,8 @@ #include <vector> -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class CommandInterpreter; @@ -32,12 +32,12 @@ namespace lldb_private { class Properties { public: - Properties() : m_collection_sp() {} + Properties() = default; Properties(const lldb::OptionValuePropertiesSP &collection_sp) : m_collection_sp(collection_sp) {} - virtual ~Properties() {} + virtual ~Properties() = default; virtual lldb::OptionValuePropertiesSP GetValueProperties() const { // This function is virtual in case subclasses want to lazily implement diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Value.h b/contrib/llvm-project/lldb/include/lldb/Core/Value.h index 0ff773e59911..1ee4fe639e6e 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/Value.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/Value.h @@ -21,8 +21,8 @@ #include <vector> -#include <stdint.h> -#include <string.h> +#include <cstdint> +#include <cstring> namespace lldb_private { class DataExtractor; @@ -37,27 +37,32 @@ namespace lldb_private { class Value { public: - // Values Less than zero are an error, greater than or equal to zero returns - // what the Scalar result is. - enum ValueType { - // m_value contains... - // ============================ - eValueTypeScalar, // raw scalar value - eValueTypeFileAddress, // file address value - eValueTypeLoadAddress, // load address value - eValueTypeHostAddress // host address value (for memory in the process that - // is using liblldb) + /// Type that describes Value::m_value. + enum class ValueType { + Invalid = -1, + // m_value contains: + /// A raw scalar value. + Scalar = 0, + /// A file address value. + FileAddress, + /// A load address value. + LoadAddress, + /// A host address value (for memory in the process that < A is + /// using liblldb). + HostAddress }; - enum ContextType // Type that describes Value::m_context - { - // m_context contains... - // ==================== - eContextTypeInvalid, // undefined - eContextTypeRegisterInfo, // RegisterInfo * (can be a scalar or a vector - // register) - eContextTypeLLDBType, // lldb_private::Type * - eContextTypeVariable // lldb_private::Variable * + /// Type that describes Value::m_context. + enum class ContextType { + // m_context contains: + /// Undefined. + Invalid = -1, + /// RegisterInfo * (can be a scalar or a vector register). + RegisterInfo = 0, + /// lldb_private::Type *. + LLDBType, + /// lldb_private::Variable *. + Variable }; Value(); @@ -85,16 +90,16 @@ public: void ClearContext() { m_context = nullptr; - m_context_type = eContextTypeInvalid; + m_context_type = ContextType::Invalid; } void SetContext(ContextType context_type, void *p) { m_context_type = context_type; m_context = p; - if (m_context_type == eContextTypeRegisterInfo) { + if (m_context_type == ContextType::RegisterInfo) { RegisterInfo *reg_info = GetRegisterInfo(); if (reg_info->encoding == lldb::eEncodingVector) - SetValueType(eValueTypeScalar); + SetValueType(ValueType::Scalar); } } @@ -143,9 +148,9 @@ public: protected: Scalar m_value; CompilerType m_compiler_type; - void *m_context; - ValueType m_value_type; - ContextType m_context_type; + void *m_context = nullptr; + ValueType m_value_type = ValueType::Scalar; + ContextType m_context_type = ContextType::Invalid; DataBufferHeap m_data_buffer; }; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObject.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObject.h index a665e7afa0ca..5f1cbc65b320 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObject.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObject.h @@ -37,8 +37,8 @@ #include <string> #include <utility> -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class Declaration; @@ -102,7 +102,7 @@ class TypeSummaryOptions; /// Shared Pointer to the contained ValueObject, /// just do so by calling GetSP() on the contained object. -class ValueObject : public UserID { +class ValueObject { public: enum GetExpressionPathFormat { eGetExpressionPathFormatDereferencePointers = 1, @@ -121,55 +121,62 @@ public: }; enum ExpressionPathScanEndReason { - eExpressionPathScanEndReasonEndOfString = 1, // out of data to parse - eExpressionPathScanEndReasonNoSuchChild, // child element not found - eExpressionPathScanEndReasonNoSuchSyntheticChild, // (synthetic) child - // element not found - eExpressionPathScanEndReasonEmptyRangeNotAllowed, // [] only allowed for - // arrays - eExpressionPathScanEndReasonDotInsteadOfArrow, // . used when -> should be - // used - eExpressionPathScanEndReasonArrowInsteadOfDot, // -> used when . should be - // used - eExpressionPathScanEndReasonFragileIVarNotAllowed, // ObjC ivar expansion - // not allowed - eExpressionPathScanEndReasonRangeOperatorNotAllowed, // [] not allowed by - // options - eExpressionPathScanEndReasonRangeOperatorInvalid, // [] not valid on objects - // other than scalars, - // pointers or arrays - eExpressionPathScanEndReasonArrayRangeOperatorMet, // [] is good for arrays, - // but I cannot parse it - eExpressionPathScanEndReasonBitfieldRangeOperatorMet, // [] is good for - // bitfields, but I - // cannot parse after - // it - eExpressionPathScanEndReasonUnexpectedSymbol, // something is malformed in - // the expression - eExpressionPathScanEndReasonTakingAddressFailed, // impossible to apply & - // operator - eExpressionPathScanEndReasonDereferencingFailed, // impossible to apply * - // operator - eExpressionPathScanEndReasonRangeOperatorExpanded, // [] was expanded into a - // VOList - eExpressionPathScanEndReasonSyntheticValueMissing, // getting the synthetic - // children failed + /// Out of data to parse. + eExpressionPathScanEndReasonEndOfString = 1, + /// Child element not found. + eExpressionPathScanEndReasonNoSuchChild, + /// (Synthetic) child element not found. + eExpressionPathScanEndReasonNoSuchSyntheticChild, + /// [] only allowed for arrays. + eExpressionPathScanEndReasonEmptyRangeNotAllowed, + /// . used when -> should be used. + eExpressionPathScanEndReasonDotInsteadOfArrow, + /// -> used when . should be used. + eExpressionPathScanEndReasonArrowInsteadOfDot, + /// ObjC ivar expansion not allowed. + eExpressionPathScanEndReasonFragileIVarNotAllowed, + /// [] not allowed by options. + eExpressionPathScanEndReasonRangeOperatorNotAllowed, + /// [] not valid on objects other than scalars, pointers or arrays. + eExpressionPathScanEndReasonRangeOperatorInvalid, + /// [] is good for arrays, but I cannot parse it. + eExpressionPathScanEndReasonArrayRangeOperatorMet, + /// [] is good for bitfields, but I cannot parse after it. + eExpressionPathScanEndReasonBitfieldRangeOperatorMet, + /// Something is malformed in he expression. + eExpressionPathScanEndReasonUnexpectedSymbol, + /// Impossible to apply & operator. + eExpressionPathScanEndReasonTakingAddressFailed, + /// Impossible to apply * operator. + eExpressionPathScanEndReasonDereferencingFailed, + /// [] was expanded into a VOList. + eExpressionPathScanEndReasonRangeOperatorExpanded, + /// getting the synthetic children failed. + eExpressionPathScanEndReasonSyntheticValueMissing, eExpressionPathScanEndReasonUnknown = 0xFFFF }; enum ExpressionPathEndResultType { - eExpressionPathEndResultTypePlain = 1, // anything but... - eExpressionPathEndResultTypeBitfield, // a bitfield - eExpressionPathEndResultTypeBoundedRange, // a range [low-high] - eExpressionPathEndResultTypeUnboundedRange, // a range [] - eExpressionPathEndResultTypeValueObjectList, // several items in a VOList + /// Anything but... + eExpressionPathEndResultTypePlain = 1, + /// A bitfield. + eExpressionPathEndResultTypeBitfield, + /// A range [low-high]. + eExpressionPathEndResultTypeBoundedRange, + /// A range []. + eExpressionPathEndResultTypeUnboundedRange, + /// Several items in a VOList. + eExpressionPathEndResultTypeValueObjectList, eExpressionPathEndResultTypeInvalid = 0xFFFF }; enum ExpressionPathAftermath { - eExpressionPathAftermathNothing = 1, // just return it - eExpressionPathAftermathDereference, // dereference the target - eExpressionPathAftermathTakeAddress // take target's address + /// Just return it. + eExpressionPathAftermathNothing = 1, + /// Dereference the target. + eExpressionPathAftermathDereference, + /// Take target's address. + eExpressionPathAftermathTakeAddress }; enum ClearUserVisibleDataItems { @@ -265,14 +272,6 @@ public: return m_exe_ctx_ref; } - // Set the EvaluationPoint to the values in exe_scope, Return true if the - // Evaluation Point changed. Since the ExecutionContextScope is always - // going to be valid currently, the Updated Context will also always be - // valid. - - // bool - // SetContext (ExecutionContextScope *exe_scope); - void SetIsConstant() { SetUpdated(); m_mod_id.SetInvalid(); @@ -319,7 +318,7 @@ public: ProcessModID m_mod_id; // This is the stop id when this ValueObject was last // evaluated. ExecutionContextRef m_exe_ctx_ref; - bool m_needs_update; + bool m_needs_update = true; }; virtual ~ValueObject(); @@ -350,10 +349,10 @@ public: void SetNeedsUpdate(); - CompilerType GetCompilerType(); + CompilerType GetCompilerType() { return MaybeCalculateCompleteType(); } // this vends a TypeImpl that is useful at the SB API layer - virtual TypeImpl GetTypeImpl(); + virtual TypeImpl GetTypeImpl() { return TypeImpl(GetCompilerType()); } virtual bool CanProvideValue(); @@ -363,24 +362,32 @@ public: virtual lldb::ValueType GetValueType() const = 0; // Subclasses can implement the functions below. - virtual ConstString GetTypeName(); + virtual ConstString GetTypeName() { return GetCompilerType().GetTypeName(); } - virtual ConstString GetDisplayTypeName(); + virtual ConstString GetDisplayTypeName() { return GetTypeName(); } - virtual ConstString GetQualifiedTypeName(); + virtual ConstString GetQualifiedTypeName() { + return GetCompilerType().GetTypeName(); + } - virtual lldb::LanguageType GetObjectRuntimeLanguage(); + virtual lldb::LanguageType GetObjectRuntimeLanguage() { + return GetCompilerType().GetMinimumLanguage(); + } virtual uint32_t - GetTypeInfo(CompilerType *pointee_or_element_compiler_type = nullptr); + GetTypeInfo(CompilerType *pointee_or_element_compiler_type = nullptr) { + return GetCompilerType().GetTypeInfo(pointee_or_element_compiler_type); + } - virtual bool IsPointerType(); + virtual bool IsPointerType() { return GetCompilerType().IsPointerType(); } - virtual bool IsArrayType(); + virtual bool IsArrayType() { return GetCompilerType().IsArrayType(); } - virtual bool IsScalarType(); + virtual bool IsScalarType() { return GetCompilerType().IsScalarType(); } - virtual bool IsPointerOrReferenceType(); + virtual bool IsPointerOrReferenceType() { + return GetCompilerType().IsPointerOrReferenceType(); + } virtual bool IsPossibleDynamicType(); @@ -394,7 +401,9 @@ public: virtual bool IsDereferenceOfParent() { return false; } - bool IsIntegerType(bool &is_signed); + bool IsIntegerType(bool &is_signed) { + return GetCompilerType().IsIntegerType(is_signed); + } virtual void GetExpressionPath( Stream &s, @@ -420,7 +429,9 @@ public: return (GetBitfieldBitSize() != 0) || (GetBitfieldBitOffset() != 0); } - virtual bool IsArrayItemForPointer() { return m_is_array_item_for_pointer; } + virtual bool IsArrayItemForPointer() { + return m_flags.m_is_array_item_for_pointer; + } virtual const char *GetValueAsCString(); @@ -436,16 +447,16 @@ public: virtual bool SetValueFromCString(const char *value_str, Status &error); - // Return the module associated with this value object in case the value is - // from an executable file and might have its data in sections of the file. - // This can be used for variables. + /// Return the module associated with this value object in case the value is + /// from an executable file and might have its data in sections of the file. + /// This can be used for variables. virtual lldb::ModuleSP GetModule(); ValueObject *GetRoot(); - // Given a ValueObject, loop over itself and its parent, and its parent's - // parent, .. until either the given callback returns false, or you end up at - // a null pointer + /// Given a ValueObject, loop over itself and its parent, and its parent's + /// parent, .. until either the given callback returns false, or you end up at + /// a null pointer ValueObject *FollowParentChain(std::function<bool(ValueObject *)>); virtual bool GetDeclaration(Declaration &decl); @@ -453,7 +464,10 @@ public: // The functions below should NOT be modified by subclasses const Status &GetError(); - ConstString GetName() const; + ConstString GetName() const { return m_name; } + + /// Returns a unique id for this ValueObject. + lldb::user_id_t GetID() const { return m_id.GetID(); } virtual lldb::ValueObjectSP GetChildAtIndex(size_t idx, bool can_create); @@ -480,9 +494,9 @@ public: size_t GetNumChildren(uint32_t max = UINT32_MAX); - const Value &GetValue() const; + const Value &GetValue() const { return m_value; } - Value &GetValue(); + Value &GetValue() { return m_value; } virtual bool ResolveValue(Scalar &scalar); @@ -491,7 +505,9 @@ public: // potentially a few others virtual bool IsLogicalTrue(Status &error); - virtual const char *GetLocationAsCString(); + virtual const char *GetLocationAsCString() { + return GetLocationAsCStringImpl(m_value, m_data); + } const char * GetSummaryAsCString(lldb::LanguageType lang = lldb::eLanguageTypeUnknown); @@ -526,11 +542,11 @@ public: PrintableRepresentationSpecialCases special = PrintableRepresentationSpecialCases::eAllow, bool do_dump_error = true); - bool GetValueIsValid() const; + bool GetValueIsValid() const { return m_flags.m_value_is_valid; } // If you call this on a newly created ValueObject, it will always return // false. - bool GetValueDidChange(); + bool GetValueDidChange() { return m_flags.m_value_did_change; } bool UpdateValueIfNeeded(bool update_format = true); @@ -538,10 +554,10 @@ public: lldb::ValueObjectSP GetSP() { return m_manager->GetSharedPointer(this); } - // Change the name of the current ValueObject. Should *not* be used from a - // synthetic child provider as it would change the name of the non synthetic - // child as well. - void SetName(ConstString name); + /// Change the name of the current ValueObject. Should *not* be used from a + /// synthetic child provider as it would change the name of the non synthetic + /// child as well. + void SetName(ConstString name) { m_name = name; } virtual lldb::addr_t GetAddressOf(bool scalar_is_load_address = true, AddressType *address_type = nullptr); @@ -571,9 +587,9 @@ public: lldb::DynamicValueType GetDynamicValueType(); - virtual lldb::ValueObjectSP GetStaticValue(); + virtual lldb::ValueObjectSP GetStaticValue() { return GetSP(); } - virtual lldb::ValueObjectSP GetNonSyntheticValue(); + virtual lldb::ValueObjectSP GetNonSyntheticValue() { return GetSP(); } lldb::ValueObjectSP GetSyntheticValue(); @@ -589,10 +605,10 @@ public: virtual lldb::ValueObjectSP Dereference(Status &error); - // Creates a copy of the ValueObject with a new name and setting the current - // ValueObject as its parent. It should be used when we want to change the - // name of a ValueObject without modifying the actual ValueObject itself - // (e.g. sythetic child provider). + /// Creates a copy of the ValueObject with a new name and setting the current + /// ValueObject as its parent. It should be used when we want to change the + /// name of a ValueObject without modifying the actual ValueObject itself + /// (e.g. sythetic child provider). virtual lldb::ValueObjectSP Clone(ConstString new_name); virtual lldb::ValueObjectSP AddressOf(Status &error); @@ -611,7 +627,7 @@ public: lldb::TypeSP &type_sp); // The backing bits of this value object were updated, clear any descriptive - // string, so we know we have to refetch them + // string, so we know we have to refetch them. virtual void ValueUpdated() { ClearUserVisibleData(eClearUserVisibleDataItemsValue | eClearUserVisibleDataItemsSummary | @@ -622,9 +638,13 @@ public: virtual bool DoesProvideSyntheticValue() { return false; } - virtual bool IsSyntheticChildrenGenerated(); + virtual bool IsSyntheticChildrenGenerated() { + return m_flags.m_is_synthetic_children_generated; + } - virtual void SetSyntheticChildrenGenerated(bool b); + virtual void SetSyntheticChildrenGenerated(bool b) { + m_flags.m_is_synthetic_children_generated = b; + } virtual SymbolContextScope *GetSymbolContextScope(); @@ -652,14 +672,10 @@ public: CreateValueObjectFromData(llvm::StringRef name, const DataExtractor &data, const ExecutionContext &exe_ctx, CompilerType type); - void LogValueObject(Log *log); - - void LogValueObject(Log *log, const DumpValueObjectOptions &options); - lldb::ValueObjectSP Persist(); - // returns true if this is a char* or a char[] if it is a char* and - // check_pointer is true, it also checks that the pointer is valid + /// Returns true if this is a char* or a char[] if it is a char* and + /// check_pointer is true, it also checks that the pointer is valid. bool IsCStringContainer(bool check_pointer = false); std::pair<size_t, bool> @@ -694,7 +710,9 @@ public: virtual lldb::LanguageType GetPreferredDisplayLanguage(); - void SetPreferredDisplayLanguage(lldb::LanguageType); + void SetPreferredDisplayLanguage(lldb::LanguageType lt) { + m_preferred_display_language = lt; + } lldb::TypeSummaryImplSP GetSummaryFormat() { UpdateFormatsIfNeeded(); @@ -744,7 +762,9 @@ public: AddressType GetAddressTypeOfChildren(); - void SetHasCompleteType() { m_did_calculate_complete_objc_class_type = true; } + void SetHasCompleteType() { + m_flags.m_did_calculate_complete_objc_class_type = true; + } /// Find out if a ValueObject might have children. /// @@ -766,16 +786,16 @@ public: virtual bool IsRuntimeSupportValue(); - virtual uint64_t GetLanguageFlags(); + virtual uint64_t GetLanguageFlags() { return m_language_flags; } - virtual void SetLanguageFlags(uint64_t flags); + virtual void SetLanguageFlags(uint64_t flags) { m_language_flags = flags; } protected: typedef ClusterManager<ValueObject> ValueObjectManager; class ChildrenManager { public: - ChildrenManager() : m_mutex(), m_children(), m_children_count(0) {} + ChildrenManager() : m_mutex(), m_children() {} bool HasChildAtIndex(size_t idx) { std::lock_guard<std::recursive_mutex> guard(m_mutex); @@ -811,80 +831,102 @@ protected: typedef ChildrenMap::value_type ChildrenPair; std::recursive_mutex m_mutex; ChildrenMap m_children; - size_t m_children_count; + size_t m_children_count = 0; }; // Classes that inherit from ValueObject can see and modify these - ValueObject - *m_parent; // The parent value object, or nullptr if this has no parent - ValueObject *m_root; // The root of the hierarchy for this ValueObject (or - // nullptr if never calculated) - EvaluationPoint m_update_point; // Stores both the stop id and the full - // context at which this value was last - // updated. When we are asked to update the value object, we check whether - // the context & stop id are the same before updating. - ConstString m_name; // The name of this object - DataExtractor - m_data; // A data extractor that can be used to extract the value. + + /// The parent value object, or nullptr if this has no parent. + ValueObject *m_parent = nullptr; + /// The root of the hierarchy for this ValueObject (or nullptr if never + /// calculated). + ValueObject *m_root = nullptr; + /// Stores both the stop id and the full context at which this value was last + /// updated. When we are asked to update the value object, we check whether + /// the context & stop id are the same before updating. + EvaluationPoint m_update_point; + /// The name of this object. + ConstString m_name; + /// A data extractor that can be used to extract the value. + DataExtractor m_data; Value m_value; - Status - m_error; // An error object that can describe any errors that occur when - // updating values. - std::string m_value_str; // Cached value string that will get cleared if/when - // the value is updated. - std::string m_old_value_str; // Cached old value string from the last time the - // value was gotten - std::string m_location_str; // Cached location string that will get cleared - // if/when the value is updated. - std::string m_summary_str; // Cached summary string that will get cleared - // if/when the value is updated. - std::string m_object_desc_str; // Cached result of the "object printer". This - // differs from the summary - // in that the summary is consed up by us, the object_desc_string is builtin. - - CompilerType m_override_type; // If the type of the value object should be - // overridden, the type to impose. - - ValueObjectManager *m_manager; // This object is managed by the root object - // (any ValueObject that gets created - // without a parent.) The manager gets passed through all the generations of - // dependent objects, and will keep the whole cluster of objects alive as - // long as a shared pointer to any of them has been handed out. Shared - // pointers to value objects must always be made with the GetSP method. + /// An error object that can describe any errors that occur when updating + /// values. + Status m_error; + /// Cached value string that will get cleared if/when the value is updated. + std::string m_value_str; + /// Cached old value string from the last time the value was gotten + std::string m_old_value_str; + /// Cached location string that will get cleared if/when the value is updated. + std::string m_location_str; + /// Cached summary string that will get cleared if/when the value is updated. + std::string m_summary_str; + /// Cached result of the "object printer". This differs from the summary + /// in that the summary is consed up by us, the object_desc_string is builtin. + std::string m_object_desc_str; + /// If the type of the value object should be overridden, the type to impose. + CompilerType m_override_type; + + /// This object is managed by the root object (any ValueObject that gets + /// created without a parent.) The manager gets passed through all the + /// generations of dependent objects, and will keep the whole cluster of + /// objects alive as long as a shared pointer to any of them has been handed + /// out. Shared pointers to value objects must always be made with the GetSP + /// method. + ValueObjectManager *m_manager = nullptr; ChildrenManager m_children; std::map<ConstString, ValueObject *> m_synthetic_children; - ValueObject *m_dynamic_value; - ValueObject *m_synthetic_value; - ValueObject *m_deref_valobj; + ValueObject *m_dynamic_value = nullptr; + ValueObject *m_synthetic_value = nullptr; + ValueObject *m_deref_valobj = nullptr; - lldb::ValueObjectSP m_addr_of_valobj_sp; // We have to hold onto a shared - // pointer to this one because it is - // created - // as an independent ValueObjectConstResult, which isn't managed by us. + /// We have to hold onto a shared pointer to this one because it is created + /// as an independent ValueObjectConstResult, which isn't managed by us. + lldb::ValueObjectSP m_addr_of_valobj_sp; - lldb::Format m_format; - lldb::Format m_last_format; - uint32_t m_last_format_mgr_revision; + lldb::Format m_format = lldb::eFormatDefault; + lldb::Format m_last_format = lldb::eFormatDefault; + uint32_t m_last_format_mgr_revision = 0; lldb::TypeSummaryImplSP m_type_summary_sp; lldb::TypeFormatImplSP m_type_format_sp; lldb::SyntheticChildrenSP m_synthetic_children_sp; ProcessModID m_user_id_of_forced_summary; - AddressType m_address_type_of_ptr_or_ref_children; + AddressType m_address_type_of_ptr_or_ref_children = eAddressTypeInvalid; llvm::SmallVector<uint8_t, 16> m_value_checksum; - lldb::LanguageType m_preferred_display_language; - - uint64_t m_language_flags; - - bool m_value_is_valid : 1, m_value_did_change : 1, m_children_count_valid : 1, - m_old_value_valid : 1, m_is_deref_of_parent : 1, - m_is_array_item_for_pointer : 1, m_is_bitfield_for_scalar : 1, - m_is_child_at_offset : 1, m_is_getting_summary : 1, - m_did_calculate_complete_objc_class_type : 1, - m_is_synthetic_children_generated : 1; + lldb::LanguageType m_preferred_display_language = lldb::eLanguageTypeUnknown; + + uint64_t m_language_flags = 0; + + /// Unique identifier for every value object. + UserID m_id; + + // Utility class for initializing all bitfields in ValueObject's constructors. + // FIXME: This could be done via default initializers once we have C++20. + struct Bitflags { + bool m_value_is_valid : 1, m_value_did_change : 1, + m_children_count_valid : 1, m_old_value_valid : 1, + m_is_deref_of_parent : 1, m_is_array_item_for_pointer : 1, + m_is_bitfield_for_scalar : 1, m_is_child_at_offset : 1, + m_is_getting_summary : 1, m_did_calculate_complete_objc_class_type : 1, + m_is_synthetic_children_generated : 1; + Bitflags() { + m_value_is_valid = false; + m_value_did_change = false; + m_children_count_valid = false; + m_old_value_valid = false; + m_is_deref_of_parent = false; + m_is_array_item_for_pointer = false; + m_is_bitfield_for_scalar = false; + m_is_child_at_offset = false; + m_is_getting_summary = false; + m_did_calculate_complete_objc_class_type = false; + m_is_synthetic_children_generated = false; + } + } m_flags; friend class ValueObjectChild; friend class ExpressionVariable; // For SetName @@ -892,22 +934,13 @@ protected: friend class ValueObjectConstResultImpl; friend class ValueObjectSynthetic; // For ClearUserVisibleData - // Constructors and Destructors - - // Use the no-argument constructor to make a constant variable object (with - // no ExecutionContextScope.) - - ValueObject(); - - // Use this constructor to create a "root variable object". The ValueObject - // will be locked to this context through-out its lifespan. - + /// Use this constructor to create a "root variable object". The ValueObject + /// will be locked to this context through-out its lifespan. ValueObject(ExecutionContextScope *exe_scope, ValueObjectManager &manager, AddressType child_ptr_or_ref_addr_type = eAddressTypeLoad); - // Use this constructor to create a ValueObject owned by another ValueObject. - // It will inherit the ExecutionContext of its parent. - + /// Use this constructor to create a ValueObject owned by another ValueObject. + /// It will inherit the ExecutionContext of its parent. ValueObject(ValueObject &parent); ValueObjectManager *GetManager() { return m_manager; } @@ -928,20 +961,23 @@ protected: virtual void CalculateSyntheticValue(); - // Should only be called by ValueObject::GetChildAtIndex() Returns a - // ValueObject managed by this ValueObject's manager. + /// Should only be called by ValueObject::GetChildAtIndex(). + /// + /// \return A ValueObject managed by this ValueObject's manager. virtual ValueObject *CreateChildAtIndex(size_t idx, bool synthetic_array_member, int32_t synthetic_index); - // Should only be called by ValueObject::GetNumChildren() + /// Should only be called by ValueObject::GetNumChildren(). virtual size_t CalculateNumChildren(uint32_t max = UINT32_MAX) = 0; void SetNumChildren(size_t num_children); - void SetValueDidChange(bool value_changed); + void SetValueDidChange(bool value_changed) { + m_flags.m_value_did_change = value_changed; + } - void SetValueIsValid(bool valid); + void SetValueIsValid(bool valid) { m_flags.m_value_is_valid = valid; } void ClearUserVisibleData( uint32_t items = ValueObject::eClearUserVisibleDataItemsAllStrings); @@ -959,7 +995,7 @@ protected: const char *GetLocationAsCStringImpl(const Value &value, const DataExtractor &data); - bool IsChecksumEmpty(); + bool IsChecksumEmpty() { return m_value_checksum.empty(); } void SetPreferredDisplayLanguageIfNeeded(lldb::LanguageType); @@ -983,47 +1019,6 @@ private: const ValueObject &operator=(const ValueObject &) = delete; }; -// A value object manager class that is seeded with the static variable value -// and it vends the user facing value object. If the type is dynamic it can -// vend the dynamic type. If this user type also has a synthetic type -// associated with it, it will vend the synthetic type. The class watches the -// process' stop -// ID and will update the user type when needed. -class ValueObjectManager { - // The root value object is the static typed variable object. - lldb::ValueObjectSP m_root_valobj_sp; - // The user value object is the value object the user wants to see. - lldb::ValueObjectSP m_user_valobj_sp; - lldb::DynamicValueType m_use_dynamic; - uint32_t m_stop_id; // The stop ID that m_user_valobj_sp is valid for. - bool m_use_synthetic; - -public: - ValueObjectManager() {} - - ValueObjectManager(lldb::ValueObjectSP in_valobj_sp, - lldb::DynamicValueType use_dynamic, bool use_synthetic); - - bool IsValid() const; - - lldb::ValueObjectSP GetRootSP() const { return m_root_valobj_sp; } - - // Gets the correct value object from the root object for a given process - // stop ID. If dynamic values are enabled, or if synthetic children are - // enabled, the value object that the user wants to see might change while - // debugging. - lldb::ValueObjectSP GetSP(); - - void SetUseDynamic(lldb::DynamicValueType use_dynamic); - void SetUseSynthetic(bool use_synthetic); - lldb::DynamicValueType GetUseDynamic() const { return m_use_dynamic; } - bool GetUseSynthetic() const { return m_use_synthetic; } - lldb::TargetSP GetTargetSP() const; - lldb::ProcessSP GetProcessSP() const; - lldb::ThreadSP GetThreadSP() const; - lldb::StackFrameSP GetFrameSP() const; -}; - } // namespace lldb_private #endif // LLDB_CORE_VALUEOBJECT_H diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectCast.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectCast.h index 342803f8ca63..84cf13353aee 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectCast.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectCast.h @@ -15,13 +15,13 @@ #include "lldb/lldb-enumerations.h" #include "lldb/lldb-forward.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class ConstString; -// A ValueObject that represents a given value represented as a different type. +/// A ValueObject that represents a given value represented as a different type. class ValueObjectCast : public ValueObject { public: ~ValueObjectCast() override; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectChild.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectChild.h index 9a9fd9294261..8a7a7f17bc76 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectChild.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectChild.h @@ -20,12 +20,12 @@ #include "llvm/ADT/Optional.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { -// A child of another ValueObject. +/// A child of another ValueObject. class ValueObjectChild : public ValueObject { public: ~ValueObjectChild() override; @@ -71,10 +71,6 @@ protected: bool m_is_deref_of_parent; llvm::Optional<LazyBool> m_can_update_with_invalid_exe_ctx; - // - // void - // ReadValueFromMemory (ValueObject* parent, lldb::addr_t address); - friend class ValueObject; friend class ValueObjectConstResult; friend class ValueObjectConstResultImpl; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResult.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResult.h index 8d823baa0b7b..58cda6fd6196 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResult.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResult.h @@ -21,15 +21,15 @@ #include "lldb/lldb-private-enumerations.h" #include "lldb/lldb-types.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class DataExtractor; class ExecutionContextScope; class Module; -// A frozen ValueObject copied into host memory +/// A frozen ValueObject copied into host memory. class ValueObjectConstResult : public ValueObject { public: ~ValueObjectConstResult() override; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResultCast.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResultCast.h index ba81785866c3..5467ce3db403 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResultCast.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResultCast.h @@ -17,8 +17,8 @@ #include "lldb/lldb-forward.h" #include "lldb/lldb-types.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class DataExtractor; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResultChild.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResultChild.h index b3606bfde0ef..26bd9f337a59 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResultChild.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResultChild.h @@ -17,8 +17,8 @@ #include "lldb/lldb-forward.h" #include "lldb/lldb-types.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class DataExtractor; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResultImpl.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResultImpl.h index 1316bf66dfdb..2536c51fa574 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResultImpl.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResultImpl.h @@ -15,8 +15,8 @@ #include "lldb/lldb-private-enumerations.h" #include "lldb/lldb-types.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class CompilerType; class DataExtractor; @@ -26,9 +26,9 @@ class ValueObject; namespace lldb_private { -// A class wrapping common implementation details for operations in -// ValueObjectConstResult ( & Child ) that may need to jump from the host -// memory space into the target's memory space +/// A class wrapping common implementation details for operations in +/// ValueObjectConstResult ( & Child ) that may need to jump from the host +/// memory space into the target's memory space. class ValueObjectConstResultImpl { public: ValueObjectConstResultImpl(ValueObject *valobj, diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectDynamicValue.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectDynamicValue.h index 2806857339ef..8822a1d39249 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectDynamicValue.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectDynamicValue.h @@ -19,17 +19,17 @@ #include "lldb/lldb-forward.h" #include "lldb/lldb-private-enumerations.h" -#include <assert.h> -#include <stddef.h> -#include <stdint.h> +#include <cassert> +#include <cstddef> +#include <cstdint> namespace lldb_private { class DataExtractor; class Declaration; class Status; -// A ValueObject that represents memory at a given address, viewed as some -// set lldb type. +/// A ValueObject that represents memory at a given address, viewed as some +/// set lldb type. class ValueObjectDynamicValue : public ValueObject { public: ~ValueObjectDynamicValue() override; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectList.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectList.h index f99fba41aa26..fcb358e21a26 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectList.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectList.h @@ -14,12 +14,12 @@ #include <vector> -#include <stddef.h> +#include <cstddef> namespace lldb_private { class ValueObject; -// A collection of ValueObject values that +/// A collection of ValueObject values that. class ValueObjectList { public: const ValueObjectList &operator=(const ValueObjectList &rhs); diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectMemory.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectMemory.h index b5d5e6ecf4c0..83671a794b5f 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectMemory.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectMemory.h @@ -18,14 +18,14 @@ #include "lldb/lldb-forward.h" #include "llvm/ADT/StringRef.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class ExecutionContextScope; -// A ValueObject that represents memory at a given address, viewed as some -// set lldb type. +/// A ValueObject that represents memory at a given address, viewed as some +/// set lldb type. class ValueObjectMemory : public ValueObject { public: ~ValueObjectMemory() override; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectRegister.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectRegister.h index 3968584ad518..e210b36d2a45 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectRegister.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectRegister.h @@ -18,8 +18,8 @@ #include "lldb/lldb-forward.h" #include "lldb/lldb-private-types.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class DataExtractor; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h index 41c461ce13f0..f7a233047cc1 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h @@ -20,18 +20,18 @@ #include <cstdint> #include <memory> -#include <stddef.h> +#include <cstddef> namespace lldb_private { class Declaration; class Status; class SyntheticChildrenFrontEnd; -// A ValueObject that obtains its children from some source other than -// real information -// This is currently used to implement Python-based children and filters but -// you can bind it to any source of synthetic information and have it behave -// accordingly +/// A ValueObject that obtains its children from some source other than +/// real information. +/// This is currently used to implement Python-based children and filters but +/// you can bind it to any source of synthetic information and have it behave +/// accordingly. class ValueObjectSynthetic : public ValueObject { public: ~ValueObjectSynthetic() override; @@ -148,9 +148,9 @@ protected: /// Guarded by m_child_mutex; SyntheticChildrenCache m_synthetic_children_cache; - uint32_t m_synthetic_children_count; // FIXME use the ValueObject's - // ChildrenManager instead of a special - // purpose solution + // FIXME: use the ValueObject's ChildrenManager instead of a special purpose + // solution. + uint32_t m_synthetic_children_count; ConstString m_parent_type_name; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectUpdater.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectUpdater.h new file mode 100644 index 000000000000..54fcb31076ad --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectUpdater.h @@ -0,0 +1,43 @@ +//===-- ValueObjectUpdater.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_CORE_VALUEOBJECTUPDATER_H +#define LLDB_CORE_VALUEOBJECTUPDATER_H + +#include "lldb/Core/ValueObject.h" + +namespace lldb_private { + +/// A value object class that is seeded with the static variable value +/// and it vends the user facing value object. If the type is dynamic it can +/// vend the dynamic type. If this user type also has a synthetic type +/// associated with it, it will vend the synthetic type. The class watches the +/// process' stop ID and will update the user type when needed. +class ValueObjectUpdater { + /// The root value object is the static typed variable object. + lldb::ValueObjectSP m_root_valobj_sp; + /// The user value object is the value object the user wants to see. + lldb::ValueObjectSP m_user_valobj_sp; + /// The stop ID that m_user_valobj_sp is valid for. + uint32_t m_stop_id = UINT32_MAX; + +public: + ValueObjectUpdater(lldb::ValueObjectSP in_valobj_sp); + + /// Gets the correct value object from the root object for a given process + /// stop ID. If dynamic values are enabled, or if synthetic children are + /// enabled, the value object that the user wants to see might change while + /// debugging. + lldb::ValueObjectSP GetSP(); + + lldb::ProcessSP GetProcessSP() const; +}; + +} // namespace lldb_private + +#endif // LLDB_CORE_VALUEOBJECTUPDATER_H diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectVariable.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectVariable.h index 23fdedbf5a4a..cbf7e5b52ced 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectVariable.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectVariable.h @@ -18,8 +18,8 @@ #include "lldb/lldb-enumerations.h" #include "lldb/lldb-forward.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class DataExtractor; @@ -28,8 +28,8 @@ class Status; class ExecutionContextScope; class SymbolContextScope; -// A ValueObject that contains a root variable that may or may not -// have children. +/// A ValueObject that contains a root variable that may or may not +/// have children. class ValueObjectVariable : public ValueObject { public: ~ValueObjectVariable() override; @@ -72,10 +72,11 @@ protected: CompilerType GetCompilerTypeImpl() override; - lldb::VariableSP - m_variable_sp; ///< The variable that this value object is based upon - Value m_resolved_value; ///< The value that DWARFExpression resolves this - ///variable to before we patch it up + /// The variable that this value object is based upon. + lldb::VariableSP m_variable_sp; + ///< The value that DWARFExpression resolves this variable to before we patch + ///< it up. + Value m_resolved_value; private: ValueObjectVariable(ExecutionContextScope *exe_scope, diff --git a/contrib/llvm-project/lldb/include/lldb/Core/dwarf.h b/contrib/llvm-project/lldb/include/lldb/Core/dwarf.h index cd9cf249bc63..968418e71c2f 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/dwarf.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/dwarf.h @@ -10,7 +10,7 @@ #define LLDB_CORE_DWARF_H #include "lldb/Utility/RangeMap.h" -#include <stdint.h> +#include <cstdint> // Get the DWARF constant definitions from llvm #include "llvm/BinaryFormat/Dwarf.h" @@ -38,39 +38,6 @@ typedef uint32_t dw_offset_t; // Dwarf Debug Information Entry offset for any #define DW_EH_PE_MASK_ENCODING 0x0F -//// The following are used only internally within lldb - don't -//// document them in the llvm Dwarf.h header file, we won't see -//// them in executable files anywhere. -//// These constants fit between DW_OP_lo_user (0xe0) and DW_OP_hi_user (0xff). -// -//#define DW_OP_APPLE_array_ref 0xEE // first pops index, then pops array; -//pushes array[index] -//#define DW_OP_APPLE_extern 0xEF // ULEB128 index of external object -//(i.e., an entity from the program that was used in the expression) -#define DW_OP_APPLE_uninit \ - 0xF0 // This is actually generated by some apple compilers in locations lists -//#define DW_OP_APPLE_assign 0xF1 // pops value off and assigns it to -//second item on stack (2nd item must have assignable context) -//#define DW_OP_APPLE_address_of 0xF2 // gets the address of the top stack -//item (top item must be a variable, or have value_type that is an address -//already) -//#define DW_OP_APPLE_value_of 0xF3 // pops the value off the stack and -//pushes the value of that object (top item must be a variable, or expression -//local) -//#define DW_OP_APPLE_deref_type 0xF4 // gets the address of the top stack -//item (top item must be a variable, or a clang type) -//#define DW_OP_APPLE_expr_local 0xF5 // ULEB128 expression local index -//#define DW_OP_APPLE_constf 0xF6 // 1 byte float size, followed by -//constant float data -//#define DW_OP_APPLE_scalar_cast 0xF7 // Cast top of stack to 2nd in stack's -//type leaving all items in place -//#define DW_OP_APPLE_clang_cast 0xF8 // pointer size clang::Type * off the -//stack and cast top stack item to this type -//#define DW_OP_APPLE_clear 0xFE // clears the entire expression stack, -//ok if the stack is empty -//#define DW_OP_APPLE_error 0xFF // Stops expression evaluation and -//returns an error (no args) - typedef lldb_private::RangeVector<dw_addr_t, dw_addr_t, 2> DWARFRangeList; #endif // LLDB_CORE_DWARF_H diff --git a/contrib/llvm-project/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h b/contrib/llvm-project/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h index 2f3bdf80a6f1..cef43f45b8e4 100644 --- a/contrib/llvm-project/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h +++ b/contrib/llvm-project/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h @@ -35,12 +35,11 @@ public: }; struct PointerAsArraySettings { - size_t m_element_count; - size_t m_base_element; - size_t m_stride; + size_t m_element_count = 0; + size_t m_base_element = 0; + size_t m_stride = 0; - PointerAsArraySettings() - : m_element_count(0), m_base_element(0), m_stride() {} + PointerAsArraySettings() = default; PointerAsArraySettings(size_t elem_count, size_t base_elem = 0, size_t stride = 1) @@ -62,8 +61,6 @@ public: DumpValueObjectOptions(); - DumpValueObjectOptions(const DumpValueObjectOptions &rhs) = default; - DumpValueObjectOptions(ValueObject &valobj); DumpValueObjectOptions & diff --git a/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormatClasses.h b/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormatClasses.h index e3989133a602..b8540de3d740 100644 --- a/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormatClasses.h +++ b/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormatClasses.h @@ -105,7 +105,7 @@ private: class TypeNameSpecifierImpl { public: - TypeNameSpecifierImpl() : m_is_regex(false), m_type() {} + TypeNameSpecifierImpl() : m_type() {} TypeNameSpecifierImpl(llvm::StringRef name, bool is_regex) : m_is_regex(is_regex), m_type() { @@ -143,7 +143,7 @@ public: bool IsRegex() { return m_is_regex; } private: - bool m_is_regex; + bool m_is_regex = false; // TODO: Replace this with TypeAndOrName. struct TypeOrName { std::string m_type_name; diff --git a/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormattersHelpers.h b/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormattersHelpers.h index a5b0da57e5d8..892807063b9c 100644 --- a/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormattersHelpers.h +++ b/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormattersHelpers.h @@ -36,11 +36,13 @@ void AddOneLineSummary(TypeCategoryImpl::SharedPointer category_sp, ConstString type_name, TypeSummaryImpl::Flags flags, bool regex = false); +/// Add a summary that is implemented by a C++ callback. void AddCXXSummary(TypeCategoryImpl::SharedPointer category_sp, CXXFunctionSummaryFormat::Callback funct, const char *description, ConstString type_name, TypeSummaryImpl::Flags flags, bool regex = false); +/// Add a synthetic that is implemented by a C++ callback. void AddCXXSynthetic(TypeCategoryImpl::SharedPointer category_sp, CXXSyntheticChildren::CreateFrontEndCallback generator, const char *description, ConstString type_name, diff --git a/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeFormat.h b/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeFormat.h index b8ed6a3443b3..4e19d4cb14a1 100644 --- a/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeFormat.h +++ b/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeFormat.h @@ -25,7 +25,7 @@ class TypeFormatImpl { public: class Flags { public: - Flags() : m_flags(lldb::eTypeOptionCascade) {} + Flags() {} Flags(const Flags &other) : m_flags(other.m_flags) {} @@ -104,7 +104,7 @@ public: void SetValue(uint32_t value) { m_flags = value; } private: - uint32_t m_flags; + uint32_t m_flags = lldb::eTypeOptionCascade; }; TypeFormatImpl(const Flags &flags = Flags()); @@ -149,7 +149,7 @@ public: protected: Flags m_flags; - uint32_t m_my_revision; + uint32_t m_my_revision = 0; private: TypeFormatImpl(const TypeFormatImpl &) = delete; diff --git a/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeSummary.h b/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeSummary.h index ce3195dbb693..30bc8cbf3feb 100644 --- a/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeSummary.h +++ b/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeSummary.h @@ -9,7 +9,7 @@ #ifndef LLDB_DATAFORMATTERS_TYPESUMMARY_H #define LLDB_DATAFORMATTERS_TYPESUMMARY_H -#include <stdint.h> +#include <cstdint> #include <functional> #include <memory> @@ -38,8 +38,8 @@ public: TypeSummaryOptions &SetCapping(lldb::TypeSummaryCapping); private: - lldb::LanguageType m_lang; - lldb::TypeSummaryCapping m_capping; + lldb::LanguageType m_lang = lldb::eLanguageTypeUnknown; + lldb::TypeSummaryCapping m_capping = lldb::eTypeSummaryCapped; }; class TypeSummaryImpl { @@ -52,7 +52,7 @@ public: class Flags { public: - Flags() : m_flags(lldb::eTypeOptionCascade) {} + Flags() = default; Flags(const Flags &other) : m_flags(other.m_flags) {} @@ -196,7 +196,7 @@ public: void SetValue(uint32_t value) { m_flags = value; } private: - uint32_t m_flags; + uint32_t m_flags = lldb::eTypeOptionCascade; }; bool Cascades() const { return m_flags.GetCascades(); } diff --git a/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeSynthetic.h b/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeSynthetic.h index fa1458281f1e..24322bd51a0c 100644 --- a/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeSynthetic.h +++ b/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeSynthetic.h @@ -9,7 +9,7 @@ #ifndef LLDB_DATAFORMATTERS_TYPESYNTHETIC_H #define LLDB_DATAFORMATTERS_TYPESYNTHETIC_H -#include <stdint.h> +#include <cstdint> #include <functional> #include <initializer_list> @@ -133,7 +133,7 @@ class SyntheticChildren { public: class Flags { public: - Flags() : m_flags(lldb::eTypeOptionCascade) {} + Flags() = default; Flags(const Flags &other) : m_flags(other.m_flags) {} @@ -225,7 +225,7 @@ public: void SetValue(uint32_t value) { m_flags = value; } private: - uint32_t m_flags; + uint32_t m_flags = lldb::eTypeOptionCascade; }; SyntheticChildren(const Flags &flags) : m_flags(flags) {} diff --git a/contrib/llvm-project/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h b/contrib/llvm-project/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h index f1301d8595b1..833cd5eea356 100644 --- a/contrib/llvm-project/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h +++ b/contrib/llvm-project/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h @@ -27,7 +27,7 @@ public: ValueObjectPrinter(ValueObject *valobj, Stream *s, const DumpValueObjectOptions &options); - ~ValueObjectPrinter() {} + ~ValueObjectPrinter() = default; bool PrintValueObject(); diff --git a/contrib/llvm-project/lldb/include/lldb/Expression/DWARFExpression.h b/contrib/llvm-project/lldb/include/lldb/Expression/DWARFExpression.h index c7d4e4b1882f..1490ac2d614a 100644 --- a/contrib/llvm-project/lldb/include/lldb/Expression/DWARFExpression.h +++ b/contrib/llvm-project/lldb/include/lldb/Expression/DWARFExpression.h @@ -250,10 +250,10 @@ private: /// The DWARF compile unit this expression belongs to. It is used to evaluate /// values indexing into the .debug_addr section (e.g. DW_OP_GNU_addr_index, /// DW_OP_GNU_const_index) - const DWARFUnit *m_dwarf_cu; + const DWARFUnit *m_dwarf_cu = nullptr; /// One of the defines that starts with LLDB_REGKIND_ - lldb::RegisterKind m_reg_kind; + lldb::RegisterKind m_reg_kind = lldb::eRegisterKindDWARF; struct LoclistAddresses { lldb::addr_t cu_file_addr; diff --git a/contrib/llvm-project/lldb/include/lldb/Expression/Expression.h b/contrib/llvm-project/lldb/include/lldb/Expression/Expression.h index aaac889e6ed2..b4207de958e9 100644 --- a/contrib/llvm-project/lldb/include/lldb/Expression/Expression.h +++ b/contrib/llvm-project/lldb/include/lldb/Expression/Expression.h @@ -39,7 +39,7 @@ public: Expression(ExecutionContextScope &exe_scope); /// Destructor - virtual ~Expression() {} + virtual ~Expression() = default; /// Return the string that the parser should parse. Must be a full /// translation unit. diff --git a/contrib/llvm-project/lldb/include/lldb/Expression/ExpressionParser.h b/contrib/llvm-project/lldb/include/lldb/Expression/ExpressionParser.h index 71d2410ea7c3..ab5223c91553 100644 --- a/contrib/llvm-project/lldb/include/lldb/Expression/ExpressionParser.h +++ b/contrib/llvm-project/lldb/include/lldb/Expression/ExpressionParser.h @@ -41,7 +41,7 @@ public: : m_expr(expr), m_generate_debug_info(generate_debug_info) {} /// Destructor - virtual ~ExpressionParser(){}; + virtual ~ExpressionParser() = default; /// Attempts to find possible command line completions for the given /// expression. diff --git a/contrib/llvm-project/lldb/include/lldb/Expression/ExpressionTypeSystemHelper.h b/contrib/llvm-project/lldb/include/lldb/Expression/ExpressionTypeSystemHelper.h index 1bba30ad8620..2ba675db8662 100644 --- a/contrib/llvm-project/lldb/include/lldb/Expression/ExpressionTypeSystemHelper.h +++ b/contrib/llvm-project/lldb/include/lldb/Expression/ExpressionTypeSystemHelper.h @@ -36,7 +36,7 @@ public: ExpressionTypeSystemHelper(LLVMCastKind kind) : m_kind(kind) {} - ~ExpressionTypeSystemHelper() {} + ~ExpressionTypeSystemHelper() = default; protected: LLVMCastKind m_kind; diff --git a/contrib/llvm-project/lldb/include/lldb/Expression/ExpressionVariable.h b/contrib/llvm-project/lldb/include/lldb/Expression/ExpressionVariable.h index 4259e6395da4..de700b676611 100644 --- a/contrib/llvm-project/lldb/include/lldb/Expression/ExpressionVariable.h +++ b/contrib/llvm-project/lldb/include/lldb/Expression/ExpressionVariable.h @@ -48,7 +48,7 @@ public: void SetRegisterInfo(const RegisterInfo *reg_info) { return m_frozen_sp->GetValue().SetContext( - Value::eContextTypeRegisterInfo, const_cast<RegisterInfo *>(reg_info)); + Value::ContextType::RegisterInfo, const_cast<RegisterInfo *>(reg_info)); } CompilerType GetCompilerType() { return m_frozen_sp->GetCompilerType(); } diff --git a/contrib/llvm-project/lldb/include/lldb/Expression/Materializer.h b/contrib/llvm-project/lldb/include/lldb/Expression/Materializer.h index 754e67c5dfa7..25cf22a8b5b0 100644 --- a/contrib/llvm-project/lldb/include/lldb/Expression/Materializer.h +++ b/contrib/llvm-project/lldb/include/lldb/Expression/Materializer.h @@ -90,7 +90,7 @@ public: class Entity { public: - Entity() : m_alignment(1), m_size(0), m_offset(0) {} + Entity() = default; virtual ~Entity() = default; @@ -113,9 +113,9 @@ public: void SetOffset(uint32_t offset) { m_offset = offset; } protected: - uint32_t m_alignment; - uint32_t m_size; - uint32_t m_offset; + uint32_t m_alignment = 1; + uint32_t m_size = 0; + uint32_t m_offset = 0; }; private: diff --git a/contrib/llvm-project/lldb/include/lldb/Expression/UtilityFunction.h b/contrib/llvm-project/lldb/include/lldb/Expression/UtilityFunction.h index 99fb32153aa2..6b558b20e212 100644 --- a/contrib/llvm-project/lldb/include/lldb/Expression/UtilityFunction.h +++ b/contrib/llvm-project/lldb/include/lldb/Expression/UtilityFunction.h @@ -42,8 +42,11 @@ public: /// /// \param[in] name /// The name of the function, as used in the text. + /// + /// \param[in] enable_debugging + /// Enable debugging of this function. UtilityFunction(ExecutionContextScope &exe_scope, std::string text, - std::string name); + std::string name, bool enable_debugging); ~UtilityFunction() override; diff --git a/contrib/llvm-project/lldb/include/lldb/Host/Debug.h b/contrib/llvm-project/lldb/include/lldb/Host/Debug.h index 402325c4c166..7da59dd04a66 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/Debug.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/Debug.h @@ -144,6 +144,12 @@ struct ThreadStopInfo { uint32_t data_count; lldb::addr_t data[8]; } exception; + + // eStopReasonFork / eStopReasonVFork + struct { + lldb::pid_t child_pid; + lldb::tid_t child_tid; + } fork; } details; }; } diff --git a/contrib/llvm-project/lldb/include/lldb/Host/Editline.h b/contrib/llvm-project/lldb/include/lldb/Host/Editline.h index a37ad1b9d106..876f6052311e 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/Editline.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/Editline.h @@ -38,12 +38,9 @@ #include <sstream> #include <vector> -#include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/lldb-private.h" -#if defined(_WIN32) -#include "lldb/Host/windows/editlinewin.h" -#elif !defined(__ANDROID__) +#if !defined(_WIN32) && !defined(__ANDROID__) #include <histedit.h> #endif @@ -56,6 +53,9 @@ #include "lldb/Utility/CompletionRequest.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Predicate.h" +#include "lldb/Utility/StringList.h" + +#include "llvm/ADT/FunctionExtras.h" namespace lldb_private { namespace line_editor { @@ -81,27 +81,26 @@ using EditLineGetCharType = wchar_t; using EditLineGetCharType = char; #endif -typedef int (*EditlineGetCharCallbackType)(::EditLine *editline, - EditLineGetCharType *c); -typedef unsigned char (*EditlineCommandCallbackType)(::EditLine *editline, - int ch); -typedef const char *(*EditlinePromptCallbackType)(::EditLine *editline); +using EditlineGetCharCallbackType = int (*)(::EditLine *editline, + EditLineGetCharType *c); +using EditlineCommandCallbackType = unsigned char (*)(::EditLine *editline, + int ch); +using EditlinePromptCallbackType = const char *(*)(::EditLine *editline); class EditlineHistory; -typedef std::shared_ptr<EditlineHistory> EditlineHistorySP; +using EditlineHistorySP = std::shared_ptr<EditlineHistory>; -typedef bool (*IsInputCompleteCallbackType)(Editline *editline, - StringList &lines, void *baton); +using IsInputCompleteCallbackType = + llvm::unique_function<bool(Editline *, StringList &)>; -typedef int (*FixIndentationCallbackType)(Editline *editline, - const StringList &lines, - int cursor_position, void *baton); +using FixIndentationCallbackType = + llvm::unique_function<int(Editline *, StringList &, int)>; -typedef llvm::Optional<std::string> (*SuggestionCallbackType)( - llvm::StringRef line, void *baton); +using SuggestionCallbackType = + llvm::unique_function<llvm::Optional<std::string>(llvm::StringRef)>; -typedef void (*CompleteCallbackType)(CompletionRequest &request, void *baton); +using CompleteCallbackType = llvm::unique_function<void(CompletionRequest &)>; /// Status used to decide when and how to start editing another line in /// multi-line sessions @@ -188,21 +187,28 @@ public: bool Cancel(); /// Register a callback for autosuggestion. - void SetSuggestionCallback(SuggestionCallbackType callback, void *baton); + void SetSuggestionCallback(SuggestionCallbackType callback) { + m_suggestion_callback = std::move(callback); + } /// Register a callback for the tab key - void SetAutoCompleteCallback(CompleteCallbackType callback, void *baton); + void SetAutoCompleteCallback(CompleteCallbackType callback) { + m_completion_callback = std::move(callback); + } /// Register a callback for testing whether multi-line input is complete - void SetIsInputCompleteCallback(IsInputCompleteCallbackType callback, - void *baton); + void SetIsInputCompleteCallback(IsInputCompleteCallbackType callback) { + m_is_input_complete_callback = std::move(callback); + } /// Register a callback for determining the appropriate indentation for a line /// when creating a newline. An optional set of insertable characters can - /// also - /// trigger the callback. - bool SetFixIndentationCallback(FixIndentationCallbackType callback, - void *baton, const char *indent_chars); + /// also trigger the callback. + void SetFixIndentationCallback(FixIndentationCallbackType callback, + const char *indent_chars) { + m_fix_indentation_callback = std::move(callback); + m_fix_indentation_callback_chars = indent_chars; + } /// Prompts for and reads a single line of user input. bool GetLine(std::string &line, bool &interrupted); @@ -338,6 +344,16 @@ private: void ApplyTerminalSizeChange(); + // The following set various editline parameters. It's not any less + // verbose to put the editline calls into a function, but it + // provides type safety, since the editline functions take varargs + // parameters. + void AddFunctionToEditLine(const EditLineCharType *command, + const EditLineCharType *helptext, + EditlineCommandCallbackType callbackFn); + void SetEditLinePromptCallback(EditlinePromptCallbackType callbackFn); + void SetGetCharacterFunction(EditlineGetCharCallbackType callbackFn); + #if LLDB_EDITLINE_USE_WCHAR std::wstring_convert<std::codecvt_utf8<wchar_t>> m_utf8conv; #endif @@ -365,15 +381,16 @@ private: FILE *m_output_file; FILE *m_error_file; ConnectionFileDescriptor m_input_connection; - IsInputCompleteCallbackType m_is_input_complete_callback = nullptr; - void *m_is_input_complete_callback_baton = nullptr; - FixIndentationCallbackType m_fix_indentation_callback = nullptr; - void *m_fix_indentation_callback_baton = nullptr; + + IsInputCompleteCallbackType m_is_input_complete_callback; + + FixIndentationCallbackType m_fix_indentation_callback; 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; + + CompleteCallbackType m_completion_callback; + + SuggestionCallbackType m_suggestion_callback; + std::size_t m_previous_autosuggestion_size = 0; std::mutex m_output_mutex; }; diff --git a/contrib/llvm-project/lldb/include/lldb/Host/File.h b/contrib/llvm-project/lldb/include/lldb/Host/File.h index d205a3fe6911..d364d954a1c1 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/File.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/File.h @@ -15,9 +15,9 @@ #include "lldb/lldb-private.h" #include "llvm/ADT/BitmaskEnum.h" +#include <cstdarg> +#include <cstdio> #include <mutex> -#include <stdarg.h> -#include <stdio.h> #include <sys/types.h> namespace lldb_private { @@ -65,10 +65,7 @@ public: static llvm::Expected<const char *> GetStreamOpenModeFromOptions(OpenOptions options); - File() - : IOObject(eFDTypeFile), m_is_interactive(eLazyBoolCalculate), - m_is_real_terminal(eLazyBoolCalculate), - m_supports_colors(eLazyBoolCalculate){}; + File() : IOObject(eFDTypeFile){}; /// Read bytes from a file from the current file position into buf. /// @@ -360,9 +357,9 @@ public: static bool classof(const File *file) { return file->isA(&ID); } protected: - LazyBool m_is_interactive; - LazyBool m_is_real_terminal; - LazyBool m_supports_colors; + LazyBool m_is_interactive = eLazyBoolCalculate; + LazyBool m_is_real_terminal = eLazyBoolCalculate; + LazyBool m_supports_colors = eLazyBoolCalculate; void CalculateInteractiveAndTerminal(); @@ -373,9 +370,7 @@ private: class NativeFile : public File { public: - NativeFile() - : m_descriptor(kInvalidDescriptor), m_own_descriptor(false), - m_stream(kInvalidStream), m_options(), m_own_stream(false) {} + NativeFile() : m_descriptor(kInvalidDescriptor), m_stream(kInvalidStream) {} NativeFile(FILE *fh, bool transfer_ownership) : m_descriptor(kInvalidDescriptor), m_own_descriptor(false), m_stream(fh), @@ -422,10 +417,10 @@ protected: // Member variables int m_descriptor; - bool m_own_descriptor; + bool m_own_descriptor = false; FILE *m_stream; - OpenOptions m_options; - bool m_own_stream; + OpenOptions m_options{}; + bool m_own_stream = false; std::mutex offset_access_mutex; private: diff --git a/contrib/llvm-project/lldb/include/lldb/Host/FileAction.h b/contrib/llvm-project/lldb/include/lldb/Host/FileAction.h index 4d333bb327a5..d3166c16a585 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/FileAction.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/FileAction.h @@ -46,9 +46,9 @@ public: void Dump(Stream &stream) const; protected: - Action m_action; // The action for this file - int m_fd; // An existing file descriptor - int m_arg; // oflag for eFileActionOpen*, dup_fd for eFileActionDuplicate + Action m_action = eFileActionNone; // The action for this file + int m_fd = -1; // An existing file descriptor + int m_arg = -1; // oflag for eFileActionOpen*, dup_fd for eFileActionDuplicate FileSpec m_file_spec; // A file spec to use for opening after fork or posix_spawn }; diff --git a/contrib/llvm-project/lldb/include/lldb/Host/FileCache.h b/contrib/llvm-project/lldb/include/lldb/Host/FileCache.h index df0d9a88c6df..1bf5f0ca80e2 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/FileCache.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/FileCache.h @@ -8,8 +8,8 @@ #ifndef LLDB_HOST_FILECACHE_H #define LLDB_HOST_FILECACHE_H +#include <cstdint> #include <map> -#include <stdint.h> #include "lldb/lldb-forward.h" #include "lldb/lldb-types.h" @@ -21,7 +21,7 @@ namespace lldb_private { class FileCache { private: - FileCache() {} + FileCache() = default; typedef std::map<lldb::user_id_t, lldb::FileUP> FDToFileMap; diff --git a/contrib/llvm-project/lldb/include/lldb/Host/FileSystem.h b/contrib/llvm-project/lldb/include/lldb/Host/FileSystem.h index 02ff5f301336..93563d4d26e3 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/FileSystem.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/FileSystem.h @@ -21,8 +21,8 @@ #include "lldb/lldb-types.h" -#include <stdint.h> -#include <stdio.h> +#include <cstdint> +#include <cstdio> #include <sys/stat.h> namespace lldb_private { @@ -33,7 +33,7 @@ public: FileSystem() : m_fs(llvm::vfs::getRealFileSystem()), m_collector(nullptr), - m_home_directory(), m_mapped(false) {} + m_home_directory() {} FileSystem(std::shared_ptr<llvm::FileCollectorBase> collector) : m_fs(llvm::vfs::getRealFileSystem()), m_collector(std::move(collector)), m_home_directory(), m_mapped(false) {} @@ -201,7 +201,7 @@ private: llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> m_fs; std::shared_ptr<llvm::FileCollectorBase> m_collector; std::string m_home_directory; - bool m_mapped; + bool m_mapped = false; }; } // 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 76792cc6eab5..1fdf7eab7eb8 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/Host.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/Host.h @@ -17,8 +17,8 @@ #include "lldb/lldb-private-forward.h" #include "lldb/lldb-private.h" #include <cerrno> +#include <cstdarg> #include <map> -#include <stdarg.h> #include <string> #include <type_traits> diff --git a/contrib/llvm-project/lldb/include/lldb/Host/HostInfoBase.h b/contrib/llvm-project/lldb/include/lldb/Host/HostInfoBase.h index 15bb168aad97..eeed881101d0 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/HostInfoBase.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/HostInfoBase.h @@ -17,7 +17,7 @@ #include "lldb/lldb-enumerations.h" #include "llvm/ADT/StringRef.h" -#include <stdint.h> +#include <cstdint> #include <string> @@ -33,11 +33,17 @@ struct SharedCacheImageInfo { class HostInfoBase { private: // Static class, unconstructable. - HostInfoBase() {} - ~HostInfoBase() {} + HostInfoBase() = default; + ~HostInfoBase() = default; public: - static void Initialize(); + /// A helper function for determining the liblldb location. It receives a + /// FileSpec with the location of file containing _this_ code. It can + /// (optionally) replace it with a file spec pointing to a more canonical + /// copy. + using SharedLibraryDirectoryHelper = void(FileSpec &this_file); + + static void Initialize(SharedLibraryDirectoryHelper *helper = nullptr); static void Terminate(); /// Gets the host target triple. diff --git a/contrib/llvm-project/lldb/include/lldb/Host/HostNativeProcessBase.h b/contrib/llvm-project/lldb/include/lldb/Host/HostNativeProcessBase.h index 642c63443c20..5469f8a50e26 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/HostNativeProcessBase.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/HostNativeProcessBase.h @@ -27,7 +27,7 @@ public: HostNativeProcessBase() : m_process(LLDB_INVALID_PROCESS) {} explicit HostNativeProcessBase(lldb::process_t process) : m_process(process) {} - virtual ~HostNativeProcessBase() {} + virtual ~HostNativeProcessBase() = default; virtual Status Terminate() = 0; virtual Status GetMainModule(FileSpec &file_spec) const = 0; diff --git a/contrib/llvm-project/lldb/include/lldb/Host/HostNativeThreadBase.h b/contrib/llvm-project/lldb/include/lldb/Host/HostNativeThreadBase.h index 0dfd363cc8fb..bfd70d745593 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/HostNativeThreadBase.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/HostNativeThreadBase.h @@ -27,9 +27,9 @@ class HostNativeThreadBase { const HostNativeThreadBase &operator=(const HostNativeThreadBase &) = delete; public: - HostNativeThreadBase(); + HostNativeThreadBase() = default; explicit HostNativeThreadBase(lldb::thread_t thread); - virtual ~HostNativeThreadBase() {} + virtual ~HostNativeThreadBase() = default; virtual Status Join(lldb::thread_result_t *result) = 0; virtual Status Cancel() = 0; @@ -45,8 +45,8 @@ protected: static lldb::thread_result_t THREAD_ROUTINE ThreadCreateTrampoline(lldb::thread_arg_t arg); - lldb::thread_t m_thread; - lldb::thread_result_t m_result; + lldb::thread_t m_thread = LLDB_INVALID_HOST_THREAD; + lldb::thread_result_t m_result = 0; }; } diff --git a/contrib/llvm-project/lldb/include/lldb/Host/MainLoop.h b/contrib/llvm-project/lldb/include/lldb/Host/MainLoop.h index 9ca5040b60a8..06785bbdbe24 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/MainLoop.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/MainLoop.h @@ -13,6 +13,7 @@ #include "lldb/Host/MainLoopBase.h" #include "llvm/ADT/DenseMap.h" #include <csignal> +#include <list> #if !HAVE_PPOLL && !HAVE_SYS_EVENT_H && !defined(__ANDROID__) #define SIGNAL_POLLING_UNSUPPORTED 1 @@ -68,7 +69,7 @@ public: protected: void UnregisterReadObject(IOObject::WaitableHandle handle) override; - void UnregisterSignal(int signo); + void UnregisterSignal(int signo, std::list<Callback>::iterator callback_it); private: void ProcessReadObject(IOObject::WaitableHandle handle); @@ -76,14 +77,16 @@ private: class SignalHandle { public: - ~SignalHandle() { m_mainloop.UnregisterSignal(m_signo); } + ~SignalHandle() { m_mainloop.UnregisterSignal(m_signo, m_callback_it); } private: - SignalHandle(MainLoop &mainloop, int signo) - : m_mainloop(mainloop), m_signo(signo) {} + SignalHandle(MainLoop &mainloop, int signo, + std::list<Callback>::iterator callback_it) + : m_mainloop(mainloop), m_signo(signo), m_callback_it(callback_it) {} MainLoop &m_mainloop; int m_signo; + std::list<Callback>::iterator m_callback_it; friend class MainLoop; SignalHandle(const SignalHandle &) = delete; @@ -91,7 +94,7 @@ private: }; struct SignalInfo { - Callback callback; + std::list<Callback> callbacks; #if HAVE_SIGACTION struct sigaction old_action; #endif diff --git a/contrib/llvm-project/lldb/include/lldb/Host/MainLoopBase.h b/contrib/llvm-project/lldb/include/lldb/Host/MainLoopBase.h index fa8cc77a94ba..67857b26ac70 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/MainLoopBase.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/MainLoopBase.h @@ -33,8 +33,8 @@ private: class ReadHandle; public: - MainLoopBase() {} - virtual ~MainLoopBase() {} + MainLoopBase() = default; + virtual ~MainLoopBase() = default; typedef std::unique_ptr<ReadHandle> ReadHandleUP; diff --git a/contrib/llvm-project/lldb/include/lldb/Host/ProcessLaunchInfo.h b/contrib/llvm-project/lldb/include/lldb/Host/ProcessLaunchInfo.h index ee9755580825..3ed21637de7f 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/ProcessLaunchInfo.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/ProcessLaunchInfo.h @@ -20,6 +20,7 @@ #include "lldb/Host/PseudoTerminal.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/ProcessInfo.h" +#include "lldb/Utility/StructuredData.h" namespace lldb_private { @@ -146,6 +147,28 @@ public: return m_flags.Test(lldb::eLaunchFlagDetachOnError); } + bool IsScriptedProcess() const { + return !m_scripted_process_class_name.empty(); + } + + std::string GetScriptedProcessClassName() const { + return m_scripted_process_class_name; + } + + void SetScriptedProcessClassName(std::string name) { + m_scripted_process_class_name = name; + } + + lldb_private::StructuredData::DictionarySP + GetScriptedProcessDictionarySP() const { + return m_scripted_process_dictionary_sp; + } + + void SetScriptedProcessDictionarySP( + lldb_private::StructuredData::DictionarySP dictionary_sp) { + m_scripted_process_dictionary_sp = dictionary_sp; + } + protected: FileSpec m_working_dir; std::string m_plugin_name; @@ -153,14 +176,19 @@ protected: Flags m_flags; // Bitwise OR of bits from lldb::LaunchFlags std::vector<FileAction> m_file_actions; // File actions for any other files std::shared_ptr<PseudoTerminal> m_pty; - uint32_t m_resume_count; // How many times do we resume after launching + uint32_t m_resume_count = 0; // How many times do we resume after launching Host::MonitorChildProcessCallback m_monitor_callback; - void *m_monitor_callback_baton; - bool m_monitor_signals; + void *m_monitor_callback_baton = nullptr; + bool m_monitor_signals = false; std::string m_event_data; // A string passed to the plugin launch, having no // meaning to the upper levels of lldb. lldb::ListenerSP m_listener_sp; lldb::ListenerSP m_hijack_listener_sp; + std::string m_scripted_process_class_name; // The name of the class that will + // manage a scripted process. + StructuredData::DictionarySP + m_scripted_process_dictionary_sp; // A dictionary that holds key/value + // pairs passed to the scripted process. }; } diff --git a/contrib/llvm-project/lldb/include/lldb/Host/ProcessLauncher.h b/contrib/llvm-project/lldb/include/lldb/Host/ProcessLauncher.h index 9467b2c009b7..33dbfd72d1e5 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/ProcessLauncher.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/ProcessLauncher.h @@ -17,7 +17,7 @@ class HostProcess; class ProcessLauncher { public: - virtual ~ProcessLauncher() {} + virtual ~ProcessLauncher() = default; virtual HostProcess LaunchProcess(const ProcessLaunchInfo &launch_info, Status &error) = 0; }; diff --git a/contrib/llvm-project/lldb/include/lldb/Host/ProcessRunLock.h b/contrib/llvm-project/lldb/include/lldb/Host/ProcessRunLock.h index 43463d144de3..b5b5328b4a33 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/ProcessRunLock.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/ProcessRunLock.h @@ -9,8 +9,8 @@ #ifndef LLDB_HOST_PROCESSRUNLOCK_H #define LLDB_HOST_PROCESSRUNLOCK_H -#include <stdint.h> -#include <time.h> +#include <cstdint> +#include <ctime> #include "lldb/lldb-defines.h" @@ -35,7 +35,7 @@ public: class ProcessRunLocker { public: - ProcessRunLocker() : m_lock(nullptr) {} + ProcessRunLocker() = default; ~ProcessRunLocker() { Unlock(); } @@ -64,7 +64,7 @@ public: } } - ProcessRunLock *m_lock; + ProcessRunLock *m_lock = nullptr; private: ProcessRunLocker(const ProcessRunLocker &) = delete; @@ -73,7 +73,7 @@ public: protected: lldb::rwlock_t m_rwlock; - bool m_running; + bool m_running = false; private: ProcessRunLock(const ProcessRunLock &) = delete; diff --git a/contrib/llvm-project/lldb/include/lldb/Host/PseudoTerminal.h b/contrib/llvm-project/lldb/include/lldb/Host/PseudoTerminal.h index 350f926dcac1..bd1e2f56241b 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/PseudoTerminal.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/PseudoTerminal.h @@ -175,8 +175,8 @@ public: protected: // Member variables - int m_primary_fd; ///< The file descriptor for the primary. - int m_secondary_fd; ///< The file descriptor for the secondary. + int m_primary_fd = invalid_fd; ///< The file descriptor for the primary. + int m_secondary_fd = invalid_fd; ///< The file descriptor for the secondary. private: PseudoTerminal(const PseudoTerminal &) = delete; diff --git a/contrib/llvm-project/lldb/include/lldb/Host/SafeMachO.h b/contrib/llvm-project/lldb/include/lldb/Host/SafeMachO.h index d7c376d23a4a..0540383b8c52 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/SafeMachO.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/SafeMachO.h @@ -23,6 +23,7 @@ #undef CPU_ARCH_MASK #undef CPU_ARCH_ABI64 +#undef CPU_ARCH_ABI64_32 #undef CPU_TYPE_ANY #undef CPU_TYPE_X86 @@ -31,12 +32,13 @@ #undef CPU_TYPE_MC98000 #undef CPU_TYPE_ARM #undef CPU_TYPE_ARM64 +#undef CPU_TYPE_ARM64_32 #undef CPU_TYPE_SPARC #undef CPU_TYPE_POWERPC #undef CPU_TYPE_POWERPC64 -#undef CPU_SUB_TYPE_MASK -#undef CPU_SUB_TYPE_LIB64 +#undef CPU_SUBTYPE_MASK +#undef CPU_SUBTYPE_LIB64 #undef CPU_SUBTYPE_MULTIPLE @@ -88,6 +90,9 @@ #undef CPU_SUBTYPE_ARM_V7M #undef CPU_SUBTYPE_ARM_V7EM +#undef CPU_SUBTYPE_ARM64E +#undef CPU_SUBTYPE_ARM64_32_V8 +#undef CPU_SUBTYPE_ARM64_V8 #undef CPU_SUBTYPE_ARM64_ALL #undef CPU_SUBTYPE_SPARC_ALL @@ -110,6 +115,47 @@ #undef CPU_SUBTYPE_MC980000_ALL #undef CPU_SUBTYPE_MC98601 +#undef VM_PROT_READ +#undef VM_PROT_WRITE +#undef VM_PROT_EXECUTE + +#undef ARM_DEBUG_STATE +#undef ARM_EXCEPTION_STATE +#undef ARM_EXCEPTION_STATE64 +#undef ARM_EXCEPTION_STATE64_COUNT +#undef ARM_THREAD_STATE +#undef ARM_THREAD_STATE64 +#undef ARM_THREAD_STATE64_COUNT +#undef ARM_THREAD_STATE_COUNT +#undef ARM_VFP_STATE +#undef ARN_THREAD_STATE_NONE +#undef PPC_EXCEPTION_STATE +#undef PPC_EXCEPTION_STATE64 +#undef PPC_FLOAT_STATE +#undef PPC_THREAD_STATE +#undef PPC_THREAD_STATE64 +#undef PPC_THREAD_STATE_NONE +#undef PPC_VECTOR_STATE +#undef x86_DEBUG_STATE +#undef x86_DEBUG_STATE32 +#undef x86_DEBUG_STATE64 +#undef x86_EXCEPTION_STATE +#undef x86_EXCEPTION_STATE32 +#undef x86_EXCEPTION_STATE64 +#undef x86_EXCEPTION_STATE64_COUNT +#undef x86_EXCEPTION_STATE_COUNT +#undef x86_FLOAT_STATE +#undef x86_FLOAT_STATE32 +#undef x86_FLOAT_STATE64 +#undef x86_FLOAT_STATE64_COUNT +#undef x86_FLOAT_STATE_COUNT +#undef x86_THREAD_STATE +#undef x86_THREAD_STATE32 +#undef x86_THREAD_STATE32_COUNT +#undef x86_THREAD_STATE64 +#undef x86_THREAD_STATE64_COUNT +#undef x86_THREAD_STATE_COUNT + #include "llvm/BinaryFormat/MachO.h" #endif // LLDB_HOST_SAFEMACHO_H diff --git a/contrib/llvm-project/lldb/include/lldb/Host/SocketAddress.h b/contrib/llvm-project/lldb/include/lldb/Host/SocketAddress.h index 862e1104a084..c88cc1260654 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/SocketAddress.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/SocketAddress.h @@ -9,7 +9,7 @@ #ifndef LLDB_HOST_SOCKETADDRESS_H #define LLDB_HOST_SOCKETADDRESS_H -#include <stdint.h> +#include <cstdint> #ifdef _WIN32 #include "lldb/Host/windows/windows.h" diff --git a/contrib/llvm-project/lldb/include/lldb/Host/StringConvert.h b/contrib/llvm-project/lldb/include/lldb/Host/StringConvert.h index ad629ff30429..33608a85ff42 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/StringConvert.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/StringConvert.h @@ -9,9 +9,7 @@ #ifndef LLDB_HOST_STRINGCONVERT_H #define LLDB_HOST_STRINGCONVERT_H -#include <stdint.h> - - +#include <cstdint> namespace lldb_private { diff --git a/contrib/llvm-project/lldb/include/lldb/Host/Terminal.h b/contrib/llvm-project/lldb/include/lldb/Host/Terminal.h index 61993223ea06..ca91d6b59720 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/Terminal.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/Terminal.h @@ -21,7 +21,7 @@ class Terminal { public: Terminal(int fd = -1) : m_fd(fd) {} - ~Terminal() {} + ~Terminal() = default; bool IsATerminal() const; @@ -116,12 +116,12 @@ protected: // Member variables Terminal m_tty; ///< A terminal - int m_tflags; ///< Cached tflags information. + int m_tflags = -1; ///< Cached tflags information. #if LLDB_ENABLE_TERMIOS std::unique_ptr<struct termios> m_termios_up; ///< Cached terminal state information. #endif - lldb::pid_t m_process_group; ///< Cached process group information. + lldb::pid_t m_process_group = -1; ///< Cached process group information. }; /// \class TerminalStateSwitcher Terminal.h "lldb/Host/Terminal.h" @@ -171,7 +171,8 @@ public: protected: // Member variables - mutable uint32_t m_currentState; ///< The currently active TTY state index. + mutable uint32_t m_currentState = + UINT32_MAX; ///< The currently active TTY state index. TerminalState m_ttystates[2]; ///< The array of TTY states that holds saved TTY info. }; diff --git a/contrib/llvm-project/lldb/include/lldb/Host/Time.h b/contrib/llvm-project/lldb/include/lldb/Host/Time.h index 83b76ec0f9d1..aee4c43247c5 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/Time.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/Time.h @@ -19,7 +19,7 @@ #include <time64.h> extern time_t timegm(struct tm *t); #else -#include <time.h> +#include <ctime> #endif #endif // LLDB_HOST_TIME_H diff --git a/contrib/llvm-project/lldb/include/lldb/Host/XML.h b/contrib/llvm-project/lldb/include/lldb/Host/XML.h index a80f1e9e4d26..9edf46bf09df 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/XML.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/XML.h @@ -107,7 +107,7 @@ public: void ForEachAttribute(AttributeCallback const &callback) const; protected: - XMLNodeImpl m_node; + XMLNodeImpl m_node = nullptr; }; class XMLDocument { @@ -138,7 +138,7 @@ public: static bool XMLEnabled(); protected: - XMLDocumentImpl m_document; + XMLDocumentImpl m_document = nullptr; StreamString m_errors; }; 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 5be9cb657382..770149e3fb28 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/common/NativeProcessProtocol.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/common/NativeProcessProtocol.h @@ -16,7 +16,7 @@ #include "lldb/Host/MainLoop.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/Status.h" -#include "lldb/Utility/TraceOptions.h" +#include "lldb/Utility/TraceGDBRemotePackets.h" #include "lldb/Utility/UnimplementedError.h" #include "lldb/lldb-private-forward.h" #include "lldb/lldb-types.h" @@ -30,6 +30,8 @@ #include <vector> namespace lldb_private { +LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); + class MemoryRegionInfo; class ResumeActionList; @@ -44,7 +46,7 @@ struct SVR4LibraryInfo { // NativeProcessProtocol class NativeProcessProtocol { public: - virtual ~NativeProcessProtocol() {} + virtual ~NativeProcessProtocol() = default; virtual Status Resume(const ResumeActionList &resume_actions) = 0; @@ -85,6 +87,12 @@ public: Status ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read); + virtual Status ReadMemoryTags(int32_t type, lldb::addr_t addr, size_t len, + std::vector<uint8_t> &tags); + + virtual Status WriteMemoryTags(int32_t type, lldb::addr_t addr, size_t len, + const std::vector<uint8_t> &tags); + /// Reads a null terminated string from memory. /// /// Reads up to \p max_size bytes of memory until it finds a '\0'. @@ -212,7 +220,7 @@ public: // Callbacks for low-level process state changes class NativeDelegate { public: - virtual ~NativeDelegate() {} + virtual ~NativeDelegate() = default; virtual void InitializeDelegate(NativeProcessProtocol *process) = 0; @@ -220,37 +228,11 @@ public: lldb::StateType state) = 0; virtual void DidExec(NativeProcessProtocol *process) = 0; - }; - - /// Register a native delegate. - /// - /// Clients can register nofication callbacks by passing in a - /// NativeDelegate impl and passing it into this function. - /// - /// Note: it is required that the lifetime of the - /// native_delegate outlive the NativeProcessProtocol. - /// - /// \param[in] native_delegate - /// A NativeDelegate impl to be called when certain events - /// happen within the NativeProcessProtocol or related threads. - /// - /// \return - /// true if the delegate was registered successfully; - /// false if the delegate was already registered. - /// - /// \see NativeProcessProtocol::NativeDelegate. - bool RegisterNativeDelegate(NativeDelegate &native_delegate); - /// Unregister a native delegate previously registered. - /// - /// \param[in] native_delegate - /// A NativeDelegate impl previously registered with this process. - /// - /// \return Returns \b true if the NativeDelegate was - /// successfully removed from the process, \b false otherwise. - /// - /// \see NativeProcessProtocol::NativeDelegate - bool UnregisterNativeDelegate(NativeDelegate &native_delegate); + virtual void + NewSubprocess(NativeProcessProtocol *parent_process, + std::unique_ptr<NativeProcessProtocol> child_process) = 0; + }; virtual Status GetLoadedModuleFileSpec(const char *module_path, FileSpec &file_spec) = 0; @@ -258,6 +240,20 @@ public: virtual Status GetFileLoadAddress(const llvm::StringRef &file_name, lldb::addr_t &load_addr) = 0; + /// Extension flag constants, returned by Factory::GetSupportedExtensions() + /// and passed to SetEnabledExtension() + enum class Extension { + multiprocess = (1u << 0), + fork = (1u << 1), + vfork = (1u << 2), + pass_signals = (1u << 3), + auxv = (1u << 4), + libraries_svr4 = (1u << 5), + memory_tagging = (1u << 6), + + LLVM_MARK_AS_BITMASK_ENUM(memory_tagging) + }; + class Factory { public: virtual ~Factory(); @@ -304,99 +300,75 @@ public: virtual llvm::Expected<std::unique_ptr<NativeProcessProtocol>> Attach(lldb::pid_t pid, NativeDelegate &native_delegate, MainLoop &mainloop) const = 0; + + /// Get the bitmask of extensions supported by this process plugin. + /// + /// \return + /// A NativeProcessProtocol::Extension bitmask. + virtual Extension GetSupportedExtensions() const { return {}; } }; - /// StartTracing API for starting a tracing instance with the - /// TraceOptions on a specific thread or process. + /// Start tracing a process or its threads. /// - /// \param[in] config - /// The configuration to use when starting tracing. + /// \param[in] json_params + /// JSON object with the information of what and how to trace. + /// In the case of gdb-remote, this object should conform to the + /// jLLDBTraceStart packet. /// - /// \param[out] error - /// Status indicates what went wrong. + /// This object should have a string entry called "type", which is the + /// tracing technology name. /// - /// \return - /// The API returns a user_id which can be used to get trace - /// data, trace configuration or stopping the trace instance. - /// The user_id is a key to identify and operate with a tracing - /// instance. It may refer to the complete process or a single - /// thread. - virtual lldb::user_id_t StartTrace(const TraceOptions &config, - Status &error) { - error.SetErrorString("Not implemented"); - return LLDB_INVALID_UID; - } - - /// StopTracing API as the name suggests stops a tracing instance. - /// - /// \param[in] traceid - /// The user id of the trace intended to be stopped. Now a - /// user_id may map to multiple threads in which case this API - /// could be used to stop the tracing for a specific thread by - /// supplying its thread id. - /// - /// \param[in] thread - /// Thread is needed when the complete process is being traced - /// and the user wishes to stop tracing on a particular thread. + /// \param[in] type + /// Tracing technology type, as described in the \a json_params. /// /// \return - /// Status indicating what went wrong. - virtual Status StopTrace(lldb::user_id_t traceid, - lldb::tid_t thread = LLDB_INVALID_THREAD_ID) { - return Status("Not implemented"); + /// \a llvm::Error::success if the operation was successful, or an + /// \a llvm::Error otherwise. + virtual llvm::Error TraceStart(llvm::StringRef json_params, + llvm::StringRef type) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Unsupported tracing type '%s'", + type.data()); } - /// This API provides the trace data collected in the form of raw - /// data. - /// - /// \param[in] traceid thread - /// The traceid and thread provide the context for the trace - /// instance. - /// - /// \param[in] buffer - /// The buffer provides the destination buffer where the trace - /// data would be read to. The buffer should be truncated to the - /// filled length by this function. - /// - /// \param[in] offset - /// There is possibility to read partially the trace data from - /// a specified offset where in such cases the buffer provided - /// may be smaller than the internal trace collection container. - /// - /// \return - /// The size of the data actually read. - virtual Status GetData(lldb::user_id_t traceid, lldb::tid_t thread, - llvm::MutableArrayRef<uint8_t> &buffer, - size_t offset = 0) { - return Status("Not implemented"); + /// \copydoc Process::TraceStop(const TraceStopRequest &) + virtual llvm::Error TraceStop(const TraceStopRequest &request) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Unsupported tracing type '%s'", + request.type.data()); } - /// Similar API as above except it aims to provide any extra data - /// useful for decoding the actual trace data. - virtual Status GetMetaData(lldb::user_id_t traceid, lldb::tid_t thread, - llvm::MutableArrayRef<uint8_t> &buffer, - size_t offset = 0) { - return Status("Not implemented"); + /// \copydoc Process::TraceGetState(llvm::StringRef type) + virtual llvm::Expected<llvm::json::Value> + TraceGetState(llvm::StringRef type) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Unsupported tracing type '%s'", + type.data()); } - /// API to query the TraceOptions for a given user id - /// - /// \param[in] traceid - /// The user id of the tracing instance. - /// - /// \param[out] config - /// The configuration being used for tracing. - /// - /// \return A status indicating what went wrong. - virtual Status GetTraceConfig(lldb::user_id_t traceid, TraceOptions &config) { - return Status("Not implemented"); + /// \copydoc Process::TraceGetBinaryData(const TraceGetBinaryDataRequest &) + virtual llvm::Expected<std::vector<uint8_t>> + TraceGetBinaryData(const TraceGetBinaryDataRequest &request) { + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Unsupported data kind '%s' for the '%s' tracing technology", + request.kind.c_str(), request.type.c_str()); } - /// \copydoc Process::GetSupportedTraceType() - virtual llvm::Expected<TraceTypeInfo> GetSupportedTraceType() { + /// \copydoc Process::TraceSupported() + virtual llvm::Expected<TraceSupportedResponse> TraceSupported() { return llvm::make_error<UnimplementedError>(); } + /// Method called in order to propagate the bitmap of protocol + /// extensions supported by the client. + /// + /// \param[in] flags + /// The bitmap of enabled extensions. + virtual void SetEnabledExtensions(Extension flags) { + m_enabled_extensions = flags; + } + protected: struct SoftwareBreakpoint { uint32_t ref_count; @@ -416,8 +388,7 @@ protected: llvm::Optional<WaitStatus> m_exit_status; - std::recursive_mutex m_delegates_mutex; - std::vector<NativeDelegate *> m_delegates; + NativeDelegate &m_delegate; NativeWatchpointList m_watchpoint_list; HardwareBreakpointMap m_hw_breakpoints_map; int m_terminal_fd; @@ -427,6 +398,9 @@ protected: // stopping it. llvm::DenseSet<int> m_signals_to_ignore; + // Extensions enabled per the last SetEnabledExtensions() call. + Extension m_enabled_extensions; + // lldb_private::Host calls should be used to launch a process for debugging, // and then the process should be attached to. When attaching to a process // lldb_private::Host calls should be used to locate the process to attach diff --git a/contrib/llvm-project/lldb/include/lldb/Host/common/NativeThreadProtocol.h b/contrib/llvm-project/lldb/include/lldb/Host/common/NativeThreadProtocol.h index 8d4c03549bb9..5cf26bd95939 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/common/NativeThreadProtocol.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/common/NativeThreadProtocol.h @@ -21,7 +21,7 @@ class NativeThreadProtocol { public: NativeThreadProtocol(NativeProcessProtocol &process, lldb::tid_t tid); - virtual ~NativeThreadProtocol() {} + virtual ~NativeThreadProtocol() = default; virtual std::string GetName() = 0; diff --git a/contrib/llvm-project/lldb/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h b/contrib/llvm-project/lldb/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h index 3ee8f9d9133e..42be989dfa7b 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h @@ -108,7 +108,7 @@ protected: std::atomic<bool> m_shutting_down; // This marks that we are shutting down so // if we get woken up from // BytesAvailable to disconnect, we won't try to read again. - bool m_waiting_for_accept; + bool m_waiting_for_accept = false; bool m_child_processes_inherit; std::string m_uri; diff --git a/contrib/llvm-project/lldb/include/lldb/Initialization/SystemInitializerCommon.h b/contrib/llvm-project/lldb/include/lldb/Initialization/SystemInitializerCommon.h index 3a5081680879..d918b1125a57 100644 --- a/contrib/llvm-project/lldb/include/lldb/Initialization/SystemInitializerCommon.h +++ b/contrib/llvm-project/lldb/include/lldb/Initialization/SystemInitializerCommon.h @@ -10,6 +10,7 @@ #define LLDB_INITIALIZATION_SYSTEMINITIALIZERCOMMON_H #include "SystemInitializer.h" +#include "lldb/Host/HostInfo.h" namespace lldb_private { /// Initializes common lldb functionality. @@ -22,11 +23,14 @@ namespace lldb_private { /// the constructor. class SystemInitializerCommon : public SystemInitializer { public: - SystemInitializerCommon(); + SystemInitializerCommon(HostInfo::SharedLibraryDirectoryHelper *helper); ~SystemInitializerCommon() override; llvm::Error Initialize() override; void Terminate() override; + +private: + HostInfo::SharedLibraryDirectoryHelper *m_shlib_dir_helper; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Initialization/SystemLifetimeManager.h b/contrib/llvm-project/lldb/include/lldb/Initialization/SystemLifetimeManager.h index 27e1a22b19dd..06328e60133f 100644 --- a/contrib/llvm-project/lldb/include/lldb/Initialization/SystemLifetimeManager.h +++ b/contrib/llvm-project/lldb/include/lldb/Initialization/SystemLifetimeManager.h @@ -30,7 +30,7 @@ public: private: std::recursive_mutex m_mutex; std::unique_ptr<SystemInitializer> m_initializer; - bool m_initialized; + bool m_initialized = false; // Noncopyable. SystemLifetimeManager(const SystemLifetimeManager &other) = delete; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandHistory.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandHistory.h index fbb42247f11a..12c170ba5eeb 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandHistory.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandHistory.h @@ -20,9 +20,9 @@ namespace lldb_private { class CommandHistory { public: - CommandHistory(); + CommandHistory() = default; - ~CommandHistory(); + ~CommandHistory() = default; size_t GetSize() const; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandInterpreter.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandInterpreter.h index c4f9dd2fdb37..3b3daced3e33 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandInterpreter.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandInterpreter.h @@ -24,15 +24,16 @@ #include "lldb/Utility/StringList.h" #include "lldb/lldb-forward.h" #include "lldb/lldb-private.h" + #include <mutex> +#include <stack> namespace lldb_private { class CommandInterpreter; class CommandInterpreterRunResult { public: - CommandInterpreterRunResult() - : m_num_errors(0), m_result(lldb::eCommandInterpreterResultSuccess) {} + CommandInterpreterRunResult() = default; uint32_t GetNumErrors() const { return m_num_errors; } @@ -50,8 +51,9 @@ protected: void SetResult(lldb::CommandInterpreterResult result) { m_result = result; } private: - int m_num_errors; - lldb::CommandInterpreterResult m_result; + int m_num_errors = 0; + lldb::CommandInterpreterResult m_result = + lldb::eCommandInterpreterResultSuccess; }; class CommandInterpreterRunOptions { @@ -98,14 +100,7 @@ public: m_echo_comment_commands(echo_comments), m_print_results(print_results), m_print_errors(print_errors), m_add_to_history(add_to_history) {} - CommandInterpreterRunOptions() - : m_stop_on_continue(eLazyBoolCalculate), - m_stop_on_error(eLazyBoolCalculate), - m_stop_on_crash(eLazyBoolCalculate), - m_echo_commands(eLazyBoolCalculate), - m_echo_comment_commands(eLazyBoolCalculate), - m_print_results(eLazyBoolCalculate), m_print_errors(eLazyBoolCalculate), - m_add_to_history(eLazyBoolCalculate) {} + CommandInterpreterRunOptions() = default; void SetSilent(bool silent) { LazyBool value = silent ? eLazyBoolNo : eLazyBoolYes; @@ -185,14 +180,14 @@ public: m_spawn_thread = spawn_thread ? eLazyBoolYes : eLazyBoolNo; } - LazyBool m_stop_on_continue; - LazyBool m_stop_on_error; - LazyBool m_stop_on_crash; - LazyBool m_echo_commands; - LazyBool m_echo_comment_commands; - LazyBool m_print_results; - LazyBool m_print_errors; - LazyBool m_add_to_history; + LazyBool m_stop_on_continue = eLazyBoolCalculate; + LazyBool m_stop_on_error = eLazyBoolCalculate; + LazyBool m_stop_on_crash = eLazyBoolCalculate; + LazyBool m_echo_commands = eLazyBoolCalculate; + LazyBool m_echo_comment_commands = eLazyBoolCalculate; + LazyBool m_print_results = eLazyBoolCalculate; + LazyBool m_print_errors = eLazyBoolCalculate; + LazyBool m_add_to_history = eLazyBoolCalculate; LazyBool m_auto_handle_events; LazyBool m_spawn_thread; @@ -245,7 +240,7 @@ public: CommandInterpreter(Debugger &debugger, bool synchronous_execution); - ~CommandInterpreter() override; + ~CommandInterpreter() override = default; // These two functions fill out the Broadcaster interface: @@ -300,10 +295,11 @@ public: CommandReturnObject &result); bool HandleCommand(const char *command_line, LazyBool add_to_history, - CommandReturnObject &result, - ExecutionContext *override_context = nullptr, - bool repeat_on_empty_command = true, - bool no_context_switching = false); + const ExecutionContext &override_context, + CommandReturnObject &result); + + bool HandleCommand(const char *command_line, LazyBool add_to_history, + CommandReturnObject &result); bool WasInterrupted() const; @@ -312,9 +308,7 @@ public: /// \param[in] commands /// The list of commands to execute. /// \param[in,out] context - /// The execution context in which to run the commands. Can be nullptr in - /// which case the default - /// context will be used. + /// The execution context in which to run the commands. /// \param[in] options /// This object holds the options used to control when to stop, whether to /// execute commands, @@ -324,8 +318,13 @@ public: /// safely, /// and failed with some explanation if we aborted executing the commands /// at some point. - void HandleCommands(const StringList &commands, ExecutionContext *context, - CommandInterpreterRunOptions &options, + void HandleCommands(const StringList &commands, + const ExecutionContext &context, + const CommandInterpreterRunOptions &options, + CommandReturnObject &result); + + void HandleCommands(const StringList &commands, + const CommandInterpreterRunOptions &options, CommandReturnObject &result); /// Execute a list of commands from a file. @@ -333,9 +332,7 @@ public: /// \param[in] file /// The file from which to read in commands. /// \param[in,out] context - /// The execution context in which to run the commands. Can be nullptr in - /// which case the default - /// context will be used. + /// The execution context in which to run the commands. /// \param[in] options /// This object holds the options used to control when to stop, whether to /// execute commands, @@ -345,8 +342,12 @@ public: /// safely, /// and failed with some explanation if we aborted executing the commands /// at some point. - void HandleCommandsFromFile(FileSpec &file, ExecutionContext *context, - CommandInterpreterRunOptions &options, + void HandleCommandsFromFile(FileSpec &file, const ExecutionContext &context, + const CommandInterpreterRunOptions &options, + CommandReturnObject &result); + + void HandleCommandsFromFile(FileSpec &file, + const CommandInterpreterRunOptions &options, CommandReturnObject &result); CommandObject *GetCommandObjectForCommand(llvm::StringRef &command_line); @@ -391,12 +392,7 @@ public: Debugger &GetDebugger() { return m_debugger; } - ExecutionContext GetExecutionContext() { - const bool thread_and_frame_only_if_stopped = true; - return m_exe_ctx_ref.Lock(thread_and_frame_only_if_stopped); - } - - void UpdateExecutionContext(ExecutionContext *override_context); + ExecutionContext GetExecutionContext() const; lldb::PlatformSP GetPlatform(bool prefer_target_platform); @@ -495,12 +491,17 @@ public: bool GetSaveSessionOnQuit() const; void SetSaveSessionOnQuit(bool enable); + FileSpec GetSaveSessionDirectory() const; + void SetSaveSessionDirectory(llvm::StringRef path); + bool GetEchoCommands() const; void SetEchoCommands(bool enable); bool GetEchoCommentCommands() const; void SetEchoCommentCommands(bool enable); + bool GetRepeatPreviousCommand() const; + const CommandObject::CommandMap &GetUserCommands() const { return m_user_dict; } @@ -581,6 +582,10 @@ protected: StringList *descriptions = nullptr) const; private: + void OverrideExecutionContext(const ExecutionContext &override_context); + + void RestoreExecutionContext(); + Status PreprocessCommand(std::string &command); void SourceInitFile(FileSpec file, CommandReturnObject &result); @@ -619,8 +624,9 @@ private: Debugger &m_debugger; // The debugger session that this interpreter is // associated with - ExecutionContextRef m_exe_ctx_ref; // The current execution context to use - // when handling commands + // Execution contexts that were temporarily set by some of HandleCommand* + // overloads. + std::stack<ExecutionContext> m_overriden_exe_contexts; bool m_synchronous_execution; bool m_skip_lldbinit_files; bool m_skip_app_init_files; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObject.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObject.h index d5ad969cda66..8bc5d3e22355 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObject.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObject.h @@ -113,7 +113,7 @@ public: llvm::StringRef help = "", llvm::StringRef syntax = "", uint32_t flags = 0); - virtual ~CommandObject(); + virtual ~CommandObject() = default; static const char * GetArgumentTypeAsCString(const lldb::CommandArgumentType arg_type); diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandReturnObject.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandReturnObject.h index a7c2eea57663..0c995b73c463 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandReturnObject.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandReturnObject.h @@ -26,7 +26,7 @@ class CommandReturnObject { public: CommandReturnObject(bool colors); - ~CommandReturnObject(); + ~CommandReturnObject() = default; llvm::StringRef GetOutputData() { lldb::StreamSP stream_sp(m_out_stream.GetStreamAtIndex(eStreamStringIndex)); @@ -63,20 +63,28 @@ public: } void SetImmediateOutputFile(lldb::FileSP file_sp) { + if (m_suppress_immediate_output) + return; lldb::StreamSP stream_sp(new StreamFile(file_sp)); m_out_stream.SetStreamAtIndex(eImmediateStreamIndex, stream_sp); } void SetImmediateErrorFile(lldb::FileSP file_sp) { + if (m_suppress_immediate_output) + return; lldb::StreamSP stream_sp(new StreamFile(file_sp)); m_err_stream.SetStreamAtIndex(eImmediateStreamIndex, stream_sp); } void SetImmediateOutputStream(const lldb::StreamSP &stream_sp) { + if (m_suppress_immediate_output) + return; m_out_stream.SetStreamAtIndex(eImmediateStreamIndex, stream_sp); } void SetImmediateErrorStream(const lldb::StreamSP &stream_sp) { + if (m_suppress_immediate_output) + return; m_err_stream.SetStreamAtIndex(eImmediateStreamIndex, stream_sp); } @@ -95,8 +103,6 @@ public: void AppendMessageWithFormat(const char *format, ...) __attribute__((format(printf, 2, 3))); - void AppendRawWarning(llvm::StringRef in_string); - void AppendWarning(llvm::StringRef in_string); void AppendWarningWithFormat(const char *format, ...) @@ -126,8 +132,6 @@ public: void SetError(const Status &error, const char *fallback_error_cstr = nullptr); - void SetError(llvm::StringRef error_cstr); - lldb::ReturnStatus GetStatus(); void SetStatus(lldb::ReturnStatus status); @@ -144,16 +148,23 @@ public: void SetInteractive(bool b); + bool GetSuppressImmediateOutput() const; + + void SetSuppressImmediateOutput(bool b); + private: enum { eStreamStringIndex = 0, eImmediateStreamIndex = 1 }; StreamTee m_out_stream; StreamTee m_err_stream; - lldb::ReturnStatus m_status; - bool m_did_change_process_state; - bool m_interactive; // If true, then the input handle from the debugger will - // be hooked up + lldb::ReturnStatus m_status = lldb::eReturnStatusStarted; + + bool m_did_change_process_state = false; + bool m_suppress_immediate_output = false; + + /// If true, then the input handle from the debugger will be hooked up. + bool m_interactive = true; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupArchitecture.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupArchitecture.h index 1eadf45bae47..4655a68f1e4a 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupArchitecture.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupArchitecture.h @@ -18,9 +18,9 @@ namespace lldb_private { class OptionGroupArchitecture : public OptionGroup { public: - OptionGroupArchitecture(); + OptionGroupArchitecture() = default; - ~OptionGroupArchitecture() override; + ~OptionGroupArchitecture() override = default; llvm::ArrayRef<OptionDefinition> GetDefinitions() override; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupBoolean.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupBoolean.h index 061e31340854..9e2dad5d9c2a 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupBoolean.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupBoolean.h @@ -25,7 +25,7 @@ public: const char *usage_text, bool default_value, bool no_argument_toggle_default); - ~OptionGroupBoolean() override; + ~OptionGroupBoolean() override = default; llvm::ArrayRef<OptionDefinition> GetDefinitions() override { return llvm::ArrayRef<OptionDefinition>(&m_option_definition, 1); @@ -33,7 +33,6 @@ public: Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override; - Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete; void OptionParsingStarting(ExecutionContext *execution_context) override; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupFile.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupFile.h index 374cf10ea30a..1e4eb35eade4 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupFile.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupFile.h @@ -24,7 +24,7 @@ public: lldb::CommandArgumentType argument_type, const char *usage_text); - ~OptionGroupFile() override; + ~OptionGroupFile() override = default; llvm::ArrayRef<OptionDefinition> GetDefinitions() override { return llvm::ArrayRef<OptionDefinition>(&m_option_definition, 1); @@ -32,7 +32,6 @@ public: Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override; - Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete; void OptionParsingStarting(ExecutionContext *execution_context) override; @@ -63,7 +62,6 @@ public: Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override; - Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete; void OptionParsingStarting(ExecutionContext *execution_context) override; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupFormat.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupFormat.h index 62c6f97c6214..2d445b8a6c20 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupFormat.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupFormat.h @@ -32,13 +32,12 @@ public: uint64_t default_count = UINT64_MAX); // Pass UINT64_MAX to disable the "--count" option - ~OptionGroupFormat() override; + ~OptionGroupFormat() override = default; llvm::ArrayRef<OptionDefinition> GetDefinitions() override; Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override; - Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete; void OptionParsingStarting(ExecutionContext *execution_context) override; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupOutputFile.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupOutputFile.h index a71998f3bc1a..3902247cfb3e 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupOutputFile.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupOutputFile.h @@ -20,13 +20,12 @@ class OptionGroupOutputFile : public OptionGroup { public: OptionGroupOutputFile(); - ~OptionGroupOutputFile() override; + ~OptionGroupOutputFile() override = default; llvm::ArrayRef<OptionDefinition> GetDefinitions() override; Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override; - Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete; void OptionParsingStarting(ExecutionContext *execution_context) override; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupPlatform.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupPlatform.h index 99945e5246fd..fed2791a6130 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupPlatform.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupPlatform.h @@ -21,8 +21,7 @@ namespace lldb_private { class OptionGroupPlatform : public OptionGroup { public: OptionGroupPlatform(bool include_platform_option) - : OptionGroup(), m_platform_name(), m_sdk_sysroot(), - m_include_platform_option(include_platform_option) {} + : m_include_platform_option(include_platform_option) {} ~OptionGroupPlatform() override = default; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupPythonClassWithDict.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupPythonClassWithDict.h index d4c924a44157..a0de1bc8b8a1 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupPythonClassWithDict.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupPythonClassWithDict.h @@ -1,4 +1,4 @@ -//===-- OptionGroupPythonClassWithDict.h -------------------------------------*- C++ -*-===// +//===-- OptionGroupPythonClassWithDict.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. @@ -9,9 +9,10 @@ #ifndef LLDB_INTERPRETER_OPTIONGROUPPYTHONCLASSWITHDICT_H #define LLDB_INTERPRETER_OPTIONGROUPPYTHONCLASSWITHDICT_H -#include "lldb/lldb-types.h" #include "lldb/Interpreter/Options.h" +#include "lldb/Utility/Flags.h" #include "lldb/Utility/StructuredData.h" +#include "lldb/lldb-types.h" namespace lldb_private { @@ -23,13 +24,21 @@ namespace lldb_private { // StructuredData::Dictionary is constructed with those pairs. class OptionGroupPythonClassWithDict : public OptionGroup { public: - OptionGroupPythonClassWithDict(const char *class_use, - bool is_class = true, - int class_option = 'C', - int key_option = 'k', - int value_option = 'v'); - - ~OptionGroupPythonClassWithDict() override; + enum OptionKind { + eScriptClass = 1 << 0, + eDictKey = 1 << 1, + eDictValue = 1 << 2, + ePythonFunction = 1 << 3, + eAllOptions = (eScriptClass | eDictKey | eDictValue | ePythonFunction) + }; + + OptionGroupPythonClassWithDict(const char *class_use, bool is_class = true, + int class_option = 'C', int key_option = 'k', + int value_option = 'v', + uint16_t required_options = eScriptClass | + ePythonFunction); + + ~OptionGroupPythonClassWithDict() override = default; llvm::ArrayRef<OptionDefinition> GetDefinitions() override { return llvm::ArrayRef<OptionDefinition>(m_option_definition); @@ -37,7 +46,6 @@ public: Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override; - Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete; void OptionParsingStarting(ExecutionContext *execution_context) override; Status OptionParsingFinished(ExecutionContext *execution_context) override; @@ -56,6 +64,7 @@ protected: std::string m_class_usage_text, m_key_usage_text, m_value_usage_text; bool m_is_class; OptionDefinition m_option_definition[4]; + Flags m_required_options; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupString.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupString.h index 1a3b5bdd88ed..aa0225639035 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupString.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupString.h @@ -22,7 +22,7 @@ public: lldb::CommandArgumentType argument_type, const char *usage_text, const char *default_value); - ~OptionGroupString() override; + ~OptionGroupString() override = default; llvm::ArrayRef<OptionDefinition> GetDefinitions() override { return llvm::ArrayRef<OptionDefinition>(&m_option_definition, 1); @@ -30,7 +30,6 @@ public: Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override; - Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete; void OptionParsingStarting(ExecutionContext *execution_context) override; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupUInt64.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupUInt64.h index 783c4b632f00..710591725409 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupUInt64.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupUInt64.h @@ -23,7 +23,7 @@ public: lldb::CommandArgumentType argument_type, const char *usage_text, uint64_t default_value); - ~OptionGroupUInt64() override; + ~OptionGroupUInt64() override = default; llvm::ArrayRef<OptionDefinition> GetDefinitions() override { return llvm::ArrayRef<OptionDefinition>(&m_option_definition, 1); @@ -31,7 +31,6 @@ public: Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override; - Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete; void OptionParsingStarting(ExecutionContext *execution_context) override; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupUUID.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupUUID.h index b1c779f7b5a4..4ca2a94b7fb3 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupUUID.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupUUID.h @@ -18,15 +18,14 @@ namespace lldb_private { class OptionGroupUUID : public OptionGroup { public: - OptionGroupUUID(); + OptionGroupUUID() = default; - ~OptionGroupUUID() override; + ~OptionGroupUUID() override = default; llvm::ArrayRef<OptionDefinition> GetDefinitions() override; Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override; - Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete; void OptionParsingStarting(ExecutionContext *execution_context) override; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h index 1ad53321d26e..56452f4956f2 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h @@ -18,15 +18,14 @@ namespace lldb_private { class OptionGroupValueObjectDisplay : public OptionGroup { public: - OptionGroupValueObjectDisplay(); + OptionGroupValueObjectDisplay() = default; - ~OptionGroupValueObjectDisplay() override; + ~OptionGroupValueObjectDisplay() override = default; llvm::ArrayRef<OptionDefinition> GetDefinitions() override; Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override; - Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete; void OptionParsingStarting(ExecutionContext *execution_context) override; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupVariable.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupVariable.h index 252ca3b42c5e..c9f1283d4de2 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupVariable.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupVariable.h @@ -20,13 +20,12 @@ class OptionGroupVariable : public OptionGroup { public: OptionGroupVariable(bool show_frame_options); - ~OptionGroupVariable() override; + ~OptionGroupVariable() override = default; llvm::ArrayRef<OptionDefinition> GetDefinitions() override; Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override; - Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete; void OptionParsingStarting(ExecutionContext *execution_context) override; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupWatchpoint.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupWatchpoint.h index 6a6c8638aede..33818043cf63 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupWatchpoint.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupWatchpoint.h @@ -17,9 +17,9 @@ namespace lldb_private { class OptionGroupWatchpoint : public OptionGroup { public: - OptionGroupWatchpoint(); + OptionGroupWatchpoint() = default; - ~OptionGroupWatchpoint() override; + ~OptionGroupWatchpoint() override = default; static bool IsWatchSizeSupported(uint32_t watch_size); @@ -27,7 +27,6 @@ public: Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override; - Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete; void OptionParsingStarting(ExecutionContext *execution_context) override; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValue.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValue.h index a8176e39940a..99f52b0411b9 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValue.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValue.h @@ -10,6 +10,7 @@ #define LLDB_INTERPRETER_OPTIONVALUE_H #include "lldb/Core/FormatEntity.h" +#include "lldb/Utility/Cloneable.h" #include "lldb/Utility/CompletionRequest.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Status.h" @@ -59,7 +60,7 @@ public: eDumpGroupExport = (eDumpOptionCommand | eDumpOptionName | eDumpOptionValue) }; - OptionValue() : m_value_was_set(false) {} + OptionValue() = default; virtual ~OptionValue() = default; @@ -87,7 +88,8 @@ public: virtual void Clear() = 0; - virtual lldb::OptionValueSP DeepCopy() const = 0; + virtual lldb::OptionValueSP + DeepCopy(const lldb::OptionValueSP &new_parent) const; virtual void AutoComplete(CommandInterpreter &interpreter, CompletionRequest &request); @@ -306,6 +308,8 @@ public: m_parent_wp = parent_sp; } + lldb::OptionValueSP GetParent() const { return m_parent_wp.lock(); } + void SetValueChangedCallback(std::function<void()> callback) { assert(!m_callback); m_callback = std::move(callback); @@ -317,14 +321,20 @@ public: } protected: + using TopmostBase = OptionValue; + + // Must be overriden by a derived class for correct downcasting the result of + // DeepCopy to it. Inherit from Cloneable to avoid doing this manually. + virtual lldb::OptionValueSP Clone() const = 0; + lldb::OptionValueWP m_parent_wp; std::function<void()> m_callback; - bool m_value_was_set; // This can be used to see if a value has been set - // by a call to SetValueFromCString(). It is often - // handy to know if an option value was set from the - // command line or as a setting, versus if we just have - // the default value that was already populated in the - // option value. + bool m_value_was_set = false; // This can be used to see if a value has been + // set by a call to SetValueFromCString(). It is + // often handy to know if an option value was + // set from the command line or as a setting, + // versus if we just have the default value that + // was already populated in the option value. }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueArch.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueArch.h index 809261ef22c3..e17520879447 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueArch.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueArch.h @@ -15,23 +15,21 @@ namespace lldb_private { -class OptionValueArch : public OptionValue { +class OptionValueArch : public Cloneable<OptionValueArch, OptionValue> { public: - OptionValueArch() : OptionValue(), m_current_value(), m_default_value() {} + OptionValueArch() = default; - OptionValueArch(const char *triple) - : OptionValue(), m_current_value(triple), m_default_value() { + OptionValueArch(const char *triple) : m_current_value(triple) { m_default_value = m_current_value; } OptionValueArch(const ArchSpec &value) - : OptionValue(), m_current_value(value), m_default_value(value) {} + : m_current_value(value), m_default_value(value) {} OptionValueArch(const ArchSpec ¤t_value, const ArchSpec &default_value) - : OptionValue(), m_current_value(current_value), - m_default_value(default_value) {} + : m_current_value(current_value), m_default_value(default_value) {} - ~OptionValueArch() override {} + ~OptionValueArch() override = default; // Virtual subclass pure virtual overrides @@ -43,17 +41,12 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { m_current_value = m_default_value; m_value_was_set = false; } - lldb::OptionValueSP DeepCopy() const override; - void AutoComplete(CommandInterpreter &interpreter, lldb_private::CompletionRequest &request) override; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueArgs.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueArgs.h index 25f7fdde0bf3..1e2a1430d0c5 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueArgs.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueArgs.h @@ -13,15 +13,14 @@ namespace lldb_private { -class OptionValueArgs : public OptionValueArray { +class OptionValueArgs : public Cloneable<OptionValueArgs, OptionValueArray> { public: OptionValueArgs() - : OptionValueArray( - OptionValue::ConvertTypeToMask(OptionValue::eTypeString)) {} + : Cloneable(OptionValue::ConvertTypeToMask(OptionValue::eTypeString)) {} - ~OptionValueArgs() override {} + ~OptionValueArgs() override = default; - size_t GetArgs(Args &args); + size_t GetArgs(Args &args) const; Type GetType() const override { return eTypeArgs; } }; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueArray.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueArray.h index 4546bbb80394..011eefc34251 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueArray.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueArray.h @@ -15,12 +15,12 @@ namespace lldb_private { -class OptionValueArray : public OptionValue { +class OptionValueArray : public Cloneable<OptionValueArray, OptionValue> { public: OptionValueArray(uint32_t type_mask = UINT32_MAX, bool raw_value_dump = false) : m_type_mask(type_mask), m_values(), m_raw_value_dump(raw_value_dump) {} - ~OptionValueArray() override {} + ~OptionValueArray() override = default; // Virtual subclass pure virtual overrides @@ -32,16 +32,14 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { m_values.clear(); m_value_was_set = false; } - lldb::OptionValueSP DeepCopy() const override; + lldb::OptionValueSP + DeepCopy(const lldb::OptionValueSP &new_parent) const override; bool IsAggregateValue() const override { return true; } diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueBoolean.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueBoolean.h index 1af14a4980ed..fd15ccb12c40 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueBoolean.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueBoolean.h @@ -13,15 +13,14 @@ namespace lldb_private { -class OptionValueBoolean : public OptionValue { +class OptionValueBoolean : public Cloneable<OptionValueBoolean, OptionValue> { public: OptionValueBoolean(bool value) - : OptionValue(), m_current_value(value), m_default_value(value) {} + : m_current_value(value), m_default_value(value) {} OptionValueBoolean(bool current_value, bool default_value) - : OptionValue(), m_current_value(current_value), - m_default_value(default_value) {} + : m_current_value(current_value), m_default_value(default_value) {} - ~OptionValueBoolean() override {} + ~OptionValueBoolean() override = default; // Virtual subclass pure virtual overrides @@ -33,9 +32,6 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { m_current_value = m_default_value; @@ -75,8 +71,6 @@ public: void SetDefaultValue(bool value) { m_default_value = value; } - lldb::OptionValueSP DeepCopy() const override; - protected: bool m_current_value; bool m_default_value; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueChar.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueChar.h index a8ecf507a4cf..6b8a314a7c99 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueChar.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueChar.h @@ -13,16 +13,15 @@ namespace lldb_private { -class OptionValueChar : public OptionValue { +class OptionValueChar : public Cloneable<OptionValueChar, OptionValue> { public: OptionValueChar(char value) - : OptionValue(), m_current_value(value), m_default_value(value) {} + : m_current_value(value), m_default_value(value) {} OptionValueChar(char current_value, char default_value) - : OptionValue(), m_current_value(current_value), - m_default_value(default_value) {} + : m_current_value(current_value), m_default_value(default_value) {} - ~OptionValueChar() override {} + ~OptionValueChar() override = default; // Virtual subclass pure virtual overrides @@ -34,9 +33,6 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { m_current_value = m_default_value; @@ -58,8 +54,6 @@ public: void SetDefaultValue(char value) { m_default_value = value; } - lldb::OptionValueSP DeepCopy() const override; - protected: char m_current_value; char m_default_value; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueDictionary.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueDictionary.h index dab1c3ea0c1c..f96cbc9fe9e7 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueDictionary.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueDictionary.h @@ -15,14 +15,14 @@ namespace lldb_private { -class OptionValueDictionary : public OptionValue { +class OptionValueDictionary + : public Cloneable<OptionValueDictionary, OptionValue> { public: OptionValueDictionary(uint32_t type_mask = UINT32_MAX, bool raw_value_dump = true) - : OptionValue(), m_type_mask(type_mask), m_values(), - m_raw_value_dump(raw_value_dump) {} + : m_type_mask(type_mask), m_raw_value_dump(raw_value_dump) {} - ~OptionValueDictionary() override {} + ~OptionValueDictionary() override = default; // Virtual subclass pure virtual overrides @@ -40,7 +40,8 @@ public: m_value_was_set = false; } - lldb::OptionValueSP DeepCopy() const override; + lldb::OptionValueSP + DeepCopy(const lldb::OptionValueSP &new_parent) const override; bool IsAggregateValue() const override { return true; } diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueEnumeration.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueEnumeration.h index 12c6473c7f1c..7dc6eea4e69d 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueEnumeration.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueEnumeration.h @@ -19,7 +19,8 @@ namespace lldb_private { -class OptionValueEnumeration : public OptionValue { +class OptionValueEnumeration + : public Cloneable<OptionValueEnumeration, OptionValue> { public: typedef int64_t enum_type; struct EnumeratorInfo { @@ -31,7 +32,7 @@ public: OptionValueEnumeration(const OptionEnumValues &enumerators, enum_type value); - ~OptionValueEnumeration() override; + ~OptionValueEnumeration() override = default; // Virtual subclass pure virtual overrides @@ -43,17 +44,12 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { m_current_value = m_default_value; m_value_was_set = false; } - lldb::OptionValueSP DeepCopy() const override; - void AutoComplete(CommandInterpreter &interpreter, CompletionRequest &request) override; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileColonLine.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileColonLine.h index 713deea9e141..83d36edc1e9a 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileColonLine.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileColonLine.h @@ -9,19 +9,20 @@ #ifndef LLDB_INTERPRETER_OPTIONVALUEFILECOLONLINE_H #define LLDB_INTERPRETER_OPTIONVALUEFILECOLONLINE_H +#include "lldb/Interpreter/CommandCompletions.h" #include "lldb/Interpreter/OptionValue.h" - #include "lldb/Utility/FileSpec.h" #include "llvm/Support/Chrono.h" namespace lldb_private { -class OptionValueFileColonLine : public OptionValue { +class OptionValueFileColonLine : + public Cloneable<OptionValueFileColonLine, OptionValue> { public: OptionValueFileColonLine(); OptionValueFileColonLine(const llvm::StringRef input); - ~OptionValueFileColonLine() override {} + ~OptionValueFileColonLine() override = default; OptionValue::Type GetType() const override { return eTypeFileLineColumn; } @@ -31,9 +32,6 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { m_file_spec.Clear(); @@ -41,8 +39,6 @@ public: m_column_number = LLDB_INVALID_COLUMN_NUMBER; } - lldb::OptionValueSP DeepCopy() const override; - void AutoComplete(CommandInterpreter &interpreter, CompletionRequest &request) override; @@ -54,9 +50,9 @@ public: protected: FileSpec m_file_spec; - uint32_t m_line_number; - uint32_t m_column_number; - uint32_t m_completion_mask; + uint32_t m_line_number = LLDB_INVALID_LINE_NUMBER; + uint32_t m_column_number = LLDB_INVALID_COLUMN_NUMBER; + uint32_t m_completion_mask = CommandCompletions::eSourceFileCompletion; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileSpec.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileSpec.h index 4fde3f6e3c8a..6648bbac93e3 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileSpec.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileSpec.h @@ -9,6 +9,7 @@ #ifndef LLDB_INTERPRETER_OPTIONVALUEFILESPEC_H #define LLDB_INTERPRETER_OPTIONVALUEFILESPEC_H +#include "lldb/Interpreter/CommandCompletions.h" #include "lldb/Interpreter/OptionValue.h" #include "lldb/Utility/FileSpec.h" @@ -16,7 +17,7 @@ namespace lldb_private { -class OptionValueFileSpec : public OptionValue { +class OptionValueFileSpec : public Cloneable<OptionValueFileSpec, OptionValue> { public: OptionValueFileSpec(bool resolve = true); @@ -25,7 +26,7 @@ public: OptionValueFileSpec(const FileSpec ¤t_value, const FileSpec &default_value, bool resolve = true); - ~OptionValueFileSpec() override {} + ~OptionValueFileSpec() override = default; // Virtual subclass pure virtual overrides @@ -37,9 +38,6 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { m_current_value = m_default_value; @@ -48,8 +46,6 @@ public: m_data_mod_time = llvm::sys::TimePoint<>(); } - lldb::OptionValueSP DeepCopy() const override; - void AutoComplete(CommandInterpreter &interpreter, CompletionRequest &request) override; @@ -79,7 +75,7 @@ protected: FileSpec m_default_value; lldb::DataBufferSP m_data_sp; llvm::sys::TimePoint<> m_data_mod_time; - uint32_t m_completion_mask; + uint32_t m_completion_mask = CommandCompletions::eDiskFileCompletion; bool m_resolve; }; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileSpecList.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileSpecList.h index 38773525c8db..29641c3a2087 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileSpecList.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileSpecList.h @@ -16,14 +16,15 @@ namespace lldb_private { -class OptionValueFileSpecList : public OptionValue { +class OptionValueFileSpecList + : public Cloneable<OptionValueFileSpecList, OptionValue> { public: - OptionValueFileSpecList() : OptionValue(), m_current_value() {} + OptionValueFileSpecList() = default; - OptionValueFileSpecList(const FileSpecList ¤t_value) - : OptionValue(), m_current_value(current_value) {} + OptionValueFileSpecList(const OptionValueFileSpecList &other) + : Cloneable(other), m_current_value(other.GetCurrentValue()) {} - ~OptionValueFileSpecList() override {} + ~OptionValueFileSpecList() override = default; // Virtual subclass pure virtual overrides @@ -35,9 +36,6 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { std::lock_guard<std::recursive_mutex> lock(m_mutex); @@ -45,8 +43,6 @@ public: m_value_was_set = false; } - lldb::OptionValueSP DeepCopy() const override; - bool IsAggregateValue() const override { return true; } // Subclass specific functions @@ -67,6 +63,8 @@ public: } protected: + lldb::OptionValueSP Clone() const override; + mutable std::recursive_mutex m_mutex; FileSpecList m_current_value; }; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFormat.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFormat.h index 5a83ff3b8983..1f2c66b164d5 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFormat.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFormat.h @@ -13,16 +13,16 @@ namespace lldb_private { -class OptionValueFormat : public OptionValue { +class OptionValueFormat + : public Cloneable<OptionValueFormat, OptionValue> { public: OptionValueFormat(lldb::Format value) - : OptionValue(), m_current_value(value), m_default_value(value) {} + : m_current_value(value), m_default_value(value) {} OptionValueFormat(lldb::Format current_value, lldb::Format default_value) - : OptionValue(), m_current_value(current_value), - m_default_value(default_value) {} + : m_current_value(current_value), m_default_value(default_value) {} - ~OptionValueFormat() override {} + ~OptionValueFormat() override = default; // Virtual subclass pure virtual overrides @@ -34,17 +34,12 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { m_current_value = m_default_value; m_value_was_set = false; } - lldb::OptionValueSP DeepCopy() const override; - // Subclass specific functions lldb::Format GetCurrentValue() const { return m_current_value; } diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h index 7c2f9fba0242..cb8b2ef13fa4 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h @@ -14,11 +14,12 @@ namespace lldb_private { -class OptionValueFormatEntity : public OptionValue { +class OptionValueFormatEntity + : public Cloneable<OptionValueFormatEntity, OptionValue> { public: OptionValueFormatEntity(const char *default_format); - ~OptionValueFormatEntity() override {} + ~OptionValueFormatEntity() override = default; // Virtual subclass pure virtual overrides @@ -30,14 +31,9 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override; - lldb::OptionValueSP DeepCopy() const override; - void AutoComplete(CommandInterpreter &interpreter, CompletionRequest &request) override; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueLanguage.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueLanguage.h index 129365296759..c00f71ffff33 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueLanguage.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueLanguage.h @@ -15,17 +15,16 @@ namespace lldb_private { -class OptionValueLanguage : public OptionValue { +class OptionValueLanguage : public Cloneable<OptionValueLanguage, OptionValue> { public: OptionValueLanguage(lldb::LanguageType value) - : OptionValue(), m_current_value(value), m_default_value(value) {} + : m_current_value(value), m_default_value(value) {} OptionValueLanguage(lldb::LanguageType current_value, lldb::LanguageType default_value) - : OptionValue(), m_current_value(current_value), - m_default_value(default_value) {} + : m_current_value(current_value), m_default_value(default_value) {} - ~OptionValueLanguage() override {} + ~OptionValueLanguage() override = default; // Virtual subclass pure virtual overrides @@ -37,17 +36,12 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { m_current_value = m_default_value; m_value_was_set = false; } - lldb::OptionValueSP DeepCopy() const override; - // Subclass specific functions lldb::LanguageType GetCurrentValue() const { return m_current_value; } diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValuePathMappings.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValuePathMappings.h index 6d1a0816f45b..4bc65ce76c76 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValuePathMappings.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValuePathMappings.h @@ -14,12 +14,13 @@ namespace lldb_private { -class OptionValuePathMappings : public OptionValue { +class OptionValuePathMappings + : public Cloneable<OptionValuePathMappings, OptionValue> { public: OptionValuePathMappings(bool notify_changes) - : OptionValue(), m_path_mappings(), m_notify_changes(notify_changes) {} + : m_notify_changes(notify_changes) {} - ~OptionValuePathMappings() override {} + ~OptionValuePathMappings() override = default; // Virtual subclass pure virtual overrides @@ -31,17 +32,12 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { m_path_mappings.Clear(m_notify_changes); m_value_was_set = false; } - lldb::OptionValueSP DeepCopy() const override; - bool IsAggregateValue() const override { return true; } // Subclass specific functions diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueProperties.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueProperties.h index d60afdeb46fb..6fa5403ac142 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueProperties.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueProperties.h @@ -18,25 +18,27 @@ #include "lldb/Utility/ConstString.h" namespace lldb_private { +class Properties; class OptionValueProperties - : public OptionValue, + : public Cloneable<OptionValueProperties, OptionValue>, public std::enable_shared_from_this<OptionValueProperties> { public: - OptionValueProperties() - : OptionValue(), m_name(), m_properties(), m_name_to_index() {} + OptionValueProperties() = default; OptionValueProperties(ConstString name); - OptionValueProperties(const OptionValueProperties &global_properties); - ~OptionValueProperties() override = default; Type GetType() const override { return eTypeProperties; } void Clear() override; - lldb::OptionValueSP DeepCopy() const override; + static lldb::OptionValuePropertiesSP + CreateLocalCopy(const Properties &global_properties); + + lldb::OptionValueSP + DeepCopy(const lldb::OptionValueSP &new_parent) const override; Status SetValueFromString(llvm::StringRef value, diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueRegex.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueRegex.h index 4751a1dc27ed..129987484f19 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueRegex.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueRegex.h @@ -14,11 +14,10 @@ namespace lldb_private { -class OptionValueRegex : public OptionValue { +class OptionValueRegex : public Cloneable<OptionValueRegex, OptionValue> { public: OptionValueRegex(const char *value = nullptr) - : OptionValue(), m_regex(llvm::StringRef::withNullAsEmpty(value)), - m_default_regex_str(llvm::StringRef::withNullAsEmpty(value).str()) {} + : m_regex(value), m_default_regex_str(value) {} ~OptionValueRegex() override = default; @@ -32,17 +31,12 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { m_regex = RegularExpression(m_default_regex_str); m_value_was_set = false; } - lldb::OptionValueSP DeepCopy() const override; - // Subclass specific functions const RegularExpression *GetCurrentValue() const { return (m_regex.IsValid() ? &m_regex : nullptr); diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueSInt64.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueSInt64.h index 87917c108865..3493eb1037c0 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueSInt64.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueSInt64.h @@ -14,27 +14,19 @@ namespace lldb_private { -class OptionValueSInt64 : public OptionValue { +class OptionValueSInt64 : public Cloneable<OptionValueSInt64, OptionValue> { public: - OptionValueSInt64() - : OptionValue(), m_current_value(0), m_default_value(0), - m_min_value(INT64_MIN), m_max_value(INT64_MAX) {} + OptionValueSInt64() = default; OptionValueSInt64(int64_t value) - : OptionValue(), m_current_value(value), m_default_value(value), - m_min_value(INT64_MIN), m_max_value(INT64_MAX) {} + : m_current_value(value), m_default_value(value) {} OptionValueSInt64(int64_t current_value, int64_t default_value) - : OptionValue(), m_current_value(current_value), - m_default_value(default_value), m_min_value(INT64_MIN), - m_max_value(INT64_MAX) {} + : m_current_value(current_value), m_default_value(default_value) {} - OptionValueSInt64(const OptionValueSInt64 &rhs) - : OptionValue(rhs), m_current_value(rhs.m_current_value), - m_default_value(rhs.m_default_value), m_min_value(rhs.m_min_value), - m_max_value(rhs.m_max_value) {} + OptionValueSInt64(const OptionValueSInt64 &rhs) = default; - ~OptionValueSInt64() override {} + ~OptionValueSInt64() override = default; // Virtual subclass pure virtual overrides @@ -46,17 +38,12 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { m_current_value = m_default_value; m_value_was_set = false; } - lldb::OptionValueSP DeepCopy() const override; - // Subclass specific functions const int64_t &operator=(int64_t value) { @@ -93,10 +80,10 @@ public: int64_t GetMaximumValue() const { return m_max_value; } protected: - int64_t m_current_value; - int64_t m_default_value; - int64_t m_min_value; - int64_t m_max_value; + int64_t m_current_value = 0; + int64_t m_default_value = 0; + int64_t m_min_value = INT64_MIN; + int64_t m_max_value = INT64_MAX; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueString.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueString.h index ed44dae67d1d..be42deb80da7 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueString.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueString.h @@ -17,32 +17,25 @@ namespace lldb_private { -class OptionValueString : public OptionValue { +class OptionValueString : public Cloneable<OptionValueString, OptionValue> { public: typedef Status (*ValidatorCallback)(const char *string, void *baton); enum Options { eOptionEncodeCharacterEscapeSequences = (1u << 0) }; - OptionValueString() - : OptionValue(), m_current_value(), m_default_value(), m_options(), - m_validator(), m_validator_baton() {} + OptionValueString() = default; OptionValueString(ValidatorCallback validator, void *baton = nullptr) - : OptionValue(), m_current_value(), m_default_value(), m_options(), - m_validator(validator), m_validator_baton(baton) {} + : m_validator(validator), m_validator_baton(baton) {} - OptionValueString(const char *value) - : OptionValue(), m_current_value(), m_default_value(), m_options(), - m_validator(), m_validator_baton() { + OptionValueString(const char *value) { if (value && value[0]) { m_current_value.assign(value); m_default_value.assign(value); } } - OptionValueString(const char *current_value, const char *default_value) - : OptionValue(), m_current_value(), m_default_value(), m_options(), - m_validator(), m_validator_baton() { + OptionValueString(const char *current_value, const char *default_value) { if (current_value && current_value[0]) m_current_value.assign(current_value); if (default_value && default_value[0]) @@ -51,8 +44,7 @@ public: OptionValueString(const char *value, ValidatorCallback validator, void *baton = nullptr) - : OptionValue(), m_current_value(), m_default_value(), m_options(), - m_validator(validator), m_validator_baton(baton) { + : m_validator(validator), m_validator_baton(baton) { if (value && value[0]) { m_current_value.assign(value); m_default_value.assign(value); @@ -61,8 +53,7 @@ public: OptionValueString(const char *current_value, const char *default_value, ValidatorCallback validator, void *baton = nullptr) - : OptionValue(), m_current_value(), m_default_value(), m_options(), - m_validator(validator), m_validator_baton(baton) { + : m_validator(validator), m_validator_baton(baton) { if (current_value && current_value[0]) m_current_value.assign(current_value); if (default_value && default_value[0]) @@ -81,17 +72,12 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { m_current_value = m_default_value; m_value_was_set = false; } - lldb::OptionValueSP DeepCopy() const override; - // Subclass specific functions Flags &GetOptions() { return m_options; } @@ -99,7 +85,7 @@ public: const Flags &GetOptions() const { return m_options; } const char *operator=(const char *value) { - SetCurrentValue(llvm::StringRef::withNullAsEmpty(value)); + SetCurrentValue(value); return m_current_value.c_str(); } @@ -109,7 +95,6 @@ public: const char *GetDefaultValue() const { return m_default_value.c_str(); } llvm::StringRef GetDefaultValueAsRef() const { return m_default_value; } - Status SetCurrentValue(const char *) = delete; Status SetCurrentValue(llvm::StringRef value); Status AppendToCurrentValue(const char *value); @@ -129,8 +114,8 @@ protected: std::string m_current_value; std::string m_default_value; Flags m_options; - ValidatorCallback m_validator; - void *m_validator_baton; + ValidatorCallback m_validator = nullptr; + void *m_validator_baton = nullptr; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueUInt64.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueUInt64.h index 1164fb802f68..f212b2a19def 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueUInt64.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueUInt64.h @@ -14,24 +14,22 @@ namespace lldb_private { -class OptionValueUInt64 : public OptionValue { +class OptionValueUInt64 : public Cloneable<OptionValueUInt64, OptionValue> { public: - OptionValueUInt64() : OptionValue(), m_current_value(0), m_default_value(0) {} + OptionValueUInt64() = default; OptionValueUInt64(uint64_t value) - : OptionValue(), m_current_value(value), m_default_value(value) {} + : m_current_value(value), m_default_value(value) {} OptionValueUInt64(uint64_t current_value, uint64_t default_value) - : OptionValue(), m_current_value(current_value), - m_default_value(default_value) {} + : m_current_value(current_value), m_default_value(default_value) {} - ~OptionValueUInt64() override {} + ~OptionValueUInt64() override = default; // Decode a uint64_t from "value_cstr" return a OptionValueUInt64 object // inside of a lldb::OptionValueSP object if all goes well. If the string // isn't a uint64_t value or any other error occurs, return an empty // lldb::OptionValueSP and fill error in with the correct stuff. - static lldb::OptionValueSP Create(const char *, Status &) = delete; static lldb::OptionValueSP Create(llvm::StringRef value_str, Status &error); // Virtual subclass pure virtual overrides @@ -43,17 +41,12 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { m_current_value = m_default_value; m_value_was_set = false; } - lldb::OptionValueSP DeepCopy() const override; - // Subclass specific functions const uint64_t &operator=(uint64_t value) { @@ -72,8 +65,8 @@ public: void SetDefaultValue(uint64_t value) { m_default_value = value; } protected: - uint64_t m_current_value; - uint64_t m_default_value; + uint64_t m_current_value = 0; + uint64_t m_default_value = 0; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueUUID.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueUUID.h index 1f663e999b9d..0ed490d1811d 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueUUID.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueUUID.h @@ -14,13 +14,13 @@ namespace lldb_private { -class OptionValueUUID : public OptionValue { +class OptionValueUUID : public Cloneable<OptionValueUUID, OptionValue> { public: - OptionValueUUID() : OptionValue(), m_uuid() {} + OptionValueUUID() = default; - OptionValueUUID(const UUID &uuid) : OptionValue(), m_uuid(uuid) {} + OptionValueUUID(const UUID &uuid) : m_uuid(uuid) {} - ~OptionValueUUID() override {} + ~OptionValueUUID() override = default; // Virtual subclass pure virtual overrides @@ -32,17 +32,12 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { m_uuid.Clear(); m_value_was_set = false; } - lldb::OptionValueSP DeepCopy() const override; - // Subclass specific functions UUID &GetCurrentValue() { return m_uuid; } diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/Options.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/Options.h index 9738cce2f7a1..6bf5c21fe98e 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/Options.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/Options.h @@ -254,8 +254,7 @@ public: class OptionGroupOptions : public Options { public: - OptionGroupOptions() - : Options(), m_option_defs(), m_option_infos(), m_did_finalize(false) {} + OptionGroupOptions() = default; ~OptionGroupOptions() override = default; @@ -318,7 +317,7 @@ public: std::vector<OptionDefinition> m_option_defs; OptionInfos m_option_infos; - bool m_did_finalize; + bool m_did_finalize = false; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptInterpreter.h index 4abd1ca68167..80a054b32ce6 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptInterpreter.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptInterpreter.h @@ -9,12 +9,15 @@ #ifndef LLDB_INTERPRETER_SCRIPTINTERPRETER_H #define LLDB_INTERPRETER_SCRIPTINTERPRETER_H +#include "lldb/API/SBData.h" +#include "lldb/API/SBError.h" #include "lldb/Breakpoint/BreakpointOptions.h" #include "lldb/Core/Communication.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Core/SearchFilter.h" #include "lldb/Core/StreamFile.h" #include "lldb/Host/PseudoTerminal.h" +#include "lldb/Interpreter/ScriptedProcessInterface.h" #include "lldb/Utility/Broadcaster.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StructuredData.h" @@ -34,6 +37,62 @@ private: operator=(const ScriptInterpreterLocker &) = delete; }; +class ExecuteScriptOptions { +public: + ExecuteScriptOptions() = default; + + bool GetEnableIO() const { return m_enable_io; } + + bool GetSetLLDBGlobals() const { return m_set_lldb_globals; } + + // If this is true then any exceptions raised by the script will be + // cleared with PyErr_Clear(). If false then they will be left for + // the caller to clean up + bool GetMaskoutErrors() const { return m_maskout_errors; } + + ExecuteScriptOptions &SetEnableIO(bool enable) { + m_enable_io = enable; + return *this; + } + + ExecuteScriptOptions &SetSetLLDBGlobals(bool set) { + m_set_lldb_globals = set; + return *this; + } + + ExecuteScriptOptions &SetMaskoutErrors(bool maskout) { + m_maskout_errors = maskout; + return *this; + } + +private: + bool m_enable_io = true; + bool m_set_lldb_globals = true; + bool m_maskout_errors = true; +}; + +class LoadScriptOptions { +public: + LoadScriptOptions() = default; + + bool GetInitSession() const { return m_init_session; } + bool GetSilent() const { return m_silent; } + + LoadScriptOptions &SetInitSession(bool b) { + m_init_session = b; + return *this; + } + + LoadScriptOptions &SetSilent(bool b) { + m_silent = b; + return *this; + } + +private: + bool m_init_session = false; + bool m_silent = false; +}; + class ScriptInterpreterIORedirect { public: /// Create an IO redirect. If IO is enabled, this will redirects the output @@ -83,44 +142,12 @@ public: eScriptReturnTypeOpaqueObject }; - ScriptInterpreter(Debugger &debugger, lldb::ScriptLanguage script_lang); - - ~ScriptInterpreter() override; - - struct ExecuteScriptOptions { - public: - ExecuteScriptOptions() - : m_enable_io(true), m_set_lldb_globals(true), m_maskout_errors(true) {} - - bool GetEnableIO() const { return m_enable_io; } - - bool GetSetLLDBGlobals() const { return m_set_lldb_globals; } + ScriptInterpreter( + Debugger &debugger, lldb::ScriptLanguage script_lang, + lldb::ScriptedProcessInterfaceUP scripted_process_interface_up = + std::make_unique<ScriptedProcessInterface>()); - // If this is true then any exceptions raised by the script will be - // cleared with PyErr_Clear(). If false then they will be left for - // the caller to clean up - bool GetMaskoutErrors() const { return m_maskout_errors; } - - ExecuteScriptOptions &SetEnableIO(bool enable) { - m_enable_io = enable; - return *this; - } - - ExecuteScriptOptions &SetSetLLDBGlobals(bool set) { - m_set_lldb_globals = set; - return *this; - } - - ExecuteScriptOptions &SetMaskoutErrors(bool maskout) { - m_maskout_errors = maskout; - return *this; - } - - private: - bool m_enable_io; - bool m_set_lldb_globals; - bool m_maskout_errors; - }; + ~ScriptInterpreter() override = default; virtual bool Interrupt() { return false; } @@ -334,18 +361,19 @@ public: } virtual void CollectDataForBreakpointCommandCallback( - std::vector<BreakpointOptions *> &options, CommandReturnObject &result); + std::vector<std::reference_wrapper<BreakpointOptions>> &options, + CommandReturnObject &result); virtual void CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options, CommandReturnObject &result); /// Set the specified text as the callback for the breakpoint. - Status - SetBreakpointCommandCallback(std::vector<BreakpointOptions *> &bp_options_vec, - const char *callback_text); + Status SetBreakpointCommandCallback( + std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec, + const char *callback_text); - virtual Status SetBreakpointCommandCallback(BreakpointOptions *bp_options, + virtual Status SetBreakpointCommandCallback(BreakpointOptions &bp_options, const char *callback_text) { Status error; error.SetErrorString("unimplemented"); @@ -354,7 +382,7 @@ public: /// This one is for deserialization: virtual Status SetBreakpointCommandCallback( - BreakpointOptions *bp_options, + BreakpointOptions &bp_options, std::unique_ptr<BreakpointOptions::CommandData> &data_up) { Status error; error.SetErrorString("unimplemented"); @@ -362,15 +390,14 @@ public: } Status SetBreakpointCommandCallbackFunction( - std::vector<BreakpointOptions *> &bp_options_vec, + std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec, const char *function_name, StructuredData::ObjectSP extra_args_sp); /// Set a script function as the callback for the breakpoint. virtual Status - SetBreakpointCommandCallbackFunction( - BreakpointOptions *bp_options, - const char *function_name, - StructuredData::ObjectSP extra_args_sp) { + SetBreakpointCommandCallbackFunction(BreakpointOptions &bp_options, + const char *function_name, + StructuredData::ObjectSP extra_args_sp) { Status error; error.SetErrorString("unimplemented"); return error; @@ -505,7 +532,7 @@ public: virtual bool CheckObjectExists(const char *name) { return false; } virtual bool - LoadScriptingModule(const char *filename, bool init_session, + LoadScriptingModule(const char *filename, const LoadScriptOptions &options, lldb_private::Status &error, StructuredData::ObjectSP *module_sp = nullptr, FileSpec extra_search_dir = {}); @@ -528,9 +555,19 @@ public: lldb::ScriptLanguage GetLanguage() { return m_script_lang; } + ScriptedProcessInterface &GetScriptedProcessInterface() { + return *m_scripted_process_interface_up; + } + + lldb::DataExtractorSP + GetDataExtractorFromSBData(const lldb::SBData &data) const; + + Status GetStatusFromSBError(const lldb::SBError &error) const; + protected: Debugger &m_debugger; lldb::ScriptLanguage m_script_lang; + lldb::ScriptedProcessInterfaceUP m_scripted_process_interface_up; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h new file mode 100644 index 000000000000..223e89be87ee --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h @@ -0,0 +1,68 @@ +//===-- ScriptedProcessInterface.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_SCRIPTEDPROCESSINTERFACE_H +#define LLDB_INTERPRETER_SCRIPTEDPROCESSINTERFACE_H + +#include "lldb/Core/StructuredDataImpl.h" +#include "lldb/Interpreter/ScriptInterpreter.h" +#include "lldb/lldb-private.h" + +#include <string> + +namespace lldb_private { +class ScriptedProcessInterface { +public: + ScriptedProcessInterface() : m_object_instance_sp(nullptr) {} + + virtual ~ScriptedProcessInterface() = default; + + virtual StructuredData::GenericSP + CreatePluginObject(const llvm::StringRef class_name, lldb::TargetSP target_sp, + StructuredData::DictionarySP args_sp) { + return nullptr; + } + + virtual Status Launch() { return Status("ScriptedProcess did not launch"); } + + virtual Status Resume() { return Status("ScriptedProcess did not resume"); } + + virtual bool ShouldStop() { return true; } + + virtual Status Stop() { return Status("ScriptedProcess did not stop"); } + + virtual lldb::MemoryRegionInfoSP + GetMemoryRegionContainingAddress(lldb::addr_t address) { + return nullptr; + } + + virtual StructuredData::DictionarySP GetThreadWithID(lldb::tid_t tid) { + return nullptr; + } + + virtual StructuredData::DictionarySP GetRegistersForThread(lldb::tid_t tid) { + return nullptr; + } + + virtual lldb::DataExtractorSP + ReadMemoryAtAddress(lldb::addr_t address, size_t size, Status &error) { + return nullptr; + } + + virtual StructuredData::DictionarySP GetLoadedImages() { return nullptr; } + + virtual lldb::pid_t GetProcessID() { return LLDB_INVALID_PROCESS_ID; } + + virtual bool IsAlive() { return true; } + +private: + StructuredData::ObjectSP m_object_instance_sp; +}; +} // namespace lldb_private + +#endif // LLDB_INTERPRETER_SCRIPTEDPROCESSINTERFACE_H diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/CompactUnwindInfo.h b/contrib/llvm-project/lldb/include/lldb/Symbol/CompactUnwindInfo.h index e622c5fde229..ceb501e1c05f 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/CompactUnwindInfo.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/CompactUnwindInfo.h @@ -50,21 +50,20 @@ private: // There are relatively few of these (one per 500/1000 functions, depending // on format) so creating them on first scan will not be too costly. struct UnwindIndex { - uint32_t function_offset; // The offset of the first function covered by - // this index - uint32_t second_level; // The offset (inside unwind_info sect) to the second - // level page for this index + uint32_t function_offset = 0; // The offset of the first function covered by + // this index + uint32_t second_level = 0; // The offset (inside unwind_info sect) to the + // second level page for this index // (either UNWIND_SECOND_LEVEL_REGULAR or UNWIND_SECOND_LEVEL_COMPRESSED) - uint32_t lsda_array_start; // The offset (inside unwind_info sect) LSDA - // array for this index - uint32_t lsda_array_end; // The offset to the LSDA array for the NEXT index - bool sentinal_entry; // There is an empty index at the end which provides - // the upper bound of + uint32_t lsda_array_start = 0; // The offset (inside unwind_info sect) LSDA + // array for this index + uint32_t lsda_array_end = + 0; // The offset to the LSDA array for the NEXT index + bool sentinal_entry = false; // There is an empty index at the end which + // provides the upper bound of // function addresses that are described - UnwindIndex() - : function_offset(0), second_level(0), lsda_array_start(0), - lsda_array_end(0), sentinal_entry(false) {} + UnwindIndex() = default; bool operator<(const CompactUnwindInfo::UnwindIndex &rhs) const { return function_offset < rhs.function_offset; @@ -78,30 +77,26 @@ private: // An internal object used to store the information we retrieve about a // function -- the encoding bits and possibly the LSDA/personality function. struct FunctionInfo { - uint32_t encoding; // compact encoding 32-bit value for this function + uint32_t encoding = 0; // compact encoding 32-bit value for this function Address lsda_address; // the address of the LSDA data for this function Address personality_ptr_address; // the address where the personality // routine addr can be found - uint32_t valid_range_offset_start; // first offset that this encoding is - // valid for (start of the function) - uint32_t - valid_range_offset_end; // the offset of the start of the next function - FunctionInfo() - : encoding(0), lsda_address(), personality_ptr_address(), - valid_range_offset_start(0), valid_range_offset_end(0) {} + uint32_t valid_range_offset_start = 0; // first offset that this encoding is + // valid for (start of the function) + uint32_t valid_range_offset_end = + 0; // the offset of the start of the next function + FunctionInfo() : lsda_address(), personality_ptr_address() {} }; struct UnwindHeader { uint32_t version; - uint32_t common_encodings_array_offset; - uint32_t common_encodings_array_count; - uint32_t personality_array_offset; - uint32_t personality_array_count; - - UnwindHeader() - : common_encodings_array_offset(0), common_encodings_array_count(0), - personality_array_offset(0), personality_array_count(0) {} + uint32_t common_encodings_array_offset = 0; + uint32_t common_encodings_array_count = 0; + uint32_t personality_array_offset = 0; + uint32_t personality_array_count = 0; + + UnwindHeader() = default; }; void ScanIndex(const lldb::ProcessSP &process_sp); diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/CompileUnit.h b/contrib/llvm-project/lldb/include/lldb/Symbol/CompileUnit.h index 256148f20d12..2e52bca7097c 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/CompileUnit.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/CompileUnit.h @@ -11,6 +11,7 @@ #include "lldb/Core/FileSpecList.h" #include "lldb/Core/ModuleChild.h" +#include "lldb/Core/SourceLocationSpec.h" #include "lldb/Symbol/DebugMacros.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/LineTable.h" @@ -345,29 +346,22 @@ public: /// Resolve symbol contexts by file and line. /// - /// Given a file in \a file_spec, and a line number, find all instances and + /// Given a file in \a src_location_spec, find all instances and /// append them to the supplied symbol context list \a sc_list. /// - /// \param[in] file_spec - /// A file specification. If \a file_spec contains no directory - /// information, only the basename will be used when matching - /// contexts. If the directory in \a file_spec is valid, a - /// complete file specification match will be performed. - /// - /// \param[in] line - /// The line number to match against the compile unit's line - /// tables. + /// \param[in] src_location_spec + /// The \a src_location_spec containing the \a file_spec, the line and the + /// column of the symbol to look for. Also hold the inlines and + /// exact_match flags. /// - /// \param[in] check_inlines - /// If \b true this function will also match any inline + /// If check_inlines is \b true, this function will also match any inline /// file and line matches. If \b false, the compile unit's /// file specification must match \a file_spec for any matches /// to be returned. /// - /// \param[in] exact - /// If true, only resolve the context if \a line exists in the line table. - /// If false, resolve the context to the closest line greater than \a line - /// in the line table. + /// If exact_match is \b true, only resolve the context if \a line and \a + /// column exists in the line table. If \b false, resolve the context to + /// the closest line greater than \a line in the line table. /// /// \param[in] resolve_scope /// For each matching line entry, this bitfield indicates what @@ -382,8 +376,7 @@ public: /// entries appended to. /// /// \see enum SymbolContext::Scope - void ResolveSymbolContext(const FileSpec &file_spec, uint32_t line, - bool check_inlines, bool exact, + void ResolveSymbolContext(const SourceLocationSpec &src_location_spec, lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list); diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/CompilerType.h b/contrib/llvm-project/lldb/include/lldb/Symbol/CompilerType.h index 5a0e8e57200d..0ad05a27570e 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/CompilerType.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/CompilerType.h @@ -71,10 +71,12 @@ public: bool IsValid() const { return m_type != nullptr && m_type_system != nullptr; } - bool IsArrayType(CompilerType *element_type, uint64_t *size, - bool *is_incomplete) const; + bool IsArrayType(CompilerType *element_type = nullptr, + uint64_t *size = nullptr, + bool *is_incomplete = nullptr) const; - bool IsVectorType(CompilerType *element_type, uint64_t *size) const; + bool IsVectorType(CompilerType *element_type = nullptr, + uint64_t *size = nullptr) const; bool IsArrayOfScalarType() const; @@ -110,7 +112,8 @@ public: bool IsFunctionPointerType() const; - bool IsBlockPointerType(CompilerType *function_pointer_type_ptr) const; + bool + IsBlockPointerType(CompilerType *function_pointer_type_ptr = nullptr) const; bool IsIntegerType(bool &is_signed) const; diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/DeclVendor.h b/contrib/llvm-project/lldb/include/lldb/Symbol/DeclVendor.h index 67dcaf1734bd..19ab2bb66e2c 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/DeclVendor.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/DeclVendor.h @@ -28,7 +28,7 @@ public: // Constructors and Destructors DeclVendor(DeclVendorKind kind) : m_kind(kind) {} - virtual ~DeclVendor() {} + virtual ~DeclVendor() = default; DeclVendorKind GetKind() const { return m_kind; } diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/Function.h b/contrib/llvm-project/lldb/include/lldb/Symbol/Function.h index 300d829219d4..b703617773ff 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/Function.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/Function.h @@ -10,10 +10,10 @@ #define LLDB_SYMBOL_FUNCTION_H #include "lldb/Core/AddressRange.h" +#include "lldb/Core/Declaration.h" #include "lldb/Core/Mangled.h" #include "lldb/Expression/DWARFExpression.h" #include "lldb/Symbol/Block.h" -#include "lldb/Symbol/Declaration.h" #include "lldb/Utility/UserID.h" #include "llvm/ADT/ArrayRef.h" @@ -271,7 +271,7 @@ using CallSiteParameterArray = llvm::SmallVector<CallSiteParameter, 0>; class CallEdge { public: enum class AddrType : uint8_t { Call, AfterCall }; - virtual ~CallEdge() {} + virtual ~CallEdge() = default; /// Get the callee's definition. /// @@ -631,10 +631,10 @@ public: lldb::DisassemblerSP GetInstructions(const ExecutionContext &exe_ctx, const char *flavor, - bool prefer_file_cache); + bool force_live_memory = false); bool GetDisassembly(const ExecutionContext &exe_ctx, const char *flavor, - bool prefer_file_cache, Stream &strm); + Stream &strm, bool force_live_memory = false); protected: enum { diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/LineEntry.h b/contrib/llvm-project/lldb/include/lldb/Symbol/LineEntry.h index 7e56ef814765..698d89974dc6 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/LineEntry.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/LineEntry.h @@ -140,10 +140,12 @@ struct LineEntry { FileSpec file; ///< The source file, possibly mapped by the target.source-map ///setting FileSpec original_file; ///< The original source file, from debug info. - uint32_t line; ///< The source line number, or zero if there is no line number - ///information. - uint16_t column; ///< The column number of the source line, or zero if there - ///is no column information. + uint32_t line = LLDB_INVALID_LINE_NUMBER; ///< The source line number, or zero + ///< if there is no line number + /// information. + uint16_t column = + 0; ///< The column number of the source line, or zero if there + /// is no column information. uint16_t is_start_of_statement : 1, ///< Indicates this entry is the beginning ///of a statement. is_start_of_basic_block : 1, ///< Indicates this entry is the beginning of diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/LineTable.h b/contrib/llvm-project/lldb/include/lldb/Symbol/LineTable.h index b48e82f19ffb..5cd22bd831ee 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/LineTable.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/LineTable.h @@ -12,6 +12,7 @@ #include "lldb/Core/Address.h" #include "lldb/Core/ModuleChild.h" #include "lldb/Core/Section.h" +#include "lldb/Core/SourceLocationSpec.h" #include "lldb/Symbol/LineEntry.h" #include "lldb/Utility/RangeMap.h" #include "lldb/lldb-private.h" @@ -137,12 +138,8 @@ public: /// CompileUnit::GetSupportFiles() /// FileSpecList::FindFileIndex (uint32_t, const FileSpec &) const /// - /// \param[in] line - /// The source line to match. - /// - /// \param[in] exact - /// If true, match only if you find a line entry exactly matching \a line. - /// If false, return the closest line entry greater than \a line. + /// \param[in] src_location_spec + /// The source location specifier to match. /// /// \param[out] line_entry_ptr /// A pointer to a line entry object that will get a copy of @@ -155,13 +152,14 @@ public: /// /// \see CompileUnit::GetSupportFiles() /// \see FileSpecList::FindFileIndex (uint32_t, const FileSpec &) const - uint32_t FindLineEntryIndexByFileIndex(uint32_t start_idx, uint32_t file_idx, - uint32_t line, bool exact, - LineEntry *line_entry_ptr); + uint32_t + FindLineEntryIndexByFileIndex(uint32_t start_idx, uint32_t file_idx, + const SourceLocationSpec &src_location_spec, + LineEntry *line_entry_ptr); uint32_t FindLineEntryIndexByFileIndex( - uint32_t start_idx, const std::vector<uint32_t> &file_indexes, - uint32_t line, bool exact, LineEntry *line_entry_ptr); + uint32_t start_idx, const std::vector<uint32_t> &file_idx, + const SourceLocationSpec &src_location_spec, LineEntry *line_entry_ptr); size_t FineLineEntriesForFileIndex(uint32_t file_idx, bool append, SymbolContextList &sc_list); @@ -211,10 +209,9 @@ public: protected: struct Entry { Entry() - : file_addr(LLDB_INVALID_ADDRESS), line(0), - is_start_of_statement(false), is_start_of_basic_block(false), + : line(0), is_start_of_statement(false), is_start_of_basic_block(false), is_prologue_end(false), is_epilogue_begin(false), - is_terminal_entry(false), column(0), file_idx(0) {} + is_terminal_entry(false) {} Entry(lldb::addr_t _file_addr, uint32_t _line, uint16_t _column, uint16_t _file_idx, bool _is_start_of_statement, @@ -281,7 +278,7 @@ protected: // Member variables. /// The file address for this line entry. - lldb::addr_t file_addr; + lldb::addr_t file_addr = LLDB_INVALID_ADDRESS; /// The source line number, or zero if there is no line number /// information. uint32_t line : 27; @@ -300,10 +297,10 @@ protected: uint32_t is_terminal_entry : 1; /// The column number of the source line, or zero if there is no /// column information. - uint16_t column; + uint16_t column = 0; /// The file index into CompileUnit's file table, or zero if there /// is no file information. - uint16_t file_idx; + uint16_t file_idx = 0; }; struct EntrySearchInfo { @@ -341,6 +338,75 @@ protected: private: LineTable(const LineTable &) = delete; const LineTable &operator=(const LineTable &) = delete; + + template <typename T> + uint32_t FindLineEntryIndexByFileIndexImpl( + uint32_t start_idx, T file_idx, + const SourceLocationSpec &src_location_spec, LineEntry *line_entry_ptr, + std::function<bool(T, uint16_t)> file_idx_matcher) { + const size_t count = m_entries.size(); + size_t best_match = UINT32_MAX; + + if (!line_entry_ptr) + return best_match; + + const uint32_t line = src_location_spec.GetLine().getValueOr(0); + const uint16_t column = + src_location_spec.GetColumn().getValueOr(LLDB_INVALID_COLUMN_NUMBER); + const bool exact_match = src_location_spec.GetExactMatch(); + + for (size_t idx = start_idx; idx < count; ++idx) { + // Skip line table rows that terminate the previous row (is_terminal_entry + // is non-zero) + if (m_entries[idx].is_terminal_entry) + continue; + + if (!file_idx_matcher(file_idx, m_entries[idx].file_idx)) + continue; + + // Exact match always wins. Otherwise try to find the closest line > the + // desired line. + // FIXME: Maybe want to find the line closest before and the line closest + // after and if they're not in the same function, don't return a match. + + if (column == LLDB_INVALID_COLUMN_NUMBER) { + if (m_entries[idx].line < line) { + continue; + } else if (m_entries[idx].line == line) { + ConvertEntryAtIndexToLineEntry(idx, *line_entry_ptr); + return idx; + } else if (!exact_match) { + if (best_match == UINT32_MAX || + m_entries[idx].line < m_entries[best_match].line) + best_match = idx; + } + } else { + if (m_entries[idx].line < line) { + continue; + } else if (m_entries[idx].line == line && + m_entries[idx].column == column) { + ConvertEntryAtIndexToLineEntry(idx, *line_entry_ptr); + return idx; + } else if (!exact_match) { + if (best_match == UINT32_MAX) + best_match = idx; + else if (m_entries[idx].line < m_entries[best_match].line) + best_match = idx; + else if (m_entries[idx].line == m_entries[best_match].line) + if (m_entries[idx].column && + m_entries[idx].column < m_entries[best_match].column) + best_match = idx; + } + } + } + + if (best_match != UINT32_MAX) { + if (line_entry_ptr) + ConvertEntryAtIndexToLineEntry(best_match, *line_entry_ptr); + return best_match; + } + return UINT32_MAX; + } }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/LocateSymbolFile.h b/contrib/llvm-project/lldb/include/lldb/Symbol/LocateSymbolFile.h index 93b76e53f41f..2c3f6a7b7b59 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/LocateSymbolFile.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/LocateSymbolFile.h @@ -9,7 +9,7 @@ #ifndef LLDB_SYMBOL_LOCATESYMBOLFILE_H #define LLDB_SYMBOL_LOCATESYMBOLFILE_H -#include <stdint.h> +#include <cstdint> #include "lldb/Core/FileSpecList.h" #include "lldb/Utility/FileSpec.h" diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/ObjectFile.h b/contrib/llvm-project/lldb/include/lldb/Symbol/ObjectFile.h index 080724cb86bd..4ccd7f92064d 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/ObjectFile.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/ObjectFile.h @@ -25,9 +25,9 @@ namespace lldb_private { class ObjectFileJITDelegate { public: - ObjectFileJITDelegate() {} + ObjectFileJITDelegate() = default; - virtual ~ObjectFileJITDelegate() {} + virtual ~ObjectFileJITDelegate() = default; virtual lldb::ByteOrder GetByteOrder() const = 0; @@ -495,6 +495,16 @@ public: return std::string(); } + /// Some object files may have the number of bits used for addressing + /// embedded in them, e.g. a Mach-O core file using an LC_NOTE. These + /// object files can return the address mask that should be used in + /// the Process. + /// \return + /// The mask will have bits set which aren't used for addressing -- + /// typically, the high bits. + /// Zero is returned when no address bits mask is available. + virtual lldb::addr_t GetAddressMask() { return 0; } + /// When the ObjectFile is a core file, lldb needs to locate the "binary" in /// the core file. lldb can iterate over the pages looking for a valid /// binary, but some core files may have metadata describing where the main @@ -666,6 +676,22 @@ public: /// Creates a plugin-specific call frame info virtual std::unique_ptr<CallFrameInfo> CreateCallFrameInfo(); + /// Load binaries listed in a corefile + /// + /// A corefile may have metadata listing binaries that can be loaded, + /// and the offsets at which they were loaded. This method will try + /// to add them to the Target. If any binaries were loaded, + /// + /// \param[in] process + /// Process where to load binaries. + /// + /// \return + /// Returns true if any binaries were loaded. + + virtual bool LoadCoreFileImages(lldb_private::Process &process) { + return false; + } + protected: // Member variables. FileSpec m_file; @@ -696,8 +722,6 @@ protected: /// false otherwise. bool SetModulesArchitecture(const ArchSpec &new_arch); - ConstString GetNextSyntheticSymbolName(); - static lldb::DataBufferSP MapFileData(const FileSpec &file, uint64_t Size, uint64_t Offset); diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/Symbol.h b/contrib/llvm-project/lldb/include/lldb/Symbol/Symbol.h index 3a235f260ba5..cb2385468702 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/Symbol.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/Symbol.h @@ -113,14 +113,20 @@ public: lldb::LanguageType GetLanguage() const { // TODO: See if there is a way to determine the language for a symbol // somehow, for now just return our best guess - return m_mangled.GuessLanguage(); + return GetMangled().GuessLanguage(); } void SetID(uint32_t uid) { m_uid = uid; } - Mangled &GetMangled() { return m_mangled; } + Mangled &GetMangled() { + SynthesizeNameIfNeeded(); + return m_mangled; + } - const Mangled &GetMangled() const { return m_mangled; } + const Mangled &GetMangled() const { + SynthesizeNameIfNeeded(); + return m_mangled; + } ConstString GetReExportedSymbolName() const; @@ -149,6 +155,8 @@ public: bool IsSynthetic() const { return m_is_synthetic; } + bool IsSyntheticWithAutoGeneratedName() const; + void SetIsSynthetic(bool b) { m_is_synthetic = b; } bool GetSizeIsSynthesized() const { return m_size_is_synthesized; } @@ -166,9 +174,9 @@ public: bool IsTrampoline() const; bool IsIndirect() const; - + bool IsWeak() const { return m_is_weak; } - + void SetIsWeak (bool b) { m_is_weak = b; } bool GetByteSizeIsValid() const { return m_size_is_valid; } @@ -223,6 +231,10 @@ public: bool ContainsFileAddress(lldb::addr_t file_addr) const; + static llvm::StringRef GetSyntheticSymbolPrefix() { + return "___lldb_unnamed_symbol"; + } + protected: // This is the internal guts of ResolveReExportedSymbol, it assumes // reexport_name is not null, and that module_spec is valid. We track the @@ -233,8 +245,11 @@ protected: lldb_private::ModuleSpec &module_spec, lldb_private::ModuleList &seen_modules) const; - uint32_t m_uid; // User ID (usually the original symbol table index) - uint16_t m_type_data; // data specific to m_type + void SynthesizeNameIfNeeded() const; + + uint32_t m_uid = + UINT32_MAX; // User ID (usually the original symbol table index) + uint16_t m_type_data = 0; // data specific to m_type uint16_t m_type_data_resolved : 1, // True if the data in m_type_data has // already been calculated m_is_synthetic : 1, // non-zero if this symbol is not actually in the @@ -257,12 +272,12 @@ protected: // doing name lookups m_is_weak : 1, m_type : 6; // Values from the lldb::SymbolType enum. - Mangled m_mangled; // uniqued symbol name/mangled name pair + mutable Mangled m_mangled; // uniqued symbol name/mangled name pair AddressRange m_addr_range; // Contains the value, or the section offset // address when the value is an address in a // section, and the size (if any) - uint32_t m_flags; // A copy of the flags from the original symbol table, the - // ObjectFile plug-in can interpret these + uint32_t m_flags = 0; // A copy of the flags from the original symbol table, + // the ObjectFile plug-in can interpret these }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolContext.h b/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolContext.h index c513dbb447f8..cac951bc19b9 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolContext.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolContext.h @@ -150,8 +150,8 @@ public: 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, - bool show_inline_callsite_line_info = true) const; + bool show_function_arguments, + bool show_function_name) const; /// Get the address range contained within a symbol context. /// @@ -316,12 +316,13 @@ public: // Member variables lldb::TargetSP target_sp; ///< The Target for a given query lldb::ModuleSP module_sp; ///< The Module for a given query - CompileUnit *comp_unit; ///< The CompileUnit for a given query - Function *function; ///< The Function for a given query - Block *block; ///< The Block for a given query + CompileUnit *comp_unit = nullptr; ///< The CompileUnit for a given query + Function *function = nullptr; ///< The Function for a given query + Block *block = nullptr; ///< The Block for a given query LineEntry line_entry; ///< The LineEntry for a given query - Symbol *symbol; ///< The Symbol for a given query - Variable *variable; ///< The global variable matching the given query + Symbol *symbol = nullptr; ///< The Symbol for a given query + Variable *variable = + nullptr; ///< The global variable matching the given query }; class SymbolContextSpecifier { diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolFile.h b/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolFile.h index 9f5806915dcb..ffdbdc6853f7 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolFile.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolFile.h @@ -10,6 +10,7 @@ #define LLDB_SYMBOL_SYMBOLFILE_H #include "lldb/Core/PluginInterface.h" +#include "lldb/Core/SourceLocationSpec.h" #include "lldb/Symbol/CompilerDecl.h" #include "lldb/Symbol/CompilerDeclContext.h" #include "lldb/Symbol/CompilerType.h" @@ -68,7 +69,7 @@ public: : m_objfile_sp(std::move(objfile_sp)), m_abilities(0), m_calculated_abilities(false) {} - ~SymbolFile() override {} + ~SymbolFile() override = default; /// Get a mask of what this symbol file supports for the object file /// that it was constructed with. @@ -209,10 +210,10 @@ public: virtual uint32_t ResolveSymbolContext(const Address &so_addr, lldb::SymbolContextItem resolve_scope, SymbolContext &sc) = 0; - virtual uint32_t ResolveSymbolContext(const FileSpec &file_spec, - uint32_t line, bool check_inlines, - lldb::SymbolContextItem resolve_scope, - SymbolContextList &sc_list); + virtual uint32_t + ResolveSymbolContext(const SourceLocationSpec &src_location_spec, + lldb::SymbolContextItem resolve_scope, + SymbolContextList &sc_list); virtual void DumpClangAST(Stream &s) {} virtual void FindGlobalVariables(ConstString name, diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/Symtab.h b/contrib/llvm-project/lldb/include/lldb/Symbol/Symtab.h index c232925eec75..e1ad0dfd2eb8 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/Symtab.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/Symtab.h @@ -13,6 +13,7 @@ #include "lldb/Symbol/Symbol.h" #include "lldb/Utility/RangeMap.h" #include "lldb/lldb-private.h" +#include <map> #include <mutex> #include <vector> @@ -173,15 +174,21 @@ protected: ObjectFile *m_objfile; collection m_symbols; FileRangeToIndexMap m_file_addr_to_index; - UniqueCStringMap<uint32_t> m_name_to_index; - UniqueCStringMap<uint32_t> m_basename_to_index; - UniqueCStringMap<uint32_t> m_method_to_index; - UniqueCStringMap<uint32_t> m_selector_to_index; + + /// Maps function names to symbol indices (grouped by FunctionNameTypes) + std::map<lldb::FunctionNameType, UniqueCStringMap<uint32_t>> + m_name_to_symbol_indices; mutable std::recursive_mutex m_mutex; // Provide thread safety for this symbol table bool m_file_addr_to_index_computed : 1, m_name_indexes_computed : 1; private: + UniqueCStringMap<uint32_t> & + GetNameToSymbolIndexMap(lldb::FunctionNameType type) { + auto map = m_name_to_symbol_indices.find(type); + assert(map != m_name_to_symbol_indices.end()); + return map->second; + } bool CheckSymbolAtIndex(size_t idx, Debug symbol_debug_type, Visibility symbol_visibility) const { switch (symbol_debug_type) { @@ -212,6 +219,26 @@ private: return false; } + /// A helper function that looks up full function names. + /// + /// We generate unique names for synthetic symbols so that users can look + /// them up by name when needed. But because doing so is uncommon in normal + /// debugger use, we trade off some performance at lookup time for faster + /// symbol table building by detecting these symbols and generating their + /// names lazily, rather than adding them to the normal symbol indexes. This + /// function does the job of first consulting the name indexes, and if that + /// fails it extracts the information it needs from the synthetic name and + /// locates the symbol. + /// + /// @param[in] symbol_name The symbol name to search for. + /// + /// @param[out] indexes The vector if symbol indexes to update with results. + /// + /// @returns The number of indexes added to the index vector. Zero if no + /// matches were found. + uint32_t GetNameIndexes(ConstString symbol_name, + std::vector<uint32_t> &indexes); + void SymbolIndicesToSymbolContextList(std::vector<uint32_t> &symbol_indexes, SymbolContextList &sc_list); diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/TaggedASTType.h b/contrib/llvm-project/lldb/include/lldb/Symbol/TaggedASTType.h index f02f99258a3f..fe1a2c659d9f 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/TaggedASTType.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/TaggedASTType.h @@ -27,7 +27,7 @@ public: TaggedASTType() : CompilerType() {} - virtual ~TaggedASTType() {} + virtual ~TaggedASTType() = default; TaggedASTType<C> &operator=(const TaggedASTType<C> &tw) { CompilerType::operator=(tw); diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/Type.h b/contrib/llvm-project/lldb/include/lldb/Symbol/Type.h index dd917cfb7ca8..9e671a565dd1 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/Type.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/Type.h @@ -9,9 +9,9 @@ #ifndef LLDB_SYMBOL_TYPE_H #define LLDB_SYMBOL_TYPE_H +#include "lldb/Core/Declaration.h" #include "lldb/Symbol/CompilerDecl.h" #include "lldb/Symbol/CompilerType.h" -#include "lldb/Symbol/Declaration.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/UserID.h" #include "lldb/lldb-private.h" @@ -51,7 +51,7 @@ public: SymbolFileType(SymbolFile &symbol_file, const lldb::TypeSP &type_sp); - ~SymbolFileType() {} + ~SymbolFileType() = default; Type *operator->() { return GetType(); } @@ -213,17 +213,17 @@ public: protected: ConstString m_name; - SymbolFile *m_symbol_file; + SymbolFile *m_symbol_file = nullptr; /// The symbol context in which this type is defined. - SymbolContextScope *m_context; - Type *m_encoding_type; - lldb::user_id_t m_encoding_uid; - EncodingDataType m_encoding_uid_type; + SymbolContextScope *m_context = nullptr; + Type *m_encoding_type = nullptr; + lldb::user_id_t m_encoding_uid = LLDB_INVALID_UID; + EncodingDataType m_encoding_uid_type = eEncodingInvalid; uint64_t m_byte_size : 63; uint64_t m_byte_size_has_value : 1; Declaration m_decl; CompilerType m_compiler_type; - ResolveState m_compiler_type_resolve_state; + ResolveState m_compiler_type_resolve_state = ResolveState::Unresolved; /// Language-specific flags. Payload m_payload; @@ -239,7 +239,7 @@ class TypeImpl { public: TypeImpl() = default; - ~TypeImpl() {} + ~TypeImpl() = default; TypeImpl(const lldb::TypeSP &type_sp); @@ -340,8 +340,7 @@ private: class TypeMemberImpl { public: TypeMemberImpl() - : m_type_impl_sp(), m_bit_offset(0), m_name(), m_bitfield_bit_size(0), - m_is_bitfield(false) + : m_type_impl_sp(), m_name() {} @@ -376,10 +375,10 @@ public: protected: lldb::TypeImplSP m_type_impl_sp; - uint64_t m_bit_offset; + uint64_t m_bit_offset = 0; ConstString m_name; - uint32_t m_bitfield_bit_size; // Bit size for bitfield members only - bool m_is_bitfield; + uint32_t m_bitfield_bit_size = 0; // Bit size for bitfield members only + bool m_is_bitfield = false; }; /// @@ -435,9 +434,7 @@ private: class TypeMemberFunctionImpl { public: - TypeMemberFunctionImpl() - : m_type(), m_decl(), m_name(), m_kind(lldb::eMemberFunctionKindUnknown) { - } + TypeMemberFunctionImpl() : m_type(), m_decl(), m_name() {} TypeMemberFunctionImpl(const CompilerType &type, const CompilerDecl &decl, const std::string &name, @@ -469,13 +466,12 @@ private: CompilerType m_type; CompilerDecl m_decl; ConstString m_name; - lldb::MemberFunctionKind m_kind; + lldb::MemberFunctionKind m_kind = lldb::eMemberFunctionKindUnknown; }; class TypeEnumMemberImpl { public: - TypeEnumMemberImpl() - : m_integer_type_sp(), m_name("<invalid>"), m_value(), m_valid(false) {} + TypeEnumMemberImpl() : m_integer_type_sp(), m_name("<invalid>"), m_value() {} TypeEnumMemberImpl(const lldb::TypeImplSP &integer_type_sp, ConstString name, const llvm::APSInt &value); @@ -498,7 +494,7 @@ protected: lldb::TypeImplSP m_integer_type_sp; ConstString m_name; llvm::APSInt m_value; - bool m_valid; + bool m_valid = false; }; class TypeEnumMemberListImpl { diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/TypeSystem.h b/contrib/llvm-project/lldb/include/lldb/Symbol/TypeSystem.h index 1fad8f61ac37..a37c1040b16e 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/TypeSystem.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/TypeSystem.h @@ -524,7 +524,7 @@ protected: mutable std::mutex m_mutex; ///< A mutex to keep this object happy in ///multi-threaded environments. collection m_map; - bool m_clear_in_progress; + bool m_clear_in_progress = false; private: typedef llvm::function_ref<lldb::TypeSystemSP()> CreateCallback; diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/UnwindPlan.h b/contrib/llvm-project/lldb/include/lldb/Symbol/UnwindPlan.h index 40814da3de4a..cc2302d25831 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/UnwindPlan.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/UnwindPlan.h @@ -71,7 +71,7 @@ public: isDWARFExpression // reg = eval(dwarf_expr) }; - RegisterLocation() : m_type(unspecified), m_location() {} + RegisterLocation() : m_location() {} bool operator==(const RegisterLocation &rhs) const; @@ -181,7 +181,7 @@ public: const UnwindPlan::Row *row, Thread *thread, bool verbose) const; private: - RestoreType m_type; // How do we locate this register? + RestoreType m_type = unspecified; // How do we locate this register? union { // For m_type == atCFAPlusOffset or m_type == isCFAPlusOffset int32_t offset; @@ -205,7 +205,7 @@ public: isRaSearch, // FA = SP + offset + ??? }; - FAValue() : m_type(unspecified), m_value() {} + FAValue() : m_value() {} bool operator==(const FAValue &rhs) const; @@ -301,7 +301,7 @@ public: void Dump(Stream &s, const UnwindPlan *unwind_plan, Thread *thread) const; private: - ValueType m_type; // How do we compute CFA value? + ValueType m_type = unspecified; // How do we compute CFA value? union { struct { // For m_type == isRegisterPlusOffset or m_type == @@ -322,8 +322,6 @@ public: Row(); - Row(const UnwindPlan::Row &rhs) = default; - bool operator==(const Row &rhs) const; bool GetRegisterInfo(uint32_t reg_num, @@ -360,6 +358,25 @@ public: bool SetRegisterLocationToSame(uint32_t reg_num, bool must_replace); + // When this UnspecifiedRegistersAreUndefined mode is + // set, any register that is not specified by this Row will + // be described as Undefined. + // This will prevent the unwinder from iterating down the + // stack looking for a spill location, or a live register value + // at frame 0. + // It would be used for an UnwindPlan row where we can't track + // spilled registers -- for instance a jitted stack frame where + // we have no unwind information or start address -- and registers + // MAY have been spilled and overwritten, so providing the + // spilled/live value from a newer frame may show an incorrect value. + void SetUnspecifiedRegistersAreUndefined(bool unspec_is_undef) { + m_unspecified_registers_are_undefined = unspec_is_undef; + } + + bool GetUnspecifiedRegistersAreUndefined() { + return m_unspecified_registers_are_undefined; + } + void Clear(); void Dump(Stream &s, const UnwindPlan *unwind_plan, Thread *thread, @@ -367,11 +384,12 @@ public: protected: typedef std::map<uint32_t, RegisterLocation> collection; - lldb::addr_t m_offset; // Offset into the function for this row + lldb::addr_t m_offset = 0; // Offset into the function for this row FAValue m_cfa_value; FAValue m_afa_value; collection m_register_locations; + bool m_unspecified_registers_are_undefined = false; }; // class Row typedef std::shared_ptr<Row> RowSP; diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/Variable.h b/contrib/llvm-project/lldb/include/lldb/Symbol/Variable.h index 0dcbbd8e4c8e..ccd5072c3d23 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/Variable.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/Variable.h @@ -9,9 +9,9 @@ #ifndef LLDB_SYMBOL_VARIABLE_H #define LLDB_SYMBOL_VARIABLE_H +#include "lldb/Core/Declaration.h" #include "lldb/Core/Mangled.h" #include "lldb/Expression/DWARFExpression.h" -#include "lldb/Symbol/Declaration.h" #include "lldb/Utility/CompletionRequest.h" #include "lldb/Utility/RangeMap.h" #include "lldb/Utility/UserID.h" diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ABI.h b/contrib/llvm-project/lldb/include/lldb/Target/ABI.h index 131b2eaff765..8fbb6aae68c4 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/ABI.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/ABI.h @@ -117,12 +117,13 @@ public: // "pc". virtual bool CodeAddressIsValid(lldb::addr_t pc) = 0; - virtual lldb::addr_t FixCodeAddress(lldb::addr_t pc) { - // Some targets might use bits in a code address to indicate a mode switch. - // ARM uses bit zero to signify a code address is thumb, so any ARM ABI - // plug-ins would strip those bits. - return pc; - } + /// Some targets might use bits in a code address to indicate a mode switch. + /// ARM uses bit zero to signify a code address is thumb, so any ARM ABI + /// plug-ins would strip those bits. + /// @{ + virtual lldb::addr_t FixCodeAddress(lldb::addr_t pc) { return pc; } + virtual lldb::addr_t FixDataAddress(lldb::addr_t pc) { return pc; } + /// @} llvm::MCRegisterInfo &GetMCRegisterInfo() { return *m_mc_register_info_up; } @@ -147,6 +148,10 @@ protected: lldb::ProcessWP m_process_wp; std::unique_ptr<llvm::MCRegisterInfo> m_mc_register_info_up; + virtual lldb::addr_t FixCodeAddress(lldb::addr_t pc, lldb::addr_t mask) { + return pc; + } + private: ABI(const ABI &) = delete; const ABI &operator=(const ABI &) = delete; diff --git a/contrib/llvm-project/lldb/include/lldb/Target/DynamicLoader.h b/contrib/llvm-project/lldb/include/lldb/Target/DynamicLoader.h index dead3eec7013..a904fac0c779 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/DynamicLoader.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/DynamicLoader.h @@ -18,8 +18,8 @@ #include "lldb/lldb-private-enumerations.h" #include "lldb/lldb-types.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class ModuleList; class Process; @@ -251,6 +251,14 @@ public: return false; } + /// Return whether the dynamic loader is fully initialized and it's safe to + /// call its APIs. + /// + /// On some systems (e.g. Darwin based systems), lldb will get notified by + /// the dynamic loader before it itself finished initializing and it's not + /// safe to call certain APIs or SPIs. + virtual bool IsFullyInitialized() { return true; } + protected: // Utility methods for derived classes @@ -294,7 +302,7 @@ protected: // Read a pointer from memory at the given addr. Return LLDB_INVALID_ADDRESS // if the read fails. lldb::addr_t ReadPointer(lldb::addr_t addr); - + // Calls into the Process protected method LoadOperatingSystemPlugin: void LoadOperatingSystemPlugin(bool flush); diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ExecutionContext.h b/contrib/llvm-project/lldb/include/lldb/Target/ExecutionContext.h index 169d56ac9b64..d8c233a666bb 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/ExecutionContext.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/ExecutionContext.h @@ -263,8 +263,9 @@ protected: lldb::TargetWP m_target_wp; ///< A weak reference to a target lldb::ProcessWP m_process_wp; ///< A weak reference to a process mutable lldb::ThreadWP m_thread_wp; ///< A weak reference to a thread - lldb::tid_t m_tid; ///< The thread ID that this object refers to in case the - ///backing object changes + lldb::tid_t m_tid = LLDB_INVALID_THREAD_ID; ///< The thread ID that this + ///< object refers to in case the + /// backing object changes StackID m_stack_id; ///< The stack ID that this object refers to in case the ///backing object changes }; diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ExecutionContextScope.h b/contrib/llvm-project/lldb/include/lldb/Target/ExecutionContextScope.h index d7003e9a572e..4f5b08ed618c 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/ExecutionContextScope.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/ExecutionContextScope.h @@ -31,7 +31,7 @@ namespace lldb_private { /// context to allow functions that take a execution contexts to be called. class ExecutionContextScope { public: - virtual ~ExecutionContextScope() {} + virtual ~ExecutionContextScope() = default; virtual lldb::TargetSP CalculateTarget() = 0; diff --git a/contrib/llvm-project/lldb/include/lldb/Target/InstrumentationRuntimeStopInfo.h b/contrib/llvm-project/lldb/include/lldb/Target/InstrumentationRuntimeStopInfo.h index 2cbf27d7b343..534516085091 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/InstrumentationRuntimeStopInfo.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/InstrumentationRuntimeStopInfo.h @@ -18,7 +18,7 @@ namespace lldb_private { class InstrumentationRuntimeStopInfo : public StopInfo { public: - ~InstrumentationRuntimeStopInfo() override {} + ~InstrumentationRuntimeStopInfo() override = default; lldb::StopReason GetStopReason() const override { return lldb::eStopReasonInstrumentation; diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Language.h b/contrib/llvm-project/lldb/include/lldb/Target/Language.h index 6368828e36da..11b9daa38945 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/Language.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/Language.h @@ -184,14 +184,31 @@ public: virtual const char *GetLanguageSpecificTypeLookupHelp(); + class MethodNameVariant { + ConstString m_name; + lldb::FunctionNameType m_type; + + public: + MethodNameVariant(ConstString name, lldb::FunctionNameType type) + : m_name(name), m_type(type) {} + ConstString GetName() const { return m_name; } + lldb::FunctionNameType GetType() const { return m_type; } + }; // If a language can have more than one possible name for a method, this // function can be used to enumerate them. This is useful when doing name // lookups. - virtual std::vector<ConstString> + virtual std::vector<Language::MethodNameVariant> GetMethodNameVariants(ConstString method_name) const { - return std::vector<ConstString>(); + return std::vector<Language::MethodNameVariant>(); }; + /// Returns true iff the given symbol name is compatible with the mangling + /// scheme of this language. + /// + /// This function should only return true if there is a high confidence + /// that the name actually belongs to this language. + virtual bool SymbolNameFitsToLanguage(Mangled name) const { return false; } + // if an individual data formatter can apply to several types and cross a // language boundary it makes sense for individual languages to want to // customize the printing of values of that type by appending proper diff --git a/contrib/llvm-project/lldb/include/lldb/Target/LanguageRuntime.h b/contrib/llvm-project/lldb/include/lldb/Target/LanguageRuntime.h index a3897adfe46a..2f95c2643318 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/LanguageRuntime.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/LanguageRuntime.h @@ -173,7 +173,51 @@ public: virtual bool isA(const void *ClassID) const { return ClassID == &ID; } static char ID; + /// A language runtime may be able to provide a special UnwindPlan for + /// the frame represented by the register contents \a regctx when that + /// frame is not following the normal ABI conventions. + /// Instead of using the normal UnwindPlan for the function, we will use + /// this special UnwindPlan for this one backtrace. + /// One example of this would be a language that has asynchronous functions, + /// functions that may not be currently-executing, while waiting on other + /// asynchronous calls they made, but are part of a logical backtrace that + /// we want to show the developer because that's how they think of the + /// program flow. + /// + /// \param[in] thread + /// The thread that the unwind is happening on. + /// + /// \param[in] regctx + /// The RegisterContext for the frame we need to create an UnwindPlan. + /// We don't yet have a StackFrame when we're selecting the UnwindPlan. + /// + /// \param[out] behaves_like_zeroth_frame + /// With normal ABI calls, all stack frames except the zeroth frame need + /// to have the return-pc value backed up by 1 for symbolication purposes. + /// For these LanguageRuntime unwind plans, they may not follow normal ABI + /// calling conventions and the return pc may need to be symbolicated + /// as-is. + /// + /// \return + /// Returns an UnwindPlan to find the caller frame if it should be used, + /// instead of the UnwindPlan that would normally be used for this + /// function. + static lldb::UnwindPlanSP + GetRuntimeUnwindPlan(lldb_private::Thread &thread, + lldb_private::RegisterContext *regctx, + bool &behaves_like_zeroth_frame); + protected: + // The static GetRuntimeUnwindPlan method above is only implemented in the + // base class; subclasses may override this protected member if they can + // provide one of these UnwindPlans. + virtual lldb::UnwindPlanSP + GetRuntimeUnwindPlan(lldb::ProcessSP process_sp, + lldb_private::RegisterContext *regctx, + bool &behaves_like_zeroth_frame) { + return lldb::UnwindPlanSP(); + } + LanguageRuntime(Process *process); }; diff --git a/contrib/llvm-project/lldb/include/lldb/Target/MemoryRegionInfo.h b/contrib/llvm-project/lldb/include/lldb/Target/MemoryRegionInfo.h index 392e1edd273e..bc5ced64cc21 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/MemoryRegionInfo.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/MemoryRegionInfo.h @@ -10,8 +10,11 @@ #ifndef LLDB_TARGET_MEMORYREGIONINFO_H #define LLDB_TARGET_MEMORYREGIONINFO_H +#include <vector> + #include "lldb/Utility/ConstString.h" #include "lldb/Utility/RangeMap.h" +#include "llvm/ADT/Optional.h" #include "llvm/Support/FormatProviders.h" namespace lldb_private { @@ -32,10 +35,7 @@ public: RangeType &GetRange() { return m_range; } - void Clear() { - m_range.Clear(); - m_read = m_write = m_execute = m_memory_tagged = eDontKnow; - } + void Clear() { *this = MemoryRegionInfo(); } const RangeType &GetRange() const { return m_range; } @@ -97,11 +97,33 @@ public: 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_memory_tagged == rhs.m_memory_tagged; + m_memory_tagged == rhs.m_memory_tagged && + m_pagesize == rhs.m_pagesize; } bool operator!=(const MemoryRegionInfo &rhs) const { return !(*this == rhs); } + /// Get the target system's VM page size in bytes. + /// \return + /// 0 is returned if this information is unavailable. + int GetPageSize() { return m_pagesize; } + + /// Get a vector of target VM pages that are dirty -- that have been + /// modified -- within this memory region. This is an Optional return + /// value; it will only be available if the remote stub was able to + /// detail this. + llvm::Optional<std::vector<lldb::addr_t>> &GetDirtyPageList() { + return m_dirty_pages; + } + + void SetPageSize(int pagesize) { m_pagesize = pagesize; } + + void SetDirtyPageList(std::vector<lldb::addr_t> pagelist) { + if (m_dirty_pages.hasValue()) + m_dirty_pages.getValue().clear(); + m_dirty_pages = std::move(pagelist); + } + protected: RangeType m_range; OptionalBool m_read = eDontKnow; @@ -112,6 +134,8 @@ protected: OptionalBool m_flash = eDontKnow; lldb::offset_t m_blocksize = 0; OptionalBool m_memory_tagged = eDontKnow; + int m_pagesize = 0; + llvm::Optional<std::vector<lldb::addr_t>> m_dirty_pages; }; inline bool operator<(const MemoryRegionInfo &lhs, diff --git a/contrib/llvm-project/lldb/include/lldb/Target/MemoryTagManager.h b/contrib/llvm-project/lldb/include/lldb/Target/MemoryTagManager.h new file mode 100644 index 000000000000..a5e0deba14a9 --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Target/MemoryTagManager.h @@ -0,0 +1,135 @@ +//===-- MemoryTagManager.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_MEMORYTAGMANAGER_H +#define LLDB_TARGET_MEMORYTAGMANAGER_H + +#include "lldb/Target/MemoryRegionInfo.h" +#include "lldb/Utility/RangeMap.h" +#include "lldb/lldb-private.h" +#include "llvm/Support/Error.h" + +namespace lldb_private { + +// This interface allows high level commands to handle memory tags +// in a generic way. +// +// Definitions: +// logical tag - the tag stored in a pointer +// allocation tag - the tag stored in hardware +// (e.g. special memory, cache line bits) +// granule - number of bytes of memory a single tag applies to + +class MemoryTagManager { +public: + typedef Range<lldb::addr_t, lldb::addr_t> TagRange; + + // Extract the logical tag from a pointer + // The tag is returned as a plain value, with any shifts removed. + // For example if your tags are stored in bits 56-60 then the logical tag + // you get will have been shifted down 56 before being returned. + virtual lldb::addr_t GetLogicalTag(lldb::addr_t addr) const = 0; + + // Remove non address bits from a pointer + virtual lldb::addr_t RemoveNonAddressBits(lldb::addr_t addr) const = 0; + + // Return the difference between two addresses, ignoring any logical tags they + // have. If your tags are just part of a larger set of ignored bits, this + // should ignore all those bits. + virtual ptrdiff_t AddressDiff(lldb::addr_t addr1, + lldb::addr_t addr2) const = 0; + + // Return the number of bytes a single tag covers + virtual lldb::addr_t GetGranuleSize() const = 0; + + // Align an address range to granule boundaries. + // So that reading memory tags for the new range returns + // tags that will cover the original range. + // + // Say your granules are 16 bytes and you want + // tags for 16 bytes of memory starting from address 8. + // 1 granule isn't enough because it only covers addresses + // 0-16, we want addresses 8-24. So the range must be + // expanded to 2 granules. + virtual TagRange ExpandToGranule(TagRange range) const = 0; + + // Given a range addr to end_addr, check that: + // * end_addr >= addr (when memory tags are removed) + // * the granule aligned range is completely covered by tagged memory + // (which may include one or more memory regions) + // + // If so, return a modified range which will have been expanded + // to be granule aligned. + // + // Tags in the input addresses are ignored and not present + // in the returned range. + virtual llvm::Expected<TagRange> MakeTaggedRange( + lldb::addr_t addr, lldb::addr_t end_addr, + const lldb_private::MemoryRegionInfos &memory_regions) const = 0; + + // Return the type value to use in GDB protocol qMemTags packets to read + // allocation tags. This is named "Allocation" specifically because the spec + // allows for logical tags to be read the same way, though we do not use that. + // + // This value is unique within a given architecture. Meaning that different + // tagging schemes within the same architecture should use unique values, + // but other architectures can overlap those values. + virtual int32_t GetAllocationTagType() const = 0; + + // Return the number of bytes a single tag will be packed into during + // transport. For example an MTE tag is 4 bits but occupies 1 byte during + // transport. + virtual size_t GetTagSizeInBytes() const = 0; + + // Unpack tags from their stored format (e.g. gdb qMemTags data) into seperate + // tags. + // + // Checks that each tag is within the expected value range and if granules is + // set to non-zero, that the number of tags found matches the number of + // granules we expected to cover. + virtual llvm::Expected<std::vector<lldb::addr_t>> + UnpackTagsData(const std::vector<uint8_t> &tags, + size_t granules = 0) const = 0; + + // Pack uncompressed tags into their storage format (e.g. for gdb QMemTags). + // Checks that each tag is within the expected value range. + // We do not check the number of tags or range they apply to because + // it is up to the remote to repeat them as needed. + virtual llvm::Expected<std::vector<uint8_t>> + PackTags(const std::vector<lldb::addr_t> &tags) const = 0; + + // Take a set of tags and repeat them as much as needed to cover the given + // range. We assume that this range has been previously expanded/aligned to + // granules. (this method is used by lldb-server to implement QMemTags + // packet handling) + // + // If the range is empty, zero tags are returned. + // If the range is not empty and... + // * there are no tags, an error is returned. + // * there are fewer tags than granules, the tags are repeated to fill the + // range. + // * there are more tags than granules, only the tags required to cover + // the range are returned. + // + // When repeating tags it will not always return a multiple of the original + // list. For example if your range is 3 granules and your tags are 1 and 2. + // You will get tags 1, 2 and 1 returned. Rather than getting 1, 2, 1, 2, + // which would be one too many tags for the range. + // + // A single tag will just be repeated as you'd expected. Tag 1 over 3 granules + // would return 1, 1, 1. + virtual llvm::Expected<std::vector<lldb::addr_t>> + RepeatTagsForRange(const std::vector<lldb::addr_t> &tags, + TagRange range) const = 0; + + virtual ~MemoryTagManager() {} +}; + +} // namespace lldb_private + +#endif // LLDB_TARGET_MEMORYTAGMANAGER_H diff --git a/contrib/llvm-project/lldb/include/lldb/Target/PathMappingList.h b/contrib/llvm-project/lldb/include/lldb/Target/PathMappingList.h index 9e1e6eb26eb9..d788d120c47e 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/PathMappingList.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/PathMappingList.h @@ -72,13 +72,19 @@ public: /// \param[in] path /// The original source file path to try and remap. /// - /// \param[out] new_path - /// The newly remapped filespec that is may or may not exist. + /// \param[in] only_if_exists + /// If \b true, besides matching \p path with the remapping rules, this + /// tries to check with the filesystem that the remapped file exists. If + /// no valid file is found, \b None is returned. This might be expensive, + /// specially on a network. + /// + /// If \b false, then the existence of the returned remapping is not + /// checked. /// /// \return - /// /b true if \a path was successfully located and \a new_path - /// is filled in with a new source path, \b false otherwise. - bool RemapPath(llvm::StringRef path, std::string &new_path) const; + /// The remapped filespec that may or may not exist on disk. + llvm::Optional<FileSpec> RemapPath(llvm::StringRef path, + bool only_if_exists = false) const; bool RemapPath(const char *, std::string &) const = delete; bool ReverseRemapPath(const FileSpec &file, FileSpec &fixed) const; @@ -94,14 +100,9 @@ public: /// \param[in] orig_spec /// The original source file path to try and remap. /// - /// \param[out] new_spec - /// The newly remapped filespec that is guaranteed to exist. - /// /// \return - /// /b true if \a orig_spec was successfully located and - /// \a new_spec is filled in with an existing file spec, - /// \b false otherwise. - bool FindFile(const FileSpec &orig_spec, FileSpec &new_spec) const; + /// The newly remapped filespec that is guaranteed to exist. + llvm::Optional<FileSpec> FindFile(const FileSpec &orig_spec) const; uint32_t FindIndexForPath(ConstString path) const; @@ -118,9 +119,9 @@ protected: const_iterator FindIteratorForPath(ConstString path) const; collection m_pairs; - ChangedCallback m_callback; - void *m_callback_baton; - uint32_t m_mod_id; // Incremented anytime anything is added or removed. + ChangedCallback m_callback = nullptr; + void *m_callback_baton = nullptr; + uint32_t m_mod_id = 0; // Incremented anytime anything is added or removed. }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Process.h b/contrib/llvm-project/lldb/include/lldb/Target/Process.h index fbdb5069b39f..aaa2470d2931 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/Process.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/Process.h @@ -11,7 +11,7 @@ #include "lldb/Host/Config.h" -#include <limits.h> +#include <climits> #include <chrono> #include <list> @@ -34,6 +34,7 @@ #include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/InstrumentationRuntime.h" #include "lldb/Target/Memory.h" +#include "lldb/Target/MemoryTagManager.h" #include "lldb/Target/QueueList.h" #include "lldb/Target/ThreadList.h" #include "lldb/Target/ThreadPlanStack.h" @@ -46,7 +47,7 @@ #include "lldb/Utility/ProcessInfo.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StructuredData.h" -#include "lldb/Utility/TraceOptions.h" +#include "lldb/Utility/TraceGDBRemotePackets.h" #include "lldb/Utility/UnimplementedError.h" #include "lldb/Utility/UserIDResolver.h" #include "lldb/lldb-private.h" @@ -77,6 +78,8 @@ public: Args GetExtraStartupCommands() const; void SetExtraStartupCommands(const Args &args); FileSpec GetPythonOSPluginPath() const; + uint32_t GetVirtualAddressableBits() const; + void SetVirtualAddressableBits(uint32_t bits); void SetPythonOSPluginPath(const FileSpec &file); bool GetIgnoreBreakpointsInExpressions() const; void SetIgnoreBreakpointsInExpressions(bool ignore); @@ -84,12 +87,15 @@ public: void SetUnwindOnErrorInExpressions(bool ignore); bool GetStopOnSharedLibraryEvents() const; void SetStopOnSharedLibraryEvents(bool stop); + bool GetDisableLangRuntimeUnwindPlans() const; + void SetDisableLangRuntimeUnwindPlans(bool disable); bool GetDetachKeepsStopped() const; void SetDetachKeepsStopped(bool keep_stopped); bool GetWarningsOptimization() const; bool GetWarningsUnsupportedLanguage() const; bool GetStopOnExec() const; std::chrono::seconds GetUtilityExpressionTimeout() const; + std::chrono::seconds GetInterruptTimeout() const; bool GetOSPluginReportsAllThreads() const; void SetOSPluginReportsAllThreads(bool does_report); bool GetSteppingRunsAllThreads() const; @@ -109,9 +115,7 @@ class ProcessAttachInfo : public ProcessInstanceInfo { public: ProcessAttachInfo() : ProcessInstanceInfo(), m_listener_sp(), m_hijack_listener_sp(), - m_plugin_name(), m_resume_count(0), m_wait_for_launch(false), - m_ignore_existing(true), m_continue_once_attached(false), - m_detach_on_error(true), m_async(false) {} + m_plugin_name() {} ProcessAttachInfo(const ProcessLaunchInfo &launch_info) : ProcessInstanceInfo(), m_listener_sp(), m_hijack_listener_sp(), @@ -196,17 +200,19 @@ protected: lldb::ListenerSP m_listener_sp; lldb::ListenerSP m_hijack_listener_sp; std::string m_plugin_name; - uint32_t m_resume_count; // How many times do we resume after launching - bool m_wait_for_launch; - bool m_ignore_existing; - bool m_continue_once_attached; // Supports the use-case scenario of - // immediately continuing the process once - // attached. - bool m_detach_on_error; // If we are debugging remotely, instruct the stub to - // detach rather than killing the target on error. - bool m_async; // Use an async attach where we start the attach and return - // immediately (used by GUI programs with --waitfor so they can - // call SBProcess::Stop() to cancel attach) + uint32_t m_resume_count = 0; // How many times do we resume after launching + bool m_wait_for_launch = false; + bool m_ignore_existing = true; + bool m_continue_once_attached = false; // Supports the use-case scenario of + // immediately continuing the process + // once attached. + bool m_detach_on_error = + true; // If we are debugging remotely, instruct the stub to + // detach rather than killing the target on error. + bool m_async = + false; // Use an async attach where we start the attach and return + // immediately (used by GUI programs with --waitfor so they can + // call SBProcess::Stop() to cancel attach) }; // This class tracks the Modification state of the process. Things that can @@ -218,10 +224,7 @@ class ProcessModID { friend bool operator==(const ProcessModID &lhs, const ProcessModID &rhs); public: - ProcessModID() - : m_stop_id(0), m_last_natural_stop_id(0), m_resume_id(0), m_memory_id(0), - m_last_user_expression_resume(0), m_running_user_expression(false), - m_running_utility_function(0) {} + ProcessModID() = default; ProcessModID(const ProcessModID &rhs) : m_stop_id(rhs.m_stop_id), m_memory_id(rhs.m_memory_id) {} @@ -312,13 +315,13 @@ public: } private: - uint32_t m_stop_id; - uint32_t m_last_natural_stop_id; - uint32_t m_resume_id; - uint32_t m_memory_id; - uint32_t m_last_user_expression_resume; - uint32_t m_running_user_expression; - uint32_t m_running_utility_function; + uint32_t m_stop_id = 0; + uint32_t m_last_natural_stop_id = 0; + uint32_t m_resume_id = 0; + uint32_t m_memory_id = 0; + uint32_t m_last_user_expression_resume = 0; + uint32_t m_running_user_expression = false; + uint32_t m_running_utility_function = 0; lldb::EventSP m_last_natural_stop_event; }; @@ -467,12 +470,12 @@ public: } lldb::ProcessWP m_process_wp; - lldb::StateType m_state; + lldb::StateType m_state = lldb::eStateInvalid; std::vector<std::string> m_restarted_reasons; - bool m_restarted; // For "eStateStopped" events, this is true if the target - // was automatically restarted. - int m_update_state; - bool m_interrupted; + bool m_restarted = false; // For "eStateStopped" events, this is true if the + // target was automatically restarted. + int m_update_state = 0; + bool m_interrupted = false; ProcessEventData(const ProcessEventData &) = delete; const ProcessEventData &operator=(const ProcessEventData &) = delete; @@ -1328,6 +1331,17 @@ public: virtual void DidExit() {} + lldb::addr_t GetCodeAddressMask(); + lldb::addr_t GetDataAddressMask(); + + void SetCodeAddressMask(lldb::addr_t code_address_mask) { + m_code_address_mask = code_address_mask; + } + + void SetDataAddressMask(lldb::addr_t data_address_mask) { + m_data_address_mask = data_address_mask; + } + /// Get the Modification ID of the process. /// /// \return @@ -1695,6 +1709,57 @@ public: lldb::addr_t CallocateMemory(size_t size, uint32_t permissions, Status &error); + /// If this architecture and process supports memory tagging, return a tag + /// manager that can be used to maniupulate those memory tags. + /// + /// \return + /// Either a valid pointer to a tag manager or an error describing why one + /// could not be provided. + llvm::Expected<const MemoryTagManager *> GetMemoryTagManager(); + + /// Read memory tags for the range addr to addr+len. It is assumed + /// that this range has already been granule aligned. + /// (see MemoryTagManager::MakeTaggedRange) + /// + /// This calls DoReadMemoryTags to do the target specific operations. + /// + /// \param[in] addr + /// Start of memory range to read tags for. + /// + /// \param[in] len + /// Length of memory range to read tags for (in bytes). + /// + /// \return + /// If this architecture or process does not support memory tagging, + /// an error saying so. + /// If it does, either the memory tags or an error describing a + /// failure to read or unpack them. + llvm::Expected<std::vector<lldb::addr_t>> ReadMemoryTags(lldb::addr_t addr, + size_t len); + + /// Write memory tags for a range of memory. + /// (calls DoWriteMemoryTags to do the target specific work) + /// + /// \param[in] addr + /// The address to start writing tags from. It is assumed that this + /// address is granule aligned. + /// + /// \param[in] len + /// The size of the range to write tags for. It is assumed that this + /// is some multiple of the granule size. This len can be different + /// from (number of tags * granule size) in the case where you want + /// lldb-server to repeat tags across the range. + /// + /// \param[in] tags + /// Allocation tags to be written. Since lldb-server can repeat tags for a + /// range, the number of tags doesn't have to match the number of granules + /// in the range. (though most of the time it will) + /// + /// \return + /// A Status telling you if the write succeeded or not. + Status WriteMemoryTags(lldb::addr_t addr, size_t len, + const std::vector<lldb::addr_t> &tags); + /// Resolve dynamically loaded indirect functions. /// /// \param[in] address @@ -2455,59 +2520,8 @@ void PruneThreadPlans(); lldb::StructuredDataPluginSP GetStructuredDataPlugin(ConstString type_name) const; - /// Starts tracing with the configuration provided in options. To enable - /// tracing on the complete process the thread_id in the options should be - /// set to LLDB_INVALID_THREAD_ID. The API returns a user_id which is needed - /// by other API's that manipulate the trace instance. The handling of - /// erroneous or unsupported configuration is left to the trace technology - /// implementations in the server, as they could be returned as an error, or - /// rounded to a valid configuration to start tracing. In the later case the - /// GetTraceConfig should supply the actual used trace configuration. - virtual lldb::user_id_t StartTrace(const TraceOptions &options, - Status &error) { - error.SetErrorString("Not implemented"); - return LLDB_INVALID_UID; - } - - /// Stops the tracing instance leading to deletion of the trace data. The - /// tracing instance is identified by the user_id which is obtained when - /// tracing was started from the StartTrace. In case tracing of the complete - /// process needs to be stopped the thread_id should be set to - /// LLDB_INVALID_THREAD_ID. In the other case that tracing on an individual - /// thread needs to be stopped a thread_id can be supplied. - virtual Status StopTrace(lldb::user_id_t uid, lldb::tid_t thread_id) { - return Status("Not implemented"); - } - - /// Provides the trace data as raw bytes. A buffer needs to be supplied to - /// copy the trace data. The exact behavior of this API may vary across - /// trace technology, as some may support partial reading of the trace data - /// from a specified offset while some may not. The thread_id should be used - /// to select a particular thread for trace extraction. - virtual Status GetData(lldb::user_id_t uid, lldb::tid_t thread_id, - llvm::MutableArrayRef<uint8_t> &buffer, - size_t offset = 0) { - return Status("Not implemented"); - } - - /// Similar API as above except for obtaining meta data - virtual Status GetMetaData(lldb::user_id_t uid, lldb::tid_t thread_id, - llvm::MutableArrayRef<uint8_t> &buffer, - size_t offset = 0) { - return Status("Not implemented"); - } - - /// API to obtain the trace configuration used by a trace instance. - /// Configurations that may be specific to some trace technology should be - /// stored in the custom parameters. The options are transported to the - /// server, which shall interpret accordingly. The thread_id can be - /// specified in the options to obtain the configuration used by a specific - /// thread. The thread_id specified should also match the uid otherwise an - /// error will be returned. - virtual Status GetTraceConfig(lldb::user_id_t uid, TraceOptions &options) { - return Status("Not implemented"); - } - +protected: + friend class Trace; /// Get the processor tracing type supported for this process. /// Responses might be different depending on the architecture and /// capabilities of the underlying OS. @@ -2515,14 +2529,64 @@ void PruneThreadPlans(); /// \return /// The supported trace type or an \a llvm::Error if tracing is /// not supported for the inferior. - virtual llvm::Expected<TraceTypeInfo> GetSupportedTraceType(); + virtual llvm::Expected<TraceSupportedResponse> TraceSupported(); + + /// Start tracing a process or its threads. + /// + /// \param[in] request + /// JSON object with the information necessary to start tracing. In the + /// case of gdb-remote processes, this JSON object should conform to the + /// jLLDBTraceStart packet. + /// + /// \return + /// \a llvm::Error::success if the operation was successful, or + /// \a llvm::Error otherwise. + virtual llvm::Error TraceStart(const llvm::json::Value &request) { + return llvm::make_error<UnimplementedError>(); + } + + /// Stop tracing a live process or its threads. + /// + /// \param[in] request + /// The information determining which threads or process to stop tracing. + /// + /// \return + /// \a llvm::Error::success if the operation was successful, or + /// \a llvm::Error otherwise. + virtual llvm::Error TraceStop(const TraceStopRequest &request) { + return llvm::make_error<UnimplementedError>(); + } + + /// Get the current tracing state of the process and its threads. + /// + /// \param[in] type + /// Tracing technology type to consider. + /// + /// \return + /// A JSON object string with custom data depending on the trace + /// technology, or an \a llvm::Error in case of errors. + virtual llvm::Expected<std::string> TraceGetState(llvm::StringRef type) { + return llvm::make_error<UnimplementedError>(); + } + + /// Get binary data given a trace technology and a data identifier. + /// + /// \param[in] request + /// Object with the params of the requested data. + /// + /// \return + /// A vector of bytes with the requested data, or an \a llvm::Error in + /// case of failures. + virtual llvm::Expected<std::vector<uint8_t>> + TraceGetBinaryData(const TraceGetBinaryDataRequest &request) { + return llvm::make_error<UnimplementedError>(); + } // 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. @@ -2561,8 +2625,6 @@ protected: 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(); /// The "private" side of resuming a process. This doesn't alter the state @@ -2708,6 +2770,60 @@ protected: /// false. bool RouteAsyncStructuredData(const StructuredData::ObjectSP object_sp); + /// Check whether the process supports memory tagging. + /// + /// \return + /// true if the process supports memory tagging, + /// false otherwise. + virtual bool SupportsMemoryTagging() { return false; } + + /// Does the final operation to read memory tags. E.g. sending a GDB packet. + /// It assumes that ReadMemoryTags has checked that memory tagging is enabled + /// and has expanded the memory range as needed. + /// + /// \param[in] addr + /// Start of address range to read memory tags for. + /// + /// \param[in] len + /// Length of the memory range to read tags for (in bytes). + /// + /// \param[in] type + /// Type of tags to read (get this from a MemoryTagManager) + /// + /// \return + /// The packed tag data received from the remote or an error + /// if the read failed. + virtual llvm::Expected<std::vector<uint8_t>> + DoReadMemoryTags(lldb::addr_t addr, size_t len, int32_t type) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "%s does not support reading memory tags", + GetPluginName().GetCString()); + } + + /// Does the final operation to write memory tags. E.g. sending a GDB packet. + /// It assumes that WriteMemoryTags has checked that memory tagging is enabled + /// and has packed the tag data. + /// + /// \param[in] addr + /// Start of address range to write memory tags for. + /// + /// \param[in] len + /// Length of the memory range to write tags for (in bytes). + /// + /// \param[in] type + /// Type of tags to read (get this from a MemoryTagManager) + /// + /// \param[in] tags + /// Packed tags to be written. + /// + /// \return + /// Status telling you whether the write succeeded. + virtual Status DoWriteMemoryTags(lldb::addr_t addr, size_t len, int32_t type, + const std::vector<uint8_t> &tags) { + return Status("%s does not support writing memory tags", + GetPluginName().GetCString()); + } + // Type definitions typedef std::map<lldb::LanguageType, lldb::LanguageRuntimeSP> LanguageRuntimeCollection; @@ -2827,6 +2943,14 @@ protected: /// from looking up or creating things during or after a finalize call. std::atomic<bool> m_finalizing; + /// Mask for code an data addresses. The default value (0) means no mask is + /// set. The bits set to 1 indicate bits that are NOT significant for + /// addressing. + /// @{ + lldb::addr_t m_code_address_mask = 0; + lldb::addr_t m_data_address_mask = 0; + /// @} + 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 diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ProcessTrace.h b/contrib/llvm-project/lldb/include/lldb/Target/ProcessTrace.h index 55faba1576d0..7b9d6b13dd6f 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/ProcessTrace.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/ProcessTrace.h @@ -15,6 +15,8 @@ namespace lldb_private { +/// Class that represents a defunct process loaded on memory via the "trace +/// load" command. class ProcessTrace : public PostMortemProcess { public: static void Initialize(); @@ -54,8 +56,6 @@ public: return error; } - bool IsAlive() override; - bool WarnBeforeDetach() const override { return false; } size_t ReadMemory(lldb::addr_t addr, void *buf, size_t size, diff --git a/contrib/llvm-project/lldb/include/lldb/Target/RegisterCheckpoint.h b/contrib/llvm-project/lldb/include/lldb/Target/RegisterCheckpoint.h index d2bcc614f587..daf20db999b3 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/RegisterCheckpoint.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/RegisterCheckpoint.h @@ -34,7 +34,7 @@ public: RegisterCheckpoint(Reason reason) : UserID(0), m_data_sp(), m_reason(reason) {} - ~RegisterCheckpoint() {} + ~RegisterCheckpoint() = default; lldb::DataBufferSP &GetData() { return m_data_sp; } diff --git a/contrib/llvm-project/lldb/include/lldb/Target/RegisterContext.h b/contrib/llvm-project/lldb/include/lldb/Target/RegisterContext.h index 5e795e59f941..c5068feedd5b 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/RegisterContext.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/RegisterContext.h @@ -148,6 +148,31 @@ public: uint64_t GetPC(uint64_t fail_value = LLDB_INVALID_ADDRESS); + /// Get an address suitable for symbolication. + /// When symbolicating -- computing line, block, function -- + /// for a function in the middle of the stack, using the return + /// address can lead to unexpected results for the user. + /// A function that ends in a tail-call may have another function + /// as the "return" address, but it will never actually return. + /// Or a noreturn call in the middle of a function is the end of + /// a block of instructions, and a DWARF location list entry for + /// the return address may be a very different code path with + /// incorrect results when printing variables for this frame. + /// + /// At a source line view, the user expects the current-line indictation + /// to point to the function call they're under, not the next source line. + /// + /// The return address (GetPC()) should always be shown to the user, + /// but when computing context, keeping within the bounds of the + /// call instruction is what the user expects to see. + /// + /// \param [out] address + /// An Address object that will be filled in, if a PC can be retrieved. + /// + /// \return + /// Returns true if the Address param was filled in. + bool GetPCForSymbolication(Address &address); + bool SetPC(uint64_t pc); bool SetPC(Address addr); @@ -196,6 +221,19 @@ public: void SetStopID(uint32_t stop_id) { m_stop_id = stop_id; } protected: + /// Indicates that this frame is currently executing code, + /// that the PC value is not a return-pc but an actual executing + /// instruction. Some places in lldb will treat a return-pc + /// value differently than the currently-executing-pc value, + /// and this method can indicate if that should be done. + /// The base class implementation only uses the frame index, + /// but subclasses may have additional information that they + /// can use to detect frames in this state, for instance a + /// frame above a trap handler (sigtramp etc).. + virtual bool BehavesLikeZerothFrame() const { + return m_concrete_frame_idx == 0; + } + // Classes that inherit from RegisterContext can see and modify these Thread &m_thread; // The thread that this register context belongs to. uint32_t m_concrete_frame_idx; // The concrete frame index for this register diff --git a/contrib/llvm-project/lldb/include/lldb/Target/RegisterContextUnwind.h b/contrib/llvm-project/lldb/include/lldb/Target/RegisterContextUnwind.h index fa96c3e42c78..edda281d5aa7 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/RegisterContextUnwind.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/RegisterContextUnwind.h @@ -67,6 +67,11 @@ public: bool ReadPC(lldb::addr_t &start_pc); + // Indicates whether this frame *behaves* like frame zero -- the currently + // executing frame -- or not. This can be true in the middle of the stack + // above asynchronous trap handlers (sigtramp) for instance. + bool BehavesLikeZerothFrame() const override; + private: enum FrameType { eNormalFrame, @@ -228,14 +233,16 @@ private: // unknown // 0 if no instructions have been executed yet. - int m_current_offset_backed_up_one; // how far into the function we've - // executed; -1 if unknown // 0 if no instructions have been executed yet. // On architectures where the return address on the stack points // to the instruction after the CALL, this value will have 1 // subtracted from it. Else a function that ends in a CALL will // have an offset pointing into the next function's address range. // m_current_pc has the actual address of the "current" pc. + int m_current_offset_backed_up_one; // how far into the function we've + // executed; -1 if unknown + + bool m_behaves_like_zeroth_frame; // this frame behaves like frame zero lldb_private::SymbolContext &m_sym_ctx; bool m_sym_ctx_valid; // if ResolveSymbolContextForAddress fails, don't try to diff --git a/contrib/llvm-project/lldb/include/lldb/Target/RegisterNumber.h b/contrib/llvm-project/lldb/include/lldb/Target/RegisterNumber.h index 362812bcffd0..90f953198969 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/RegisterNumber.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/RegisterNumber.h @@ -50,10 +50,10 @@ private: typedef std::map<lldb::RegisterKind, uint32_t> Collection; lldb::RegisterContextSP m_reg_ctx_sp; - uint32_t m_regnum; - lldb::RegisterKind m_kind; + uint32_t m_regnum = LLDB_INVALID_REGNUM; + lldb::RegisterKind m_kind = lldb::kNumRegisterKinds; Collection m_kind_regnum_map; - const char *m_name; + const char *m_name = nullptr; }; #endif // LLDB_TARGET_REGISTERNUMBER_H diff --git a/contrib/llvm-project/lldb/include/lldb/Target/RemoteAwarePlatform.h b/contrib/llvm-project/lldb/include/lldb/Target/RemoteAwarePlatform.h index 6d6ac99c093f..269d15299889 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/RemoteAwarePlatform.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/RemoteAwarePlatform.h @@ -97,6 +97,9 @@ public: Status KillProcess(const lldb::pid_t pid) override; + size_t ConnectToWaitingProcesses(Debugger &debugger, + Status &error) override; + protected: lldb::PlatformSP m_remote_platform_sp; }; diff --git a/contrib/llvm-project/lldb/include/lldb/Target/StackFrame.h b/contrib/llvm-project/lldb/include/lldb/Target/StackFrame.h index 905c56c91263..1a9aaad1a4db 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/StackFrame.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/StackFrame.h @@ -134,6 +134,24 @@ public: /// The Address object set to the current PC value. const Address &GetFrameCodeAddress(); + /// Get the current code Address suitable for symbolication, + /// may not be the same as GetFrameCodeAddress(). + /// + /// For a frame in the middle of the stack, the return-pc is the + /// current code address, but for symbolication purposes the + /// return address after a noreturn call may point to the next + /// function, a DWARF location list entry that is a completely + /// different code path, or the wrong source line. + /// + /// The address returned should be used for symbolication (source line, + /// block, function, DWARF location entry selection) but should NOT + /// be shown to the user. It may not point to an actual instruction + /// boundary. + /// + /// \return + /// The Address object set to the current PC value. + Address GetFrameCodeAddressForSymbolication(); + /// Change the pc value for a given thread. /// /// Change the current pc value for the frame on this thread. @@ -404,22 +422,6 @@ public: GetValueObjectForFrameVariable(const lldb::VariableSP &variable_sp, lldb::DynamicValueType use_dynamic); - /// Add an arbitrary Variable object (e.g. one that specifics a global or - /// static) to a StackFrame's list of ValueObjects. - /// - /// \params [in] variable_sp - /// The Variable to base this ValueObject on - /// - /// \params [in] use_dynamic - /// Whether the correct dynamic type of the variable should be - /// determined before creating the ValueObject, or if the static type - /// is sufficient. One of the DynamicValueType enumerated values. - /// - /// \return - /// A ValueObject for this variable. - lldb::ValueObjectSP TrackGlobalVariable(const lldb::VariableSP &variable_sp, - lldb::DynamicValueType use_dynamic); - /// Query this frame to determine what the default language should be when /// parsing expressions given the execution context. /// diff --git a/contrib/llvm-project/lldb/include/lldb/Target/StackFrameList.h b/contrib/llvm-project/lldb/include/lldb/Target/StackFrameList.h index 1b0b986d7059..c98995cad36f 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/StackFrameList.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/StackFrameList.h @@ -89,9 +89,6 @@ protected: bool SetFrameAtIndex(uint32_t idx, lldb::StackFrameSP &frame_sp); - static void Merge(std::unique_ptr<StackFrameList> &curr_up, - lldb::StackFrameListSP &prev_sp); - void GetFramesUpTo(uint32_t end_idx); void GetOnlyConcreteFramesUpTo(uint32_t end_idx, Unwind &unwinder); diff --git a/contrib/llvm-project/lldb/include/lldb/Target/StackFrameRecognizer.h b/contrib/llvm-project/lldb/include/lldb/Target/StackFrameRecognizer.h index baffc890bb06..64be759dc79e 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/StackFrameRecognizer.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/StackFrameRecognizer.h @@ -37,7 +37,7 @@ public: return lldb::ValueObjectSP(); } virtual lldb::StackFrameSP GetMostRelevantFrame() { return nullptr; }; - virtual ~RecognizedStackFrame(){}; + virtual ~RecognizedStackFrame() = default; std::string GetStopDescription() { return m_stop_desc; } @@ -63,7 +63,7 @@ public: return ""; } - virtual ~StackFrameRecognizer(){}; + virtual ~StackFrameRecognizer() = default; }; /// \class ScriptedStackFrameRecognizer @@ -80,7 +80,7 @@ class ScriptedStackFrameRecognizer : public StackFrameRecognizer { public: ScriptedStackFrameRecognizer(lldb_private::ScriptInterpreter *interpreter, const char *pclass); - ~ScriptedStackFrameRecognizer() override {} + ~ScriptedStackFrameRecognizer() override = default; std::string GetName() override { return GetPythonClassName(); diff --git a/contrib/llvm-project/lldb/include/lldb/Target/StackID.h b/contrib/llvm-project/lldb/include/lldb/Target/StackID.h index 827ed1be7c0f..95d12df6742c 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/StackID.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/StackID.h @@ -18,8 +18,8 @@ class StackID { public: // Constructors and Destructors StackID() - : m_pc(LLDB_INVALID_ADDRESS), m_cfa(LLDB_INVALID_ADDRESS), - m_symbol_scope(nullptr) {} + + {} explicit StackID(lldb::addr_t pc, lldb::addr_t cfa, SymbolContextScope *symbol_scope) @@ -69,23 +69,25 @@ protected: void SetCFA(lldb::addr_t cfa) { m_cfa = cfa; } - lldb::addr_t - m_pc; // The pc value for the function/symbol for this frame. This will + lldb::addr_t m_pc = + LLDB_INVALID_ADDRESS; // The pc value for the function/symbol for this + // frame. This will // only get used if the symbol scope is nullptr (the code where we are // stopped is not represented by any function or symbol in any shared // library). - lldb::addr_t m_cfa; // The call frame address (stack pointer) value - // at the beginning of the function that uniquely - // identifies this frame (along with m_symbol_scope - // below) - SymbolContextScope * - m_symbol_scope; // If nullptr, there is no block or symbol for this frame. - // If not nullptr, this will either be the scope for the - // lexical block for the frame, or the scope for the - // symbol. Symbol context scopes are always be unique - // pointers since the are part of the Block and Symbol - // objects and can easily be used to tell if a stack ID - // is the same as another. + lldb::addr_t m_cfa = + LLDB_INVALID_ADDRESS; // The call frame address (stack pointer) value + // at the beginning of the function that uniquely + // identifies this frame (along with m_symbol_scope + // below) + SymbolContextScope *m_symbol_scope = + nullptr; // If nullptr, there is no block or symbol for this frame. + // If not nullptr, this will either be the scope for the + // lexical block for the frame, or the scope for the + // symbol. Symbol context scopes are always be unique + // pointers since the are part of the Block and Symbol + // objects and can easily be used to tell if a stack ID + // is the same as another. }; bool operator==(const StackID &lhs, const StackID &rhs); diff --git a/contrib/llvm-project/lldb/include/lldb/Target/StopInfo.h b/contrib/llvm-project/lldb/include/lldb/Target/StopInfo.h index 4378d2d63799..0e81e5160846 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/StopInfo.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/StopInfo.h @@ -25,7 +25,7 @@ public: // Constructors and Destructors StopInfo(Thread &thread, uint64_t value); - virtual ~StopInfo() {} + virtual ~StopInfo() = default; bool IsValid() const; @@ -129,6 +129,9 @@ public: static lldb::StopInfoSP CreateStopReasonWithExec(Thread &thread); + static lldb::StopInfoSP + CreateStopReasonProcessorTrace(Thread &thread, const char *description); + static lldb::ValueObjectSP GetReturnValueObject(lldb::StopInfoSP &stop_info_sp); diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Target.h b/contrib/llvm-project/lldb/include/lldb/Target/Target.h index 69baefb964b0..ac8d002b09a1 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/Target.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/Target.h @@ -37,8 +37,6 @@ namespace lldb_private { -class ClangModulesDeclVendor; - OptionEnumValues GetDynamicValueTypes(); enum InlineStrategy { @@ -211,7 +209,7 @@ public: void SetDisplayRecognizedArguments(bool b); - const ProcessLaunchInfo &GetProcessLaunchInfo(); + const ProcessLaunchInfo &GetProcessLaunchInfo() const; void SetProcessLaunchInfo(const ProcessLaunchInfo &launch_info); @@ -227,6 +225,10 @@ public: void UpdateLaunchInfoFromProperties(); + void SetDebugUtilityExpression(bool debug); + + bool GetDebugUtilityExpression() const; + private: // Callbacks for m_launch_info. void Arg0ValueChangedCallback(); @@ -1001,11 +1003,12 @@ public: // read from const sections in object files, read from the target. This // version of ReadMemory will try and read memory from the process if the // process is alive. The order is: - // 1 - if (prefer_file_cache == true) then read from object file cache - // 2 - if there is a valid process, try and read from its memory - // 3 - if (prefer_file_cache == false) then read from object file cache - size_t ReadMemory(const Address &addr, bool prefer_file_cache, void *dst, - size_t dst_len, Status &error, + // 1 - if (force_live_memory == false) and the address falls in a read-only + // section, then read from the file cache + // 2 - if there is a process, then read from memory + // 3 - if there is no process, then read from the file cache + size_t ReadMemory(const Address &addr, void *dst, size_t dst_len, + Status &error, bool force_live_memory = false, lldb::addr_t *load_addr_ptr = nullptr); size_t ReadCStringFromMemory(const Address &addr, std::string &out_str, @@ -1014,18 +1017,19 @@ public: size_t ReadCStringFromMemory(const Address &addr, char *dst, size_t dst_max_len, Status &result_error); - size_t ReadScalarIntegerFromMemory(const Address &addr, - bool prefer_file_cache, uint32_t byte_size, + size_t ReadScalarIntegerFromMemory(const Address &addr, uint32_t byte_size, bool is_signed, Scalar &scalar, - Status &error); + Status &error, + bool force_live_memory = false); uint64_t ReadUnsignedIntegerFromMemory(const Address &addr, - bool prefer_file_cache, size_t integer_byte_size, - uint64_t fail_value, Status &error); + uint64_t fail_value, Status &error, + bool force_live_memory = false); - bool ReadPointerFromMemory(const Address &addr, bool prefer_file_cache, - Status &error, Address &pointer_addr); + bool ReadPointerFromMemory(const Address &addr, Status &error, + Address &pointer_addr, + bool force_live_memory = false); SectionLoadList &GetSectionLoadList() { return m_section_load_history.GetCurrentSectionLoadList(); @@ -1122,7 +1126,19 @@ public: /// /// \return /// The trace object. It might be undefined. - const lldb::TraceSP &GetTrace(); + lldb::TraceSP GetTrace(); + + /// Create a \a Trace object for the current target using the using the + /// default supported tracing technology for this process. + /// + /// \return + /// The new \a Trace or an \a llvm::Error if a \a Trace already exists or + /// the trace couldn't be created. + llvm::Expected<lldb::TraceSP> CreateTrace(); + + /// If a \a Trace object is present, this returns it, otherwise a new Trace is + /// created with \a Trace::CreateTrace. + llvm::Expected<lldb::TraceSP> GetTraceOrCreate(); // Since expressions results can persist beyond the lifetime of a process, // and the const expression results are available after a process is gone, we @@ -1325,8 +1341,6 @@ public: SourceManager &GetSourceManager(); - ClangModulesDeclVendor *GetClangModulesDeclVendor(); - // Methods. lldb::SearchFilterSP GetSearchFilterForModule(const FileSpec *containingModule); @@ -1410,15 +1424,15 @@ protected: typedef std::map<lldb::LanguageType, lldb::REPLSP> REPLMap; REPLMap m_repl_map; - std::unique_ptr<ClangModulesDeclVendor> m_clang_modules_decl_vendor_up; - lldb::SourceManagerUP m_source_manager_up; typedef std::map<lldb::user_id_t, StopHookSP> StopHookCollection; StopHookCollection m_stop_hooks; lldb::user_id_t m_stop_hook_next_id; + uint32_t m_latest_stop_hook_id; /// This records the last natural stop at + /// which we ran a stop-hook. bool m_valid; - bool m_suppress_stop_hooks; + bool m_suppress_stop_hooks; /// Used to not run stop hooks for expressions bool m_is_dummy_target; unsigned m_next_persistent_variable_index = 0; /// An optional \a lldb_private::Trace object containing processor trace diff --git a/contrib/llvm-project/lldb/include/lldb/Target/TargetList.h b/contrib/llvm-project/lldb/include/lldb/Target/TargetList.h index 903ca4bcefbc..65781a4811fd 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/TargetList.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/TargetList.h @@ -14,6 +14,7 @@ #include "lldb/Target/Target.h" #include "lldb/Utility/Broadcaster.h" +#include "lldb/Utility/Iterable.h" namespace lldb_private { @@ -42,6 +43,11 @@ public: return GetStaticBroadcasterClass(); } + typedef std::vector<lldb::TargetSP> collection; + typedef LockingAdaptedIterable<collection, lldb::TargetSP, vector_adapter, + std::recursive_mutex> + TargetIterable; + /// Create a new Target. /// /// Clients must use this function to create a Target. This allows @@ -179,14 +185,15 @@ public: lldb::TargetSP GetSelectedTarget(); -protected: - typedef std::vector<lldb::TargetSP> collection; - // Member variables. + TargetIterable Targets() { + return TargetIterable(m_target_list, m_target_list_mutex); + } + +private: collection m_target_list; mutable std::recursive_mutex m_target_list_mutex; uint32_t m_selected_target_idx; -private: static Status CreateTargetInternal( Debugger &debugger, llvm::StringRef user_exe_path, llvm::StringRef triple_str, LoadDependentFiles load_dependent_files, diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Thread.h b/contrib/llvm-project/lldb/include/lldb/Target/Thread.h index 4b148063ec6e..0f6b5741573e 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/Thread.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/Thread.h @@ -615,7 +615,7 @@ public: /// \return /// A shared pointer to the newly queued thread plan, or nullptr if the /// plan could not be queued. - virtual lldb::ThreadPlanSP QueueFundamentalPlan(bool abort_other_plans); + lldb::ThreadPlanSP QueueBasePlan(bool abort_other_plans); /// Queues the plan used to step one instruction from the current PC of \a /// thread. @@ -781,10 +781,10 @@ public: /// \param[in] stop_other_threads /// \b true if we will stop other threads while we single step this one. /// - /// \param[in] stop_vote + /// \param[in] report_stop_vote /// See standard meanings for the stop & run votes in ThreadPlan.h. /// - /// \param[in] run_vote + /// \param[in] report_run_vote /// See standard meanings for the stop & run votes in ThreadPlan.h. /// /// \param[out] status @@ -800,7 +800,7 @@ public: /// plan could not be queued. virtual lldb::ThreadPlanSP QueueThreadPlanForStepOut( bool abort_other_plans, SymbolContext *addr_context, bool first_insn, - bool stop_other_threads, Vote stop_vote, Vote run_vote, + bool stop_other_threads, Vote report_stop_vote, Vote report_run_vote, uint32_t frame_idx, Status &status, LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate); @@ -830,10 +830,10 @@ public: /// \param[in] stop_other_threads /// \b true if we will stop other threads while we single step this one. /// - /// \param[in] stop_vote + /// \param[in] report_stop_vote /// See standard meanings for the stop & run votes in ThreadPlan.h. /// - /// \param[in] run_vote + /// \param[in] report_run_vote /// See standard meanings for the stop & run votes in ThreadPlan.h. /// /// \param[in] frame_idx @@ -864,7 +864,7 @@ public: /// plan could not be queued. virtual lldb::ThreadPlanSP QueueThreadPlanForStepOutNoShouldStop( bool abort_other_plans, SymbolContext *addr_context, bool first_insn, - bool stop_other_threads, Vote stop_vote, Vote run_vote, + bool stop_other_threads, Vote report_stop_vote, Vote report_run_vote, uint32_t frame_idx, Status &status, bool continue_to_next_branch = false); /// Gets the plan used to step through the code that steps from a function @@ -1050,12 +1050,7 @@ public: virtual bool RestoreRegisterStateFromCheckpoint(ThreadStateCheckpoint &saved_state); - virtual bool - RestoreThreadStateFromCheckpoint(ThreadStateCheckpoint &saved_state); - - void EnableTracer(bool value, bool single_step); - - void SetTracer(lldb::ThreadPlanTracerSP &tracer_sp); + void RestoreThreadStateFromCheckpoint(ThreadStateCheckpoint &saved_state); // Get the thread index ID. The index ID that is guaranteed to not be re-used // by a process. They start at 1 and increase with each new thread. This diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ThreadCollection.h b/contrib/llvm-project/lldb/include/lldb/Target/ThreadCollection.h index 40dc938976ff..29f5103e7eec 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/ThreadCollection.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/ThreadCollection.h @@ -28,7 +28,7 @@ public: ThreadCollection(collection threads); - virtual ~ThreadCollection() {} + virtual ~ThreadCollection() = default; uint32_t GetSize(); diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlan.h b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlan.h index 242a4d3c2d6c..5e14a1fd6577 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlan.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlan.h @@ -260,8 +260,8 @@ namespace lldb_private { // One other little detail here, sometimes a plan will push another plan onto // the plan stack to do some part of the first plan's job, and it would be // convenient to tell that plan how it should respond to ShouldReportStop. -// You can do that by setting the stop_vote in the child plan when you create -// it. +// You can do that by setting the report_stop_vote in the child plan when you +// create it. // // Suppressing the initial eStateRunning event: // @@ -275,14 +275,13 @@ namespace lldb_private { // 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. +// report_run_vote argument to the constructor works like report_stop_vote, and +// is a way for a plan to instruct a sub-plan on how to respond to +// ShouldReportStop. class ThreadPlan : public std::enable_shared_from_this<ThreadPlan>, public UserID { public: - enum ThreadScope { eAllThreads, eSomeThreads, eThisThread }; - // We use these enums so that we can cast a base thread plan to it's real // type without having to resort to dynamic casting. enum ThreadPlanKind { @@ -298,15 +297,9 @@ public: eKindStepInRange, eKindRunToAddress, eKindStepThrough, - eKindStepUntil, - eKindTestCondition - + eKindStepUntil }; - // Constructors and Destructors - ThreadPlan(ThreadPlanKind kind, const char *name, Thread &thread, - Vote stop_vote, Vote run_vote); - virtual ~ThreadPlan(); /// Returns the name of this thread plan. @@ -368,6 +361,12 @@ public: virtual bool ShouldStop(Event *event_ptr) = 0; + /// Returns whether this thread plan overrides the `ShouldStop` of + /// subsequently processed plans. + /// + /// When processing the thread plan stack, this function gives plans the + /// ability to continue - even when subsequent plans return true from + /// `ShouldStop`. \see Thread::ShouldStop virtual bool ShouldAutoContinue(Event *event_ptr) { return false; } // Whether a "stop class" event should be reported to the "outside world". @@ -375,7 +374,7 @@ public: virtual Vote ShouldReportStop(Event *event_ptr); - virtual Vote ShouldReportRun(Event *event_ptr); + Vote ShouldReportRun(Event *event_ptr); virtual void SetStopOthers(bool new_value); @@ -416,15 +415,6 @@ public: virtual void WillPop(); - // This pushes a plan onto the plan stack of the current plan's thread. - // Also sets the plans to private and not master plans. A plan pushed by - // another thread plan is never either of the above. - void PushPlan(lldb::ThreadPlanSP &thread_plan_sp) { - GetThread().PushPlan(thread_plan_sp); - thread_plan_sp->SetPrivate(false); - thread_plan_sp->SetIsMasterPlan(false); - } - ThreadPlanKind GetKind() const { return m_kind; } bool IsPlanComplete(); @@ -448,15 +438,6 @@ public: m_tracer_sp->Log(); } - // Some thread plans hide away the actual stop info which caused any - // particular stop. For instance the ThreadPlanCallFunction restores the - // original stop reason so that stopping and calling a few functions won't - // lose the history of the run. This call can be implemented to get you back - // to the real stop info. - virtual lldb::StopInfoSP GetRealStopInfo() { - return GetThread().GetStopInfo(); - } - // If the completion of the thread plan stepped out of a function, the return // value of the function might have been captured by the thread plan // (currently only ThreadPlanStepOut does this.) If so, the ReturnValueObject @@ -481,14 +462,11 @@ public: // to restore the state when it is done. This will do that job. This is // mostly useful for artificial plans like CallFunction plans. - virtual bool RestoreThreadState() { - // Nothing to do in general. - return true; - } + virtual void RestoreThreadState() {} virtual bool IsVirtualStep() { return false; } - virtual bool SetIterationCount(size_t count) { + bool SetIterationCount(size_t count) { if (m_takes_iteration_count) { // Don't tell me to do something 0 times... if (count == 0) @@ -498,14 +476,11 @@ public: return m_takes_iteration_count; } - virtual size_t GetIterationCount() { - if (!m_takes_iteration_count) - return 0; - else - return m_iteration_count; - } - protected: + // Constructors and Destructors + ThreadPlan(ThreadPlanKind kind, const char *name, Thread &thread, + Vote report_stop_vote, Vote report_run_vote); + // Classes that inherit from ThreadPlan can see and modify these virtual bool DoWillResume(lldb::StateType resume_state, bool current_plan) { @@ -514,6 +489,15 @@ protected: virtual bool DoPlanExplainsStop(Event *event_ptr) = 0; + // This pushes a plan onto the plan stack of the current plan's thread. + // Also sets the plans to private and not master plans. A plan pushed by + // another thread plan is never either of the above. + void PushPlan(lldb::ThreadPlanSP &thread_plan_sp) { + GetThread().PushPlan(thread_plan_sp); + thread_plan_sp->SetPrivate(true); + thread_plan_sp->SetIsMasterPlan(false); + } + // This gets the previous plan to the current plan (for forwarding requests). // This is mostly a formal requirement, it allows us to make the Thread's // GetPreviousPlan protected, but only friend ThreadPlan to thread. @@ -531,14 +515,6 @@ protected: GetThread().SetStopInfo(stop_reason_sp); } - void CachePlanExplainsStop(bool does_explain) { - m_cached_plan_explains_stop = does_explain ? eLazyBoolYes : eLazyBoolNo; - } - - LazyBool GetCachedPlanExplainsStop() const { - return m_cached_plan_explains_stop; - } - virtual lldb::StateType GetPlanRunState() = 0; bool IsUsuallyUnexplainedStopReason(lldb::StopReason); @@ -546,13 +522,17 @@ protected: Status m_status; Process &m_process; lldb::tid_t m_tid; - Vote m_stop_vote; - Vote m_run_vote; + Vote m_report_stop_vote; + Vote m_report_run_vote; bool m_takes_iteration_count; bool m_could_not_resolve_hw_bp; int32_t m_iteration_count = 1; private: + void CachePlanExplainsStop(bool does_explain) { + m_cached_plan_explains_stop = does_explain ? eLazyBoolYes : eLazyBoolNo; + } + // For ThreadPlan only static lldb::user_id_t GetNextID(); diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanBase.h b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanBase.h index 48058a9b40ab..5c44b9fb17b2 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanBase.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanBase.h @@ -44,8 +44,7 @@ protected: ThreadPlanBase(Thread &thread); private: - friend lldb::ThreadPlanSP - Thread::QueueFundamentalPlan(bool abort_other_plans); + friend lldb::ThreadPlanSP Thread::QueueBasePlan(bool abort_other_plans); ThreadPlanBase(const ThreadPlanBase &) = delete; const ThreadPlanBase &operator=(const ThreadPlanBase &) = delete; diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanCallFunction.h b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanCallFunction.h index 5b432e5e604a..24c5736f44c3 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanCallFunction.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanCallFunction.h @@ -81,7 +81,7 @@ public: // stop reason. But if something bad goes wrong, it is nice to be able to // tell the user what really happened. - lldb::StopInfoSP GetRealStopInfo() override { + virtual lldb::StopInfoSP GetRealStopInfo() { if (m_real_stop_info_sp) return m_real_stop_info_sp; else @@ -90,7 +90,7 @@ public: lldb::addr_t GetStopAddress() { return m_stop_address; } - bool RestoreThreadState() override; + void RestoreThreadState() override; void ThreadDestroyed() override { m_takedown_done = true; } diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStack.h b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStack.h index 7b2817b2e8fd..e0f76f8e1df5 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStack.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStack.h @@ -33,7 +33,7 @@ class ThreadPlanStack { public: ThreadPlanStack(const Thread &thread, bool make_empty = false); - ~ThreadPlanStack() {} + ~ThreadPlanStack() = default; using PlanStack = std::vector<lldb::ThreadPlanSP>; @@ -48,10 +48,6 @@ public: void ThreadDestroyed(Thread *thread); - void EnableTracer(bool value, bool single_stepping); - - void SetTracer(lldb::ThreadPlanTracerSP &tracer_sp); - void PushPlan(lldb::ThreadPlanSP new_plan_sp); lldb::ThreadPlanSP PopPlan(); @@ -114,12 +110,13 @@ private: size_t m_completed_plan_checkpoint = 0; // Monotonically increasing token for // completed plan checkpoints. std::unordered_map<size_t, PlanStack> m_completed_plan_store; + mutable std::recursive_mutex m_stack_mutex; }; class ThreadPlanStackMap { public: ThreadPlanStackMap(Process &process) : m_process(process) {} - ~ThreadPlanStackMap() {} + ~ThreadPlanStackMap() = default; // Prune the map using the current_threads list. void Update(ThreadList ¤t_threads, bool delete_missing, @@ -157,7 +154,7 @@ public: } void Clear() { - for (auto plan : m_plans_list) + for (auto &plan : m_plans_list) plan.second.ThreadDestroyed(nullptr); m_plans_list.clear(); } diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStepInRange.h b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStepInRange.h index a26b0fb87b3a..f9ef87942a7c 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStepInRange.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStepInRange.h @@ -22,7 +22,7 @@ class ThreadPlanStepInRange : public ThreadPlanStepRange, public: ThreadPlanStepInRange(Thread &thread, const AddressRange &range, const SymbolContext &addr_context, - lldb::RunMode stop_others, + const char *step_into_target, lldb::RunMode stop_others, LazyBool step_in_avoids_code_without_debug_info, LazyBool step_out_avoids_code_without_debug_info); @@ -34,10 +34,6 @@ public: void SetAvoidRegexp(const char *name); - void SetStepInTarget(const char *target) { - m_step_into_target.SetCString(target); - } - static void SetDefaultFlagValue(uint32_t new_value); bool IsVirtualStep() override; diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStepInstruction.h b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStepInstruction.h index 760bc4886faa..52a5a2efc0a4 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStepInstruction.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStepInstruction.h @@ -18,7 +18,7 @@ namespace lldb_private { class ThreadPlanStepInstruction : public ThreadPlan { public: ThreadPlanStepInstruction(Thread &thread, bool step_over, bool stop_others, - Vote stop_vote, Vote run_vote); + Vote report_stop_vote, Vote report_run_vote); ~ThreadPlanStepInstruction() override; diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStepOut.h b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStepOut.h index 5c39232fd2e8..b1d8769f7c54 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStepOut.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStepOut.h @@ -18,8 +18,8 @@ namespace lldb_private { class ThreadPlanStepOut : public ThreadPlan, public ThreadPlanShouldStopHere { public: ThreadPlanStepOut(Thread &thread, SymbolContext *addr_context, - bool first_insn, bool stop_others, Vote stop_vote, - Vote run_vote, uint32_t frame_idx, + bool first_insn, bool stop_others, Vote report_stop_vote, + Vote report_run_vote, uint32_t frame_idx, LazyBool step_out_avoids_code_without_debug_info, bool continue_to_next_branch = false, bool gather_return_value = true); @@ -76,8 +76,9 @@ private: friend lldb::ThreadPlanSP Thread::QueueThreadPlanForStepOut( bool abort_other_plans, SymbolContext *addr_context, bool first_insn, - bool stop_others, Vote stop_vote, Vote run_vote, uint32_t frame_idx, - Status &status, LazyBool step_out_avoids_code_without_debug_info); + bool stop_others, Vote report_stop_vote, Vote report_run_vote, + uint32_t frame_idx, Status &status, + LazyBool step_out_avoids_code_without_debug_info); void SetupAvoidNoDebug(LazyBool step_out_avoids_code_without_debug_info); // Need an appropriate marker for the current stack so we can tell step out diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanTracer.h b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanTracer.h index 677a2c0dd93c..a6fd2f031dc2 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanTracer.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanTracer.h @@ -50,14 +50,6 @@ public: bool TracingEnabled() { return m_enabled; } - bool EnableSingleStep(bool value) { - bool old_value = m_single_step; - m_single_step = value; - return old_value; - } - - bool SingleStepEnabled() { return m_single_step; } - Thread &GetThread(); protected: @@ -71,7 +63,6 @@ protected: private: bool TracerExplainsStop(); - bool m_single_step; bool m_enabled; lldb::StreamSP m_stream_sp; Thread *m_thread; diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ThreadSpec.h b/contrib/llvm-project/lldb/include/lldb/Target/ThreadSpec.h index 8c22d53185ff..7c7c83274119 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/ThreadSpec.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/ThreadSpec.h @@ -120,8 +120,8 @@ private: return g_option_names[(size_t) enum_value]; } - uint32_t m_index; - lldb::tid_t m_tid; + uint32_t m_index = UINT32_MAX; + lldb::tid_t m_tid = LLDB_INVALID_THREAD_ID; std::string m_name; std::string m_queue_name; }; diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Trace.h b/contrib/llvm-project/lldb/include/lldb/Target/Trace.h index 3b127916a917..f5654988b201 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/Trace.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/Trace.h @@ -9,10 +9,15 @@ #ifndef LLDB_TARGET_TRACE_H #define LLDB_TARGET_TRACE_H +#include <unordered_map> + #include "llvm/Support/JSON.h" #include "lldb/Core/PluginInterface.h" +#include "lldb/Target/Thread.h" +#include "lldb/Target/TraceCursor.h" #include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/TraceGDBRemotePackets.h" #include "lldb/Utility/UnimplementedError.h" #include "lldb/lldb-private.h" @@ -36,15 +41,10 @@ namespace lldb_private { /// /// 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. +/// \a jLLDBTraceSupported. 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 @@ -94,8 +94,24 @@ public: /// 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); + FindPluginForPostMortemProcess(Debugger &debugger, + const llvm::json::Value &trace_session_file, + llvm::StringRef session_file_dir); + + /// Find a trace plug-in to trace a live process. + /// + /// \param[in] plugin_name + /// Plug-in name to search. + /// + /// \param[in] process + /// Live process to trace. + /// + /// \return + /// A \a TraceSP instance, or an \a llvm::Error if the plug-in name + /// doesn't match any registered plug-ins or tracing couldn't be + /// started. + static llvm::Expected<lldb::TraceSP> + FindPluginForLiveProcess(llvm::StringRef plugin_name, Process &process); /// Get the schema of a Trace plug-in given its name. /// @@ -104,98 +120,189 @@ public: static llvm::Expected<llvm::StringRef> FindPluginSchema(llvm::StringRef plugin_name); + /// Get the command handle for the "process trace start" command. + virtual lldb::CommandObjectSP + GetProcessTraceStartCommand(CommandInterpreter &interpreter) = 0; + + /// Get the command handle for the "thread trace start" command. + virtual lldb::CommandObjectSP + GetThreadTraceStartCommand(CommandInterpreter &interpreter) = 0; + /// \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. + /// Get a \a TraceCursor for the given thread's trace. /// /// \return - /// The current position of the thread's trace or \b 0 if empty. - virtual size_t GetCursorPosition(const Thread &thread) = 0; + /// A \a TraceCursorUP. If the thread is not traced or its trace + /// information failed to load, the corresponding error is embedded in the + /// trace. + virtual lldb::TraceCursorUP GetCursor(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. + /// Dump general info about a given thread's trace. Each Trace plug-in + /// decides which data to show. /// /// \param[in] thread - /// The thread whose trace will be dumped. + /// The thread that owns the trace in question. /// /// \param[in] s - /// The stream object where the instructions are printed. + /// The stream object where the info will be printed printed. /// - /// \param[in] count - /// The number of instructions to print. + /// \param[in] verbose + /// If \b true, print detailed info + /// If \b false, print compact info + virtual void DumpTraceInfo(Thread &thread, Stream &s, bool verbose) = 0; + + /// Check if a thread is currently traced by this object. + /// + /// \param[in] thread + /// The thread in question. /// - /// \param[in] end_position - /// The position of the last instruction to print. + /// \return + /// \b true if the thread is traced by this instance, \b false otherwise. + virtual bool IsTraced(const Thread &thread) = 0; + + /// \return + /// A description of the parameters to use for the \a Trace::Start method. + virtual const char *GetStartConfigurationHelp() = 0; + + /// Start tracing a live process. /// - /// \param[in] raw - /// Dump only instruction addresses without disassembly nor symbol + /// \param[in] configuration + /// See \a SBTrace::Start(const lldb::SBStructuredData &) for more /// information. - void DumpTraceInstructions(Thread &thread, Stream &s, size_t count, - size_t end_position, bool raw); + /// + /// \return + /// \a llvm::Error::success if the operation was successful, or + /// \a llvm::Error otherwise. + virtual llvm::Error Start( + StructuredData::ObjectSP configuration = StructuredData::ObjectSP()) = 0; - /// Run the provided callback on the instructions of the trace of the given - /// thread. + /// Start tracing live threads. /// - /// 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. + /// \param[in] tids + /// Threads to trace. This method tries to trace as many threads as + /// possible. /// - /// 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] configuration + /// See \a SBTrace::Start(const lldb::SBThread &, const + /// lldb::SBStructuredData &) for more information. /// - /// \param[in] thread - /// The thread whose trace will be traversed. + /// \return + /// \a llvm::Error::success if the operation was successful, or + /// \a llvm::Error otherwise. + virtual llvm::Error Start( + llvm::ArrayRef<lldb::tid_t> tids, + StructuredData::ObjectSP configuration = StructuredData::ObjectSP()) = 0; + + /// Stop tracing live threads. /// - /// \param[in] position - /// The instruction position to start iterating on. + /// \param[in] tids + /// The threads to stop tracing 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. + /// \return + /// \a llvm::Error::success if the operation was successful, or + /// \a llvm::Error otherwise. + llvm::Error Stop(llvm::ArrayRef<lldb::tid_t> tids); + + /// Stop tracing all current and future threads of a live process. + /// + /// \param[in] request + /// The information determining which threads or process to stop tracing. /// - /// \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; + /// \return + /// \a llvm::Error::success if the operation was successful, or + /// \a llvm::Error otherwise. + llvm::Error Stop(); + + /// Get the trace file of the given post mortem thread. + llvm::Expected<const FileSpec &> GetPostMortemTraceFile(lldb::tid_t tid); - /// Stop tracing a live thread + /// \return + /// The stop ID of the live process being traced, or an invalid stop ID + /// if the trace is in an error or invalid state. + uint32_t GetStopID(); + +protected: + /// Get binary data of a live thread given a data identifier. /// - /// \param[in] thread - /// The thread object to stop tracing. + /// \param[in] tid + /// The thread whose data is requested. + /// + /// \param[in] kind + /// The kind of data requested. /// /// \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>(); - } + /// A vector of bytes with the requested data, or an \a llvm::Error in + /// case of failures. + llvm::Expected<llvm::ArrayRef<uint8_t>> + GetLiveThreadBinaryData(lldb::tid_t tid, llvm::StringRef kind); - /// Get the number of available instructions in the trace of the given thread. + /// Get binary data of the current process given a data identifier. /// - /// \param[in] thread - /// The thread whose trace will be inspected. + /// \param[in] kind + /// The kind of data requested. /// /// \return - /// The total number of instructions in the trace. - virtual size_t GetInstructionCount(const Thread &thread) = 0; + /// A vector of bytes with the requested data, or an \a llvm::Error in + /// case of failures. + llvm::Expected<llvm::ArrayRef<uint8_t>> + GetLiveProcessBinaryData(llvm::StringRef kind); + + /// Get the size of the data returned by \a GetLiveThreadBinaryData + llvm::Optional<size_t> GetLiveThreadBinaryDataSize(lldb::tid_t tid, + llvm::StringRef kind); + + /// Get the size of the data returned by \a GetLiveProcessBinaryData + llvm::Optional<size_t> GetLiveProcessBinaryDataSize(llvm::StringRef kind); + /// Constructor for post mortem processes + Trace() = default; + + /// Constructor for a live process + Trace(Process &live_process) : m_live_process(&live_process) {} + + /// Start tracing a live process or its threads. + /// + /// \param[in] request + /// JSON object with the information necessary to start tracing. In the + /// case of gdb-remote processes, this JSON object should conform to the + /// jLLDBTraceStart packet. + /// + /// \return + /// \a llvm::Error::success if the operation was successful, or + /// \a llvm::Error otherwise. + llvm::Error Start(const llvm::json::Value &request); + + /// Get the current tracing state of a live process and its threads. + /// + /// \return + /// A JSON object string with custom data depending on the trace + /// technology, or an \a llvm::Error in case of errors. + llvm::Expected<std::string> GetLiveProcessState(); + + /// Method to be overriden by the plug-in to refresh its own state. + /// + /// This is invoked by RefreshLiveProcessState when a new state is found. + /// + /// \param[in] state + /// The jLLDBTraceGetState response. + virtual void + DoRefreshLiveProcessState(llvm::Expected<TraceGetStateResponse> state) = 0; + + /// Method to be invoked by the plug-in to refresh the live process state. + /// + /// The result is cached through the same process stop. + void RefreshLiveProcessState(); + + uint32_t m_stop_id = LLDB_INVALID_STOP_ID; + /// Process traced by this object if doing live tracing. Otherwise it's null. + Process *m_live_process = nullptr; + /// tid -> data kind -> size + std::map<lldb::tid_t, std::unordered_map<std::string, size_t>> + m_live_thread_data; + /// data kind -> size + std::unordered_map<std::string, size_t> m_live_process_data; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Target/TraceCursor.h b/contrib/llvm-project/lldb/include/lldb/Target/TraceCursor.h new file mode 100644 index 000000000000..14fc00d5f95b --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Target/TraceCursor.h @@ -0,0 +1,211 @@ +//===-- TraceCursor.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_CURSOR_H +#define LLDB_TARGET_TRACE_CURSOR_H + +#include "lldb/lldb-private.h" + +#include "lldb/Target/ExecutionContext.h" + +namespace lldb_private { + +/// Class used for iterating over the instructions of a thread's trace. +/// +/// This class attempts to be a generic interface for accessing the instructions +/// of the trace so that each Trace plug-in can reconstruct, represent and store +/// the instruction data in an flexible way that is efficient for the given +/// technology. +/// +/// Live processes: +/// In the case of a live process trace, an instance of a \a TraceCursor should +/// point to the trace at the moment it was collected. If the process is later +/// resumed and new trace data is collected, that should leave that old cursor +/// unaffected. +/// +/// Errors in the trace: +/// As there could be errors when reconstructing the instructions of a trace, +/// these errors are represented as failed instructions, and the cursor can +/// point at them. The consumer should invoke \a TraceCursor::GetError() to +/// check if the cursor is pointing to either a valid instruction or an error. +/// +/// Instructions: +/// A \a TraceCursor always points to a specific instruction or error in the +/// trace. +/// +/// Defaults: +/// By default, the cursor points at the end item of the trace, moves +/// backwards, has a move granularity of \a +/// eTraceInstructionControlFlowTypeInstruction (i.e. visit every instruction) +/// and stops at every error (the "ignore errors" flag is \b false). See the +/// \a TraceCursor::Next() method for more documentation. +/// +/// Sample usage: +/// +/// TraceCursorUP cursor = trace.GetTrace(thread); +/// +/// cursor->SetGranularity(eTraceInstructionControlFlowTypeCall | +/// eTraceInstructionControlFlowTypeReturn); +/// +/// do { +/// if (llvm::Error error = cursor->GetError()) +/// cout << "error found at: " << llvm::toString(error) << endl; +/// else if (cursor->GetInstructionControlFlowType() & +/// eTraceInstructionControlFlowTypeCall) +/// std::cout << "call found at " << cursor->GetLoadAddress() << +/// std::endl; +/// else if (cursor->GetInstructionControlFlowType() & +/// eTraceInstructionControlFlowTypeReturn) +/// std::cout << "return found at " << cursor->GetLoadAddress() << +/// std::endl; +/// } while(cursor->Next()); +/// +/// Low level traversal: +/// Unlike the \a TraceCursor::Next() API, which uses a given granularity and +/// direction to advance the cursor, the \a TraceCursor::Seek() method can be +/// used to reposition the cursor to an offset of the end, beginning, or +/// current position of the trace. +class TraceCursor { +public: + /// Helper enum to indicate the reference point when invoking + /// \a TraceCursor::Seek(). + enum class SeekType { + /// The beginning of the trace, i.e the oldest item. + Set = 0, + /// The current position in the trace. + Current, + /// The end of the trace, i.e the most recent item. + End + }; + + /// Create a cursor that initially points to the end of the trace, i.e. the + /// most recent item. + TraceCursor(lldb::ThreadSP thread_sp); + + virtual ~TraceCursor() = default; + + /// Set the granularity to use in the \a TraceCursor::Next() method. + void SetGranularity(lldb::TraceInstructionControlFlowType granularity); + + /// Set the "ignore errors" flag to use in the \a TraceCursor::Next() method. + void SetIgnoreErrors(bool ignore_errors); + + /// Set the direction to use in the \a TraceCursor::Next() method. + /// + /// \param[in] forwards + /// If \b true, then the traversal will be forwards, otherwise backwards. + void SetForwards(bool forwards); + + /// Check if the direction to use in the \a TraceCursor::Next() method is + /// forwards. + /// + /// \return + /// \b true if the current direction is forwards, \b false if backwards. + bool IsForwards() const; + + /// Move the cursor to the next instruction that matches the current + /// granularity. + /// + /// Direction: + /// The traversal is done following the current direction of the trace. If + /// it is forwards, the instructions are visited forwards + /// chronologically. Otherwise, the traversal is done in + /// the opposite direction. By default, a cursor moves backwards unless + /// changed with \a TraceCursor::SetForwards(). + /// + /// Granularity: + /// The cursor will traverse the trace looking for the first instruction + /// that matches the current granularity. If there aren't any matching + /// instructions, the cursor won't move, to give the opportunity of + /// changing granularities. + /// + /// Ignore errors: + /// If the "ignore errors" flags is \b false, the traversal will stop as + /// soon as it finds an error in the trace and the cursor will point at + /// it. + /// + /// \return + /// \b true if the cursor effectively moved, \b false otherwise. + virtual bool Next() = 0; + + /// Make the cursor point to an item in the trace based on an origin point and + /// an offset. This API doesn't distinguishes instruction types nor errors in + /// the trace, unlike the \a TraceCursor::Next() method. + /// + /// The resulting position of the trace is + /// origin + offset + /// + /// If this resulting position would be out of bounds, it will be adjusted to + /// the last or first item in the trace correspondingly. + /// + /// \param[in] offset + /// How many items to move forwards (if positive) or backwards (if + /// negative) from the given origin point. + /// + /// \param[in] origin + /// The reference point to use when moving the cursor. + /// + /// \return + /// The number of trace items moved from the origin. + virtual size_t Seek(ssize_t offset, SeekType origin) = 0; + + /// \return + /// The \a ExecutionContextRef of the backing thread from the creation time + /// of this cursor. + ExecutionContextRef &GetExecutionContextRef(); + + /// Instruction or error information + /// \{ + + /// \return + /// Whether the cursor points to an error or not. + virtual bool IsError() = 0; + + /// Get the corresponding error message if the cursor points to an error in + /// the trace. + /// + /// \return + /// \b llvm::Error::success if the cursor is not pointing to an error in + /// the trace. Otherwise return an \a llvm::Error describing the issue. + virtual llvm::Error GetError() = 0; + + /// \return + /// The load address of the instruction the cursor is pointing at. If the + /// cursor points to an error in the trace, return \b + /// LLDB_INVALID_ADDRESS. + virtual lldb::addr_t GetLoadAddress() = 0; + + /// Get the timestamp counter associated with the current instruction. + /// Modern Intel, ARM and AMD processors support this counter. However, a + /// trace plugin might decide to use a different time unit instead of an + /// actual TSC. + /// + /// \return + /// The timestamp or \b llvm::None if not available. + virtual llvm::Optional<uint64_t> GetTimestampCounter() = 0; + + /// \return + /// The \a lldb::TraceInstructionControlFlowType categories the + /// instruction the cursor is pointing at falls into. If the cursor points + /// to an error in the trace, return \b 0. + virtual lldb::TraceInstructionControlFlowType + GetInstructionControlFlowType() = 0; + /// \} + +protected: + ExecutionContextRef m_exe_ctx_ref; + + lldb::TraceInstructionControlFlowType m_granularity = + lldb::eTraceInstructionControlFlowTypeInstruction; + bool m_ignore_errors = false; + bool m_forwards = false; +}; + +} // namespace lldb_private + +#endif // LLDB_TARGET_TRACE_CURSOR_H diff --git a/contrib/llvm-project/lldb/include/lldb/Target/TraceExporter.h b/contrib/llvm-project/lldb/include/lldb/Target/TraceExporter.h new file mode 100644 index 000000000000..6560b39fd42e --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Target/TraceExporter.h @@ -0,0 +1,42 @@ +//===-- TraceExporter.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_EXPORTER_H +#define LLDB_TARGET_TRACE_EXPORTER_H + +#include "lldb/Core/PluginInterface.h" + +namespace lldb_private { + +/// \class TraceExporter TraceExporter.h "lldb/Target/TraceExporter.h" +/// A plug-in interface definition class for trace exporters. +/// +/// Trace exporter plug-ins operate on traces, converting the trace data +/// provided by an \a lldb_private::TraceCursor into a different format that can +/// be digested by other tools, e.g. Chrome Trace Event Profiler. +/// +/// Trace exporters are supposed to operate on an architecture-agnostic fashion, +/// as a TraceCursor, which feeds the data, hides the actual trace technology +/// being used. +class TraceExporter : public PluginInterface { +public: + /// Create an instance of a trace exporter plugin given its name. + /// + /// \param[in] plugin_Name + /// Plug-in name to search. + /// + /// \return + /// A \a TraceExporterUP instance, or an \a llvm::Error if the plug-in + /// name doesn't match any registered plug-ins. + static llvm::Expected<lldb::TraceExporterUP> + FindPlugin(llvm::StringRef plugin_name); +}; + +} // namespace lldb_private + +#endif // LLDB_TARGET_TRACE_EXPORTER_H diff --git a/contrib/llvm-project/lldb/include/lldb/Target/TraceInstructionDumper.h b/contrib/llvm-project/lldb/include/lldb/Target/TraceInstructionDumper.h new file mode 100644 index 000000000000..c4878bfd3fd5 --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Target/TraceInstructionDumper.h @@ -0,0 +1,77 @@ +//===-- TraceInstructionDumper.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 +// +//===----------------------------------------------------------------------===// + +#include "lldb/Target/TraceCursor.h" + +#ifndef LLDB_TARGET_TRACE_INSTRUCTION_DUMPER_H +#define LLDB_TARGET_TRACE_INSTRUCTION_DUMPER_H + +namespace lldb_private { + +/// Class used to dump the instructions of a \a TraceCursor using its current +/// state and granularity. +class TraceInstructionDumper { +public: + /// Create a instruction dumper for the cursor. + /// + /// \param[in] cursor + /// The cursor whose instructions will be dumped. + /// + /// \param[in] initial_index + /// Presentation index to use for referring to the current instruction + /// of the cursor. If the direction is forwards, the index will increase, + /// and if the direction is backwards, the index will decrease. + /// + /// \param[in] raw + /// Dump only instruction addresses without disassembly nor symbol + /// information. + /// + /// \param[in] show_tsc + /// For each instruction, print the corresponding timestamp counter if + /// available. + TraceInstructionDumper(lldb::TraceCursorUP &&cursor_up, int initial_index = 0, + bool raw = false, bool show_tsc = false); + + /// Dump \a count instructions of the thread trace starting at the current + /// cursor position. + /// + /// This effectively moves the cursor to the next unvisited position, so that + /// a subsequent call to this method continues where it left off. + /// + /// \param[in] s + /// The stream object where the instructions are printed. + /// + /// \param[in] count + /// The number of instructions to print. + void DumpInstructions(Stream &s, size_t count); + + /// Indicate the dumper that no more data is available in the trace. + void SetNoMoreData(); + + /// \return + /// \b true if there's still more data to traverse in the trace. + bool HasMoreData(); + +private: + /// Move the cursor one step. + /// + /// \return + /// \b true if the cursor moved. + bool TryMoveOneStep(); + + lldb::TraceCursorUP m_cursor_up; + int m_index; + bool m_raw; + bool m_show_tsc; + /// If \b true, all the instructions have been traversed. + bool m_no_more_data = false; +}; + +} // namespace lldb_private + +#endif // LLDB_TARGET_TRACE_INSTRUCTION_DUMPER_H diff --git a/contrib/llvm-project/lldb/include/lldb/Target/UnixSignals.h b/contrib/llvm-project/lldb/include/lldb/Target/UnixSignals.h index cc24b76e4c3f..6fecdda12def 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/UnixSignals.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/UnixSignals.h @@ -104,7 +104,7 @@ protected: Signal(const char *name, bool default_suppress, bool default_stop, bool default_notify, const char *description, const char *alias); - ~Signal() {} + ~Signal() = default; }; virtual void Reset(); diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Unwind.h b/contrib/llvm-project/lldb/include/lldb/Target/Unwind.h index 783b7103e8fe..3faef139b00a 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/Unwind.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/Unwind.h @@ -21,7 +21,7 @@ protected: Unwind(Thread &thread) : m_thread(thread), m_unwind_mutex() {} public: - virtual ~Unwind() {} + virtual ~Unwind() = default; void Clear() { std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex); diff --git a/contrib/llvm-project/lldb/include/lldb/Target/UnwindLLDB.h b/contrib/llvm-project/lldb/include/lldb/Target/UnwindLLDB.h index c7c9cfbccbad..f6750171c54a 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/UnwindLLDB.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/UnwindLLDB.h @@ -109,17 +109,17 @@ protected: private: struct Cursor { - lldb::addr_t start_pc; // The start address of the function/symbol for this - // frame - current pc if unknown - lldb::addr_t cfa; // The canonical frame address for this stack frame + lldb::addr_t start_pc = + LLDB_INVALID_ADDRESS; // The start address of the function/symbol for + // this frame - current pc if unknown + lldb::addr_t cfa = LLDB_INVALID_ADDRESS; // The canonical frame address for + // this stack frame lldb_private::SymbolContext sctx; // A symbol context we'll contribute to & // provide to the StackFrame creation RegisterContextLLDBSP reg_ctx_lldb_sp; // These are all RegisterContextUnwind's - Cursor() - : start_pc(LLDB_INVALID_ADDRESS), cfa(LLDB_INVALID_ADDRESS), sctx(), - reg_ctx_lldb_sp() {} + Cursor() : sctx(), reg_ctx_lldb_sp() {} private: Cursor(const Cursor &) = delete; diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Args.h b/contrib/llvm-project/lldb/include/lldb/Utility/Args.h index b93677b53935..cecf6b1502b5 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/Args.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/Args.h @@ -115,7 +115,8 @@ public: /// /// \return /// The number or arguments in this object. - size_t GetArgumentCount() const; + size_t GetArgumentCount() const { return m_entries.size(); } + bool empty() const { return GetArgumentCount() == 0; } /// Gets the NULL terminated C string argument pointer for the argument at @@ -252,9 +253,9 @@ public: /// If the argument was originally quoted, put in the quote char here. void Unshift(llvm::StringRef arg_str, char quote_char = '\0'); - // Clear the arguments. - // - // For re-setting or blanking out the list of arguments. + /// Clear the arguments. + /// + /// For re-setting or blanking out the list of arguments. void Clear(); static lldb::Encoding @@ -266,21 +267,20 @@ public: 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 - // this for all of the supported escaped sequences and for the \0ooo (octal) - // and \xXX (hex). The resulting "dst" string will contain the character - // versions of all supported escape sequences. The common supported escape - // sequences are: "\a", "\b", "\f", "\n", "\r", "\t", "\v", "\'", "\"", "\\". - + /// EncodeEscapeSequences will change the textual representation of common + /// escape sequences like "\n" (two characters) into a single '\n'. It does + /// this for all of the supported escaped sequences and for the \0ooo (octal) + /// and \xXX (hex). The resulting "dst" string will contain the character + /// versions of all supported escape sequences. The common supported escape + /// sequences are: "\a", "\b", "\f", "\n", "\r", "\t", "\v", "\'", "\"", "\\". static void EncodeEscapeSequences(const char *src, std::string &dst); - // ExpandEscapeSequences will change a string of possibly non-printable - // characters and expand them into text. So '\n' will turn into two - // characters like "\n" which is suitable for human reading. When a character - // is not printable and isn't one of the common in escape sequences listed in - // the help for EncodeEscapeSequences, then it will be encoded as octal. - // Printable characters are left alone. + /// ExpandEscapeSequences will change a string of possibly non-printable + /// characters and expand them into text. So '\n' will turn into two + /// characters like "\n" which is suitable for human reading. When a character + /// is not printable and isn't one of the common in escape sequences listed in + /// the help for EncodeEscapeSequences, then it will be encoded as octal. + /// Printable characters are left alone. static void ExpandEscapedCharacters(const char *src, std::string &dst); static std::string EscapeLLDBCommandArgument(const std::string &arg, @@ -290,6 +290,10 @@ private: friend struct llvm::yaml::MappingTraits<Args>; std::vector<ArgEntry> m_entries; + /// The arguments as C strings with a trailing nullptr element. + /// + /// These strings are owned by the ArgEntry object in m_entries with the + /// same index. std::vector<char *> m_argv; }; diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Baton.h b/contrib/llvm-project/lldb/include/lldb/Utility/Baton.h index 010f8da43868..8a2f04163682 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/Baton.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/Baton.h @@ -34,8 +34,8 @@ namespace lldb_private { /// needed resources in their destructors. class Baton { public: - Baton() {} - virtual ~Baton() {} + Baton() = default; + virtual ~Baton() = default; virtual void *data() = 0; diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Cloneable.h b/contrib/llvm-project/lldb/include/lldb/Utility/Cloneable.h new file mode 100644 index 000000000000..4c9b7ae340dc --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Utility/Cloneable.h @@ -0,0 +1,56 @@ +//===-- Cloneable.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_CLONEABLE_H +#define LLDB_UTILITY_CLONEABLE_H + +#include <memory> +#include <type_traits> + +namespace lldb_private { + +/// \class Cloneable Cloneable.h "lldb/Utility/Cloneable.h" +/// A class that implements CRTP-based "virtual constructor" idiom. +/// +/// Example: +/// @code +/// class Base { +/// using TopmostBase = Base; +/// public: +/// virtual std::shared_ptr<Base> Clone() const = 0; +/// }; +/// @endcode +/// +/// To define a class derived from the Base with overridden Clone: +/// @code +/// class Intermediate : public Cloneable<Intermediate, Base> {}; +/// @endcode +/// +/// To define a class at the next level of inheritance with overridden Clone: +/// @code +/// class Derived : public Cloneable<Derived, Intermediate> {}; +/// @endcode + +template <typename Derived, typename Base> +class Cloneable : public Base { +public: + using Base::Base; + + std::shared_ptr<typename Base::TopmostBase> Clone() const override { + // std::is_base_of requires derived type to be complete, that's why class + // scope static_assert cannot be used. + static_assert(std::is_base_of<Cloneable, Derived>::value, + "Derived class must be derived from this."); + + return std::make_shared<Derived>(static_cast<const Derived &>(*this)); + } +}; + +} // namespace lldb_private + +#endif // LLDB_UTILITY_CLONEABLE_H diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Connection.h b/contrib/llvm-project/lldb/include/lldb/Utility/Connection.h index 39e6e40191b0..0b587b81c999 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/Connection.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/Connection.h @@ -18,7 +18,7 @@ #include <ratio> #include <string> -#include <stddef.h> +#include <cstddef> namespace lldb_private { class Status; diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/ConstString.h b/contrib/llvm-project/lldb/include/lldb/Utility/ConstString.h index 8a67faf5b54a..52d3556418f6 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/ConstString.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/ConstString.h @@ -14,7 +14,7 @@ #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/YAMLTraits.h" -#include <stddef.h> +#include <cstddef> namespace lldb_private { class Stream; diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/DataBuffer.h b/contrib/llvm-project/lldb/include/lldb/Utility/DataBuffer.h index 302b13307958..c778299b89ad 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/DataBuffer.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/DataBuffer.h @@ -10,8 +10,8 @@ #define LLDB_UTILITY_DATABUFFER_H #if defined(__cplusplus) -#include <stdint.h> -#include <string.h> +#include <cstdint> +#include <cstring> #include "lldb/lldb-types.h" @@ -48,7 +48,7 @@ public: /// and be downcast to the DataBuffer pure virtual interface. The virtual /// destructor ensures that destructing the base class will destruct the /// class that inherited from it correctly. - virtual ~DataBuffer() {} + virtual ~DataBuffer() = default; /// Get a pointer to the data. /// diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/DataBufferLLVM.h b/contrib/llvm-project/lldb/include/lldb/Utility/DataBufferLLVM.h index 4dc800c348c5..abb1bb40d534 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/DataBufferLLVM.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/DataBufferLLVM.h @@ -12,8 +12,8 @@ #include "lldb/Utility/DataBuffer.h" #include "lldb/lldb-types.h" +#include <cstdint> #include <memory> -#include <stdint.h> namespace llvm { class WritableMemoryBuffer; diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/DataEncoder.h b/contrib/llvm-project/lldb/include/lldb/Utility/DataEncoder.h index 8edec54c36f5..b944c09d5c47 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/DataEncoder.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/DataEncoder.h @@ -16,8 +16,8 @@ #include "lldb/lldb-forward.h" #include "lldb/lldb-types.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { @@ -226,10 +226,10 @@ private: size_t GetByteSize() const { return m_end - m_start; } /// A pointer to the first byte of data. - uint8_t *m_start; + uint8_t *m_start = nullptr; /// A pointer to the byte that is past the end of the data. - uint8_t *m_end; + uint8_t *m_end = nullptr; /// The byte order of the data we are extracting from. lldb::ByteOrder m_byte_order; diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/DataExtractor.h b/contrib/llvm-project/lldb/include/lldb/Utility/DataExtractor.h index 0210af5cf6d1..0923e5280cba 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/DataExtractor.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/DataExtractor.h @@ -19,8 +19,8 @@ #include "llvm/Support/SwapByteOrder.h" #include <cassert> -#include <stdint.h> -#include <string.h> +#include <cstdint> +#include <cstring> namespace lldb_private { class Log; @@ -997,15 +997,15 @@ protected: } // Member variables - const uint8_t *m_start; ///< A pointer to the first byte of data. - const uint8_t - *m_end; ///< A pointer to the byte that is past the end of the data. + const uint8_t *m_start = nullptr; ///< A pointer to the first byte of data. + const uint8_t *m_end = + nullptr; ///< A pointer to the byte that is past the end of the data. lldb::ByteOrder m_byte_order; ///< The byte order of the data we are extracting from. uint32_t m_addr_size; ///< The address size to use when extracting addresses. /// The shared pointer to data that can be shared among multiple instances lldb::DataBufferSP m_data_sp; - const uint32_t m_target_byte_size; + const uint32_t m_target_byte_size = 1; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Endian.h b/contrib/llvm-project/lldb/include/lldb/Utility/Endian.h index 1d1f8fa333b8..7822dfa766dc 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/Endian.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/Endian.h @@ -11,7 +11,7 @@ #include "lldb/lldb-enumerations.h" -#include <stdint.h> +#include <cstdint> namespace lldb_private { diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Event.h b/contrib/llvm-project/lldb/include/lldb/Utility/Event.h index 06c02629d448..4e38f98a02f3 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/Event.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/Event.h @@ -22,8 +22,8 @@ #include <memory> #include <string> -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class Event; @@ -101,7 +101,7 @@ class EventDataReceipt : public EventData { public: EventDataReceipt() : EventData(), m_predicate(false) {} - ~EventDataReceipt() override {} + ~EventDataReceipt() override = default; static ConstString GetFlavorString() { static ConstString g_flavor("Process::ProcessEventData"); diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/FileSpec.h b/contrib/llvm-project/lldb/include/lldb/Utility/FileSpec.h index f7cbeb247100..0f4e6505e433 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/FileSpec.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/FileSpec.h @@ -20,8 +20,8 @@ #include "llvm/Support/Path.h" #include "llvm/Support/YAMLTraits.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class Stream; @@ -38,7 +38,7 @@ template <typename T> class SmallVectorImpl; namespace lldb_private { -/// \class FileSpec FileSpec.h "lldb/Host/FileSpec.h" +/// \class FileSpec FileSpec.h "lldb/Utility/FileSpec.h" /// A file utility class. /// /// A file specification class that divides paths up into a directory diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/GDBRemote.h b/contrib/llvm-project/lldb/include/lldb/Utility/GDBRemote.h index 2ee706efbea2..f658818de806 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/GDBRemote.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/GDBRemote.h @@ -17,8 +17,8 @@ #include "llvm/Support/YAMLTraits.h" #include "llvm/Support/raw_ostream.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> #include <string> #include <vector> @@ -55,9 +55,7 @@ struct GDBRemotePacket { enum Type { ePacketTypeInvalid = 0, ePacketTypeSend, ePacketTypeRecv }; - GDBRemotePacket() - : packet(), type(ePacketTypeInvalid), bytes_transmitted(0), packet_idx(0), - tid(LLDB_INVALID_THREAD_ID) {} + GDBRemotePacket() : packet() {} void Clear() { packet.data.clear(); @@ -74,10 +72,10 @@ struct GDBRemotePacket { void Dump(Stream &strm) const; BinaryData packet; - Type type; - uint32_t bytes_transmitted; - uint32_t packet_idx; - lldb::tid_t tid; + Type type = ePacketTypeInvalid; + uint32_t bytes_transmitted = 0; + uint32_t packet_idx = 0; + lldb::tid_t tid = LLDB_INVALID_THREAD_ID; private: llvm::StringRef GetTypeStr() const; diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/IOObject.h b/contrib/llvm-project/lldb/include/lldb/Utility/IOObject.h index 9b2b9cfcfec0..8cf42992e7be 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/IOObject.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/IOObject.h @@ -9,8 +9,8 @@ #ifndef LLDB_UTILITY_IOOBJECT_H #define LLDB_UTILITY_IOOBJECT_H -#include <stdarg.h> -#include <stdio.h> +#include <cstdarg> +#include <cstdio> #include <sys/types.h> #include "lldb/lldb-private.h" diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/LLDBAssert.h b/contrib/llvm-project/lldb/include/lldb/Utility/LLDBAssert.h index 845af1d4cc2a..471a2f7e824f 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/LLDBAssert.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/LLDBAssert.h @@ -20,6 +20,6 @@ namespace lldb_private { void lldb_assert(bool expression, const char *expr_text, const char *func, const char *file, unsigned int line); -} +} // namespace lldb_private #endif // LLDB_UTILITY_LLDBASSERT_H diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Listener.h b/contrib/llvm-project/lldb/include/lldb/Utility/Listener.h index 9d96e36c5abc..d70e778c9480 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/Listener.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/Listener.h @@ -23,8 +23,8 @@ #include <string> #include <vector> -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class ConstString; diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Predicate.h b/contrib/llvm-project/lldb/include/lldb/Utility/Predicate.h index a17ac05f6e56..af16abc1a1d3 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/Predicate.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/Predicate.h @@ -9,8 +9,8 @@ #ifndef LLDB_UTILITY_PREDICATE_H #define LLDB_UTILITY_PREDICATE_H -#include <stdint.h> -#include <time.h> +#include <cstdint> +#include <ctime> #include <condition_variable> #include <mutex> diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/ProcessInfo.h b/contrib/llvm-project/lldb/include/lldb/Utility/ProcessInfo.h index 8f5a5f6d21fb..3c5956926391 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/ProcessInfo.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/ProcessInfo.h @@ -95,10 +95,10 @@ protected: // the resolved platform executable (which is in m_executable) Args m_arguments; // All program arguments except argv[0] Environment m_environment; - uint32_t m_uid; - uint32_t m_gid; + uint32_t m_uid = UINT32_MAX; + uint32_t m_gid = UINT32_MAX; ArchSpec m_arch; - lldb::pid_t m_pid; + lldb::pid_t m_pid = LLDB_INVALID_PROCESS_ID; }; // ProcessInstanceInfo @@ -107,9 +107,7 @@ protected: // to that process. class ProcessInstanceInfo : public ProcessInfo { public: - ProcessInstanceInfo() - : ProcessInfo(), m_euid(UINT32_MAX), m_egid(UINT32_MAX), - m_parent_pid(LLDB_INVALID_PROCESS_ID) {} + ProcessInstanceInfo() : ProcessInfo() {} ProcessInstanceInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) : ProcessInfo(name, arch, pid), m_euid(UINT32_MAX), m_egid(UINT32_MAX), @@ -151,9 +149,9 @@ public: protected: friend struct llvm::yaml::MappingTraits<ProcessInstanceInfo>; - uint32_t m_euid; - uint32_t m_egid; - lldb::pid_t m_parent_pid; + uint32_t m_euid = UINT32_MAX; + uint32_t m_egid = UINT32_MAX; + lldb::pid_t m_parent_pid = LLDB_INVALID_PROCESS_ID; }; typedef std::vector<ProcessInstanceInfo> ProcessInstanceInfoList; @@ -164,9 +162,7 @@ typedef std::vector<ProcessInstanceInfo> ProcessInstanceInfoList; class ProcessInstanceInfoMatch { public: - ProcessInstanceInfoMatch() - : m_match_info(), m_name_match_type(NameMatch::Ignore), - m_match_all_users(false) {} + ProcessInstanceInfoMatch() : m_match_info() {} ProcessInstanceInfoMatch(const char *process_name, NameMatch process_name_match_type) @@ -211,8 +207,8 @@ public: protected: ProcessInstanceInfo m_match_info; - NameMatch m_name_match_type; - bool m_match_all_users; + NameMatch m_name_match_type = NameMatch::Ignore; + bool m_match_all_users = false; }; namespace repro { diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/RegisterValue.h b/contrib/llvm-project/lldb/include/lldb/Utility/RegisterValue.h index 4211b0a59992..1ece4f0eb79f 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/RegisterValue.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/RegisterValue.h @@ -43,8 +43,7 @@ public: eTypeBytes }; - RegisterValue() - : m_type(eTypeInvalid), m_scalar(static_cast<unsigned long>(0)) {} + RegisterValue() : m_scalar(static_cast<unsigned long>(0)) {} explicit RegisterValue(uint8_t inst) : m_type(eTypeUInt8) { m_scalar = inst; } @@ -257,7 +256,7 @@ public: void Clear(); protected: - RegisterValue::Type m_type; + RegisterValue::Type m_type = eTypeInvalid; Scalar m_scalar; struct { diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/ReproducerInstrumentation.h b/contrib/llvm-project/lldb/include/lldb/Utility/ReproducerInstrumentation.h index c8a98adf85c7..2b2d273a17a8 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/ReproducerInstrumentation.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/ReproducerInstrumentation.h @@ -469,7 +469,7 @@ template <> struct DeserializationHelper<> { /// The replayer interface. struct Replayer { - virtual ~Replayer() {} + virtual ~Replayer() = default; virtual void operator()(Deserializer &deserializer) const = 0; }; @@ -714,8 +714,7 @@ protected: friend llvm::optional_detail::OptionalStorage<InstrumentationData, true>; friend llvm::Optional<InstrumentationData>; - InstrumentationData() - : m_serializer(nullptr), m_deserializer(nullptr), m_registry(nullptr) {} + InstrumentationData() = default; InstrumentationData(Serializer &serializer, Registry ®istry) : m_serializer(&serializer), m_deserializer(nullptr), m_registry(®istry) {} @@ -726,9 +725,9 @@ protected: private: static llvm::Optional<InstrumentationData> &InstanceImpl(); - Serializer *m_serializer; - Deserializer *m_deserializer; - Registry *m_registry; + Serializer *m_serializer = nullptr; + Deserializer *m_deserializer = nullptr; + Registry *m_registry = nullptr; }; struct EmptyArg {}; @@ -888,17 +887,17 @@ private: } #endif - Serializer *m_serializer; + Serializer *m_serializer = nullptr; /// Pretty function for logging. llvm::StringRef m_pretty_func; std::string m_pretty_args; /// Whether this function call was the one crossing the API boundary. - bool m_local_boundary; + bool m_local_boundary = false; /// Whether the return value was recorded explicitly. - bool m_result_recorded; + bool m_result_recorded = true; /// The sequence number for this pair of function and result. unsigned m_sequence; diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/ReproducerProvider.h b/contrib/llvm-project/lldb/include/lldb/Utility/ReproducerProvider.h index 221c0eb9c5bb..db7378069a87 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/ReproducerProvider.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/ReproducerProvider.h @@ -32,7 +32,8 @@ 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) {} + m_os(filename.GetPath(), ec, llvm::sys::fs::OF_TextWithCRLF), + m_record(true) {} public: const FileSpec &GetFilename() { return m_filename; } @@ -168,7 +169,7 @@ public: 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); + llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_TextWithCRLF); if (ec) return; os << m_directory << "\n"; @@ -290,7 +291,7 @@ public: 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); + llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_TextWithCRLF); if (ec) return; llvm::yaml::Output yout(os); diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Scalar.h b/contrib/llvm-project/lldb/include/lldb/Utility/Scalar.h index f797aaf99626..2801b1bd6326 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/Scalar.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/Scalar.h @@ -49,7 +49,7 @@ public: }; // Constructors and Destructors - Scalar() : m_type(e_void), m_float(0.0f) {} + Scalar() : 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) {} @@ -187,7 +187,7 @@ public: size_t byte_size); protected: - Scalar::Type m_type; + Scalar::Type m_type = e_void; llvm::APSInt m_integer; llvm::APFloat m_float; diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Status.h b/contrib/llvm-project/lldb/include/lldb/Utility/Status.h index 9babad18edc0..61d663bdccba 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/Status.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/Status.h @@ -15,7 +15,7 @@ #include "llvm/Support/Error.h" #include "llvm/Support/FormatVariadic.h" #include <cstdarg> -#include <stdint.h> +#include <cstdint> #include <string> #include <system_error> #include <type_traits> @@ -196,8 +196,9 @@ public: protected: /// Member variables - ValueType m_code; ///< Status code as an integer value. - lldb::ErrorType m_type; ///< The type of the above error code. + ValueType m_code = 0; ///< Status code as an integer value. + lldb::ErrorType m_type = + lldb::eErrorTypeInvalid; ///< The type of the above error code. mutable std::string m_string; ///< A string representation of the error code. }; diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Stream.h b/contrib/llvm-project/lldb/include/lldb/Utility/Stream.h index e7f065a1fc7b..1a5fd343e4df 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/Stream.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/Stream.h @@ -16,9 +16,9 @@ #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/raw_ostream.h" -#include <stdarg.h> -#include <stddef.h> -#include <stdint.h> +#include <cstdarg> +#include <cstddef> +#include <cstdint> #include <type_traits> namespace lldb_private { @@ -361,10 +361,10 @@ public: protected: // Member variables Flags m_flags; ///< Dump flags. - uint32_t m_addr_size; ///< Size of an address in bytes. + uint32_t m_addr_size = 4; ///< Size of an address in bytes. lldb::ByteOrder m_byte_order; ///< Byte order to use when encoding scalar types. - unsigned m_indent_level; ///< Indention level. + unsigned m_indent_level = 0; ///< Indention level. std::size_t m_bytes_written = 0; ///< Number of bytes written so far. void _PutHex8(uint8_t uvalue, bool add_prefix); diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/StreamCallback.h b/contrib/llvm-project/lldb/include/lldb/Utility/StreamCallback.h index d6d74fb84799..d234cbea85c6 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/StreamCallback.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/StreamCallback.h @@ -12,8 +12,8 @@ #include "lldb/lldb-types.h" #include "llvm/Support/raw_ostream.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/StreamString.h b/contrib/llvm-project/lldb/include/lldb/Utility/StreamString.h index b0be0f7dd76a..4c568acdcc6f 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/StreamString.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/StreamString.h @@ -15,8 +15,8 @@ #include <string> -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/StreamTee.h b/contrib/llvm-project/lldb/include/lldb/Utility/StreamTee.h index 2995bc07f42a..b5d3b9679e91 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/StreamTee.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/StreamTee.h @@ -9,7 +9,7 @@ #ifndef LLDB_UTILITY_STREAMTEE_H #define LLDB_UTILITY_STREAMTEE_H -#include <limits.h> +#include <climits> #include <mutex> @@ -45,7 +45,7 @@ public: m_streams = rhs.m_streams; } - ~StreamTee() override {} + ~StreamTee() override = default; StreamTee &operator=(const StreamTee &rhs) { if (this != &rhs) { diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/StringExtractor.h b/contrib/llvm-project/lldb/include/lldb/Utility/StringExtractor.h index 6a5bb24779a4..a4819378ce32 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/StringExtractor.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/StringExtractor.h @@ -12,8 +12,8 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> #include <string> class StringExtractor { @@ -115,7 +115,7 @@ protected: /// When extracting data from a packet, this index will march along as things /// get extracted. If set to UINT64_MAX the end of the packet data was /// reached when decoding information. - uint64_t m_index; + uint64_t m_index = 0; }; #endif // LLDB_UTILITY_STRINGEXTRACTOR_H diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/StringExtractorGDBRemote.h b/contrib/llvm-project/lldb/include/lldb/Utility/StringExtractorGDBRemote.h index 3b6ed8030985..c67c05bdf182 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/StringExtractorGDBRemote.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/StringExtractorGDBRemote.h @@ -15,15 +15,15 @@ #include <string> -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> class StringExtractorGDBRemote : public StringExtractor { public: typedef bool (*ResponseValidatorCallback)( void *baton, const StringExtractorGDBRemote &response); - StringExtractorGDBRemote() : StringExtractor(), m_validator(nullptr) {} + StringExtractorGDBRemote() : StringExtractor() {} StringExtractorGDBRemote(llvm::StringRef str) : StringExtractor(str), m_validator(nullptr) {} @@ -162,13 +162,14 @@ public: eServerPacketType__m, eServerPacketType_notify, // '%' notification - eServerPacketType_jTraceStart, // deprecated - eServerPacketType_jTraceBufferRead, // deprecated - eServerPacketType_jTraceMetaRead, // deprecated - eServerPacketType_jTraceStop, // deprecated - eServerPacketType_jTraceConfigRead, // deprecated + eServerPacketType_jLLDBTraceSupported, + eServerPacketType_jLLDBTraceStart, + eServerPacketType_jLLDBTraceStop, + eServerPacketType_jLLDBTraceGetState, + eServerPacketType_jLLDBTraceGetBinaryData, - eServerPacketType_jLLDBTraceSupportedType, + eServerPacketType_qMemTags, // read memory tags + eServerPacketType_QMemTags, // write memory tags }; ServerPacketType GetServerPacketType() const; @@ -193,8 +194,17 @@ public: size_t GetEscapedBinaryData(std::string &str); + static constexpr lldb::pid_t AllProcesses = UINT64_MAX; + static constexpr lldb::tid_t AllThreads = UINT64_MAX; + + // Read thread-id from the packet. If the packet is valid, returns + // the pair (PID, TID), otherwise returns llvm::None. If the packet + // does not list a PID, default_pid is used. + llvm::Optional<std::pair<lldb::pid_t, lldb::tid_t>> + GetPidTid(lldb::pid_t default_pid); + protected: - ResponseValidatorCallback m_validator; + ResponseValidatorCallback m_validator = nullptr; void *m_validator_baton; }; diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/StringList.h b/contrib/llvm-project/lldb/include/lldb/Utility/StringList.h index 34930abeac3c..70f4654a6ac9 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/StringList.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/StringList.h @@ -11,7 +11,7 @@ #include "llvm/ADT/StringRef.h" -#include <stddef.h> +#include <cstddef> #include <string> #include <vector> diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Timeout.h b/contrib/llvm-project/lldb/include/lldb/Utility/Timeout.h index 80e201515577..29f8c1bbee38 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/Timeout.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/Timeout.h @@ -37,7 +37,6 @@ private: public: Timeout(llvm::NoneType none) : Base(none) {} - Timeout(const Timeout &other) = default; template <typename Ratio2, typename = typename EnableIf<int64_t, Ratio2>::type> diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Timer.h b/contrib/llvm-project/lldb/include/lldb/Utility/Timer.h index edc064b23b57..c70c18049426 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/Timer.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/Timer.h @@ -9,10 +9,15 @@ #ifndef LLDB_UTILITY_TIMER_H #define LLDB_UTILITY_TIMER_H -#include "lldb/lldb-defines.h" +#include "llvm/ADT/ScopeExit.h" #include "llvm/Support/Chrono.h" +#include "llvm/Support/Signposts.h" #include <atomic> -#include <stdint.h> +#include <cstdint> + +namespace llvm { + class SignpostEmitter; +} namespace lldb_private { class Stream; @@ -41,7 +46,11 @@ public: /// Default constructor. Timer(Category &category, const char *format, ...) - __attribute__((format(printf, 3, 4))); +#if !defined(_MSC_VER) + // MSVC appears to have trouble recognizing the this argument in the constructor. + __attribute__((format(printf, 3, 4))) +#endif + ; /// Destructor ~Timer(); @@ -72,13 +81,28 @@ private: const Timer &operator=(const Timer &) = delete; }; +llvm::SignpostEmitter &GetSignposts(); + } // namespace lldb_private +// Use a format string because LLVM_PRETTY_FUNCTION might not be a string +// literal. #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(...) \ + ::lldb_private::Timer _scoped_timer(_cat, "%s", LLVM_PRETTY_FUNCTION); \ + SIGNPOST_EMITTER_START_INTERVAL(::lldb_private::GetSignposts(), \ + &_scoped_timer, "%s", LLVM_PRETTY_FUNCTION); \ + auto _scoped_signpost = llvm::make_scope_exit([&_scoped_timer]() { \ + ::lldb_private::GetSignposts().endInterval(&_scoped_timer); \ + }) + +#define LLDB_SCOPED_TIMERF(FMT, ...) \ static ::lldb_private::Timer::Category _cat(LLVM_PRETTY_FUNCTION); \ - ::lldb_private::Timer _scoped_timer(_cat, __VA_ARGS__) + ::lldb_private::Timer _scoped_timer(_cat, FMT, __VA_ARGS__); \ + SIGNPOST_EMITTER_START_INTERVAL(::lldb_private::GetSignposts(), \ + &_scoped_timer, FMT, __VA_ARGS__); \ + auto _scoped_signpost = llvm::make_scope_exit([&_scoped_timer]() { \ + ::lldb_private::GetSignposts().endInterval(&_scoped_timer); \ + }) #endif // LLDB_UTILITY_TIMER_H diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/TraceGDBRemotePackets.h b/contrib/llvm-project/lldb/include/lldb/Utility/TraceGDBRemotePackets.h new file mode 100644 index 000000000000..1d2448b05f2a --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Utility/TraceGDBRemotePackets.h @@ -0,0 +1,154 @@ +//===-- TraceGDBRemotePackets.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_TRACEGDBREMOTEPACKETS_H +#define LLDB_UTILITY_TRACEGDBREMOTEPACKETS_H + +#include "llvm/Support/JSON.h" + +#include "lldb/lldb-defines.h" +#include "lldb/lldb-enumerations.h" + +/// See docs/lldb-gdb-remote.txt for more information. +namespace lldb_private { + +/// jLLDBTraceSupported gdb-remote packet +/// \{ +struct TraceSupportedResponse { + /// 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; + /// The description for the technology. + std::string description; +}; + +bool fromJSON(const llvm::json::Value &value, TraceSupportedResponse &info, + llvm::json::Path path); + +llvm::json::Value toJSON(const TraceSupportedResponse &packet); +/// \} + +/// jLLDBTraceStart gdb-remote packet +/// \{ +struct TraceStartRequest { + /// Tracing technology name, e.g. intel-pt, arm-coresight. + std::string type; + + /// If \a llvm::None, then this starts tracing the whole process. Otherwise, + /// only tracing for the specified threads is enabled. + llvm::Optional<std::vector<int64_t>> tids; + + /// \return + /// \b true if \a tids is \a None, i.e. whole process tracing. + bool IsProcessTracing() const; +}; + +bool fromJSON(const llvm::json::Value &value, TraceStartRequest &packet, + llvm::json::Path path); + +llvm::json::Value toJSON(const TraceStartRequest &packet); +/// \} + +/// jLLDBTraceStop gdb-remote packet +/// \{ +struct TraceStopRequest { + TraceStopRequest() = default; + + TraceStopRequest(llvm::StringRef type, const std::vector<lldb::tid_t> &tids); + + TraceStopRequest(llvm::StringRef type) : type(type){}; + + bool IsProcessTracing() const; + + /// Tracing technology name, e.g. intel-pt, arm-coresight. + std::string type; + /// If \a llvm::None, then this stops tracing the whole process. Otherwise, + /// only tracing for the specified threads is stopped. + llvm::Optional<std::vector<int64_t>> tids; +}; + +bool fromJSON(const llvm::json::Value &value, TraceStopRequest &packet, + llvm::json::Path path); + +llvm::json::Value toJSON(const TraceStopRequest &packet); +///} + +/// jLLDBTraceGetState gdb-remote packet +/// \{ +struct TraceGetStateRequest { + /// Tracing technology name, e.g. intel-pt, arm-coresight. + std::string type; +}; + +bool fromJSON(const llvm::json::Value &value, TraceGetStateRequest &packet, + llvm::json::Path path); + +llvm::json::Value toJSON(const TraceGetStateRequest &packet); + +struct TraceBinaryData { + /// Identifier of data to fetch with jLLDBTraceGetBinaryData. + std::string kind; + /// Size in bytes for this data. + int64_t size; +}; + +bool fromJSON(const llvm::json::Value &value, TraceBinaryData &packet, + llvm::json::Path path); + +llvm::json::Value toJSON(const TraceBinaryData &packet); + +struct TraceThreadState { + int64_t tid; + /// List of binary data objects for this thread. + std::vector<TraceBinaryData> binaryData; +}; + +bool fromJSON(const llvm::json::Value &value, TraceThreadState &packet, + llvm::json::Path path); + +llvm::json::Value toJSON(const TraceThreadState &packet); + +struct TraceGetStateResponse { + std::vector<TraceThreadState> tracedThreads; + std::vector<TraceBinaryData> processBinaryData; +}; + +bool fromJSON(const llvm::json::Value &value, TraceGetStateResponse &packet, + llvm::json::Path path); + +llvm::json::Value toJSON(const TraceGetStateResponse &packet); +/// \} + +/// jLLDBTraceGetBinaryData gdb-remote packet +/// \{ +struct TraceGetBinaryDataRequest { + /// Tracing technology name, e.g. intel-pt, arm-coresight. + std::string type; + /// Identifier for the data. + std::string kind; + /// Optional tid if the data is related to a thread. + llvm::Optional<int64_t> tid; + /// Offset in bytes from where to start reading the data. + int64_t offset; + /// Number of bytes to read. + int64_t size; +}; + +bool fromJSON(const llvm::json::Value &value, + lldb_private::TraceGetBinaryDataRequest &packet, + llvm::json::Path path); + +llvm::json::Value toJSON(const lldb_private::TraceGetBinaryDataRequest &packet); +/// \} + +} // namespace lldb_private + +#endif // LLDB_UTILITY_TRACEGDBREMOTEPACKETS_H diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/TraceIntelPTGDBRemotePackets.h b/contrib/llvm-project/lldb/include/lldb/Utility/TraceIntelPTGDBRemotePackets.h new file mode 100644 index 000000000000..8f4947b1f189 --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Utility/TraceIntelPTGDBRemotePackets.h @@ -0,0 +1,45 @@ +//===-- TraceIntelPTGDBRemotePackets.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_TRACEINTELPTGDBREMOTEPACKETS_H +#define LLDB_UTILITY_TRACEINTELPTGDBREMOTEPACKETS_H + +#include "lldb/Utility/TraceGDBRemotePackets.h" + +/// See docs/lldb-gdb-remote.txt for more information. +namespace lldb_private { + +/// jLLDBTraceStart gdb-remote packet +/// \{ +struct TraceIntelPTStartRequest : TraceStartRequest { + /// Size in bytes to use for each thread's trace buffer. + int64_t threadBufferSize; + + /// Whether to enable TSC + bool enableTsc; + + /// PSB packet period + llvm::Optional<int64_t> psbPeriod; + + /// Required when doing "process tracing". + /// + /// Limit in bytes on all the thread traces started by this "process trace" + /// instance. When a thread is about to be traced and the limit would be hit, + /// then a "tracing" stop event is triggered. + llvm::Optional<int64_t> processBufferSizeLimit; +}; + +bool fromJSON(const llvm::json::Value &value, TraceIntelPTStartRequest &packet, + llvm::json::Path path); + +llvm::json::Value toJSON(const TraceIntelPTStartRequest &packet); +/// \} + +} // namespace lldb_private + +#endif // LLDB_UTILITY_TRACEINTELPTGDBREMOTEPACKETS_H diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/TraceOptions.h b/contrib/llvm-project/lldb/include/lldb/Utility/TraceOptions.h deleted file mode 100644 index c9a8d12ce125..000000000000 --- a/contrib/llvm-project/lldb/include/lldb/Utility/TraceOptions.h +++ /dev/null @@ -1,81 +0,0 @@ -//===-- TraceOptions.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_TRACEOPTIONS_H -#define LLDB_UTILITY_TRACEOPTIONS_H - -#include "lldb/lldb-defines.h" -#include "lldb/lldb-enumerations.h" - -#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()) {} - - const StructuredData::DictionarySP &getTraceParams() const { - return m_trace_params; - } - - lldb::TraceType getType() const { return m_type; } - - uint64_t getTraceBufferSize() const { return m_trace_buffer_size; } - - uint64_t getMetaDataBufferSize() const { return m_meta_data_buffer_size; } - - void setTraceParams(const StructuredData::DictionarySP &dict_obj) { - m_trace_params = dict_obj; - } - - void setType(lldb::TraceType type) { m_type = type; } - - void setTraceBufferSize(uint64_t size) { m_trace_buffer_size = size; } - - void setMetaDataBufferSize(uint64_t size) { m_meta_data_buffer_size = size; } - - void setThreadID(lldb::tid_t thread_id) { m_thread_id = thread_id; } - - lldb::tid_t getThreadID() const { return m_thread_id; } - -private: - lldb::TraceType m_type; - uint64_t m_trace_buffer_size; - uint64_t m_meta_data_buffer_size; - lldb::tid_t m_thread_id; - - /// m_trace_params is meant to hold any custom parameters - /// apart from meta buffer size and trace size. - /// The interpretation of such parameters is left to - /// the lldb-server. - StructuredData::DictionarySP m_trace_params; -}; -} - -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 f2107d9b135b..1c7c04758da0 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/UUID.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/UUID.h @@ -12,8 +12,8 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Endian.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> #include <string> namespace lldb_private { diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/UserID.h b/contrib/llvm-project/lldb/include/lldb/Utility/UserID.h index 9fc6985a5a99..19e0052fc51c 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/UserID.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/UserID.h @@ -33,7 +33,7 @@ struct UserID { UserID(lldb::user_id_t uid = LLDB_INVALID_UID) : m_uid(uid) {} /// Destructor. - ~UserID() {} + ~UserID() = default; /// Clears the object state. /// diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/VMRange.h b/contrib/llvm-project/lldb/include/lldb/Utility/VMRange.h index 4b01cd86da2c..095092c1a381 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/VMRange.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/VMRange.h @@ -12,8 +12,8 @@ #include "lldb/lldb-types.h" #include "llvm/Support/raw_ostream.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> #include <vector> namespace lldb_private { @@ -26,13 +26,13 @@ public: typedef collection::iterator iterator; typedef collection::const_iterator const_iterator; - VMRange() : m_base_addr(0), m_byte_size(0) {} + VMRange() = default; VMRange(lldb::addr_t start_addr, lldb::addr_t end_addr) : m_base_addr(start_addr), m_byte_size(end_addr > start_addr ? end_addr - start_addr : 0) {} - ~VMRange() {} + ~VMRange() = default; void Clear() { m_base_addr = 0; @@ -88,8 +88,8 @@ public: const VMRange &range); protected: - lldb::addr_t m_base_addr; - lldb::addr_t m_byte_size; + lldb::addr_t m_base_addr = 0; + lldb::addr_t m_byte_size = 0; }; bool operator==(const VMRange &lhs, const VMRange &rhs); diff --git a/contrib/llvm-project/lldb/include/lldb/lldb-defines.h b/contrib/llvm-project/lldb/include/lldb/lldb-defines.h index 487cd0b01d5c..4bf01c3f86c6 100644 --- a/contrib/llvm-project/lldb/include/lldb/lldb-defines.h +++ b/contrib/llvm-project/lldb/include/lldb/lldb-defines.h @@ -82,6 +82,7 @@ #define LLDB_REGNUM_GENERIC_ARG8 \ 12 // The register that would contain pointer size or less argument 8 (if any) /// Invalid value definitions +#define LLDB_INVALID_STOP_ID 0 #define LLDB_INVALID_ADDRESS UINT64_MAX #define LLDB_INVALID_INDEX32 UINT32_MAX #define LLDB_INVALID_IVAR_OFFSET UINT32_MAX diff --git a/contrib/llvm-project/lldb/include/lldb/lldb-enumerations.h b/contrib/llvm-project/lldb/include/lldb/lldb-enumerations.h index b3f8198b1146..0d68833c12f5 100644 --- a/contrib/llvm-project/lldb/include/lldb/lldb-enumerations.h +++ b/contrib/llvm-project/lldb/include/lldb/lldb-enumerations.h @@ -160,7 +160,7 @@ enum Format { eFormatBytes, eFormatBytesWithASCII, eFormatChar, - eFormatCharPrintable, ///< Only printable characters, space if not printable + eFormatCharPrintable, ///< Only printable characters, '.' if not printable eFormatComplex, ///< Floating point complex type eFormatComplexFloat = eFormatComplex, eFormatCString, ///< NULL terminated C strings @@ -247,7 +247,11 @@ enum StopReason { eStopReasonExec, ///< Program was re-exec'ed eStopReasonPlanComplete, eStopReasonThreadExiting, - eStopReasonInstrumentation + eStopReasonInstrumentation, + eStopReasonProcessorTrace, + eStopReasonFork, + eStopReasonVFork, + eStopReasonVForkDone, }; /// Command Return Status Types. @@ -597,6 +601,7 @@ enum CommandArgumentType { eArgTypeCommand, eArgTypeColumnNum, eArgTypeModuleUUID, + eArgTypeSaveCoreStyle, eArgTypeLastArg // Always keep this entry as the last entry in this // enumeration!! }; @@ -954,6 +959,25 @@ enum ExpressionEvaluationPhase { eExpressionEvaluationComplete }; +/// Architecture-agnostic categorization of instructions for traversing the +/// control flow of a trace. +/// +/// A single instruction can match one or more of these categories. +FLAGS_ENUM(TraceInstructionControlFlowType){ + /// Any instruction. + eTraceInstructionControlFlowTypeInstruction = (1u << 1), + /// A conditional or unconditional branch/jump. + eTraceInstructionControlFlowTypeBranch = (1u << 2), + /// A conditional or unconditional branch/jump that changed + /// the control flow of the program. + eTraceInstructionControlFlowTypeTakenBranch = (1u << 3), + /// A call to a function. + eTraceInstructionControlFlowTypeCall = (1u << 4), + /// A return from a function. + eTraceInstructionControlFlowTypeReturn = (1u << 5)}; + +LLDB_MARK_AS_BITMASK_ENUM(TraceInstructionControlFlowType) + /// Watchpoint Kind. /// /// Indicates what types of events cause the watchpoint to fire. Used by Native @@ -1107,6 +1131,14 @@ enum CommandInterpreterResult { /// Stopped because quit was requested. eCommandInterpreterResultQuitRequested, }; + +// Style of core file to create when calling SaveCore. +enum SaveCoreStyle { + eSaveCoreUnspecified = 0, + eSaveCoreFull = 1, + eSaveCoreDirtyOnly = 2, +}; + } // namespace lldb #endif // LLDB_LLDB_ENUMERATIONS_H diff --git a/contrib/llvm-project/lldb/include/lldb/lldb-forward.h b/contrib/llvm-project/lldb/include/lldb/lldb-forward.h index a297a928a3f4..ad5298151e4a 100644 --- a/contrib/llvm-project/lldb/include/lldb/lldb-forward.h +++ b/contrib/llvm-project/lldb/include/lldb/lldb-forward.h @@ -174,6 +174,7 @@ class RichManglingContext; class Scalar; class ScriptInterpreter; class ScriptInterpreterLocker; +class ScriptedProcessInterface; class ScriptedSyntheticChildren; class SearchFilter; class Section; @@ -226,10 +227,10 @@ class ThreadPlanStepRange; class ThreadPlanStepThrough; class ThreadPlanTracer; class ThreadSpec; -class ThreadTrace; +class ThreadPostMortemTrace; class Trace; -class TraceSessionFileParser; -class TraceOptions; +class TraceCursor; +class TraceExporter; class Type; class TypeAndOrName; class TypeCategoryImpl; @@ -341,6 +342,7 @@ typedef std::shared_ptr<lldb_private::Listener> ListenerSP; typedef std::weak_ptr<lldb_private::Listener> ListenerWP; typedef std::shared_ptr<lldb_private::MemoryHistory> MemoryHistorySP; typedef std::unique_ptr<lldb_private::MemoryRegionInfo> MemoryRegionInfoUP; +typedef std::shared_ptr<lldb_private::MemoryRegionInfo> MemoryRegionInfoSP; typedef std::shared_ptr<lldb_private::Module> ModuleSP; typedef std::weak_ptr<lldb_private::Module> ModuleWP; typedef std::shared_ptr<lldb_private::ObjectFile> ObjectFileSP; @@ -391,6 +393,8 @@ typedef std::shared_ptr<lldb_private::ScriptSummaryFormat> ScriptSummaryFormatSP; typedef std::shared_ptr<lldb_private::ScriptInterpreter> ScriptInterpreterSP; typedef std::unique_ptr<lldb_private::ScriptInterpreter> ScriptInterpreterUP; +typedef std::unique_ptr<lldb_private::ScriptedProcessInterface> + ScriptedProcessInterfaceUP; typedef std::shared_ptr<lldb_private::Section> SectionSP; typedef std::unique_ptr<lldb_private::SectionList> SectionListUP; typedef std::weak_ptr<lldb_private::Section> SectionWP; @@ -433,10 +437,13 @@ 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::shared_ptr<lldb_private::ThreadPostMortemTrace> + ThreadPostMortemTraceSP; 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::unique_ptr<lldb_private::TraceExporter> TraceExporterUP; +typedef std::unique_ptr<lldb_private::TraceCursor> TraceCursorUP; typedef std::shared_ptr<lldb_private::Type> TypeSP; typedef std::weak_ptr<lldb_private::Type> TypeWP; typedef std::shared_ptr<lldb_private::TypeCategoryImpl> TypeCategoryImplSP; 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 df33f8af0e14..2ed083ec8ae9 100644 --- a/contrib/llvm-project/lldb/include/lldb/lldb-private-interfaces.h +++ b/contrib/llvm-project/lldb/include/lldb/lldb-private-interfaces.h @@ -54,7 +54,9 @@ typedef ObjectFile *(*ObjectFileCreateMemoryInstance)( const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t offset); typedef bool (*ObjectFileSaveCore)(const lldb::ProcessSP &process_sp, - const FileSpec &outfile, Status &error); + const FileSpec &outfile, + lldb::SaveCoreStyle &core_style, + Status &error); typedef EmulateInstruction *(*EmulateInstructionCreateInstance)( const ArchSpec &arch, InstructionType inst_type); typedef OperatingSystem *(*OperatingSystemCreateInstance)(Process *process, @@ -111,12 +113,17 @@ 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)( +/// Trace +/// \{ +typedef llvm::Expected<lldb::TraceSP> (*TraceCreateInstanceForSessionFile)( const llvm::json::Value &trace_session_file, llvm::StringRef session_file_dir, lldb_private::Debugger &debugger); -typedef lldb::CommandObjectSP (*TraceGetStartCommand)( +typedef llvm::Expected<lldb::TraceSP> (*TraceCreateInstanceForLiveProcess)( + Process &process); +typedef llvm::Expected<lldb::TraceExporterUP> (*TraceExporterCreateInstance)(); +typedef lldb::CommandObjectSP (*ThreadTraceExportCommandCreator)( CommandInterpreter &interpreter); - +/// \} } // namespace lldb_private #endif // #if defined(__cplusplus) 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 c7e652650da7..73d618d7069c 100644 --- a/contrib/llvm-project/lldb/include/lldb/lldb-private-types.h +++ b/contrib/llvm-project/lldb/include/lldb/lldb-private-types.h @@ -100,7 +100,7 @@ struct OptionEnumValueElement { using OptionEnumValues = llvm::ArrayRef<OptionEnumValueElement>; struct OptionValidator { - virtual ~OptionValidator() {} + virtual ~OptionValidator() = default; virtual bool IsValid(Platform &platform, const ExecutionContext &target) const = 0; virtual const char *ShortConditionString() const = 0; diff --git a/contrib/llvm-project/lldb/include/lldb/lldb-types.h b/contrib/llvm-project/lldb/include/lldb/lldb-types.h index c3e2f07acc45..976da35b11dd 100644 --- a/contrib/llvm-project/lldb/include/lldb/lldb-types.h +++ b/contrib/llvm-project/lldb/include/lldb/lldb-types.h @@ -12,7 +12,7 @@ #include "lldb/lldb-enumerations.h" #include "lldb/lldb-forward.h" -#include <stdint.h> +#include <cstdint> // All host systems must define: // lldb::thread_t The native thread type for spawned threads on the diff --git a/contrib/llvm-project/lldb/source/API/SBBlock.cpp b/contrib/llvm-project/lldb/source/API/SBBlock.cpp index a5fee445d5c6..5c49053dd972 100644 --- a/contrib/llvm-project/lldb/source/API/SBBlock.cpp +++ b/contrib/llvm-project/lldb/source/API/SBBlock.cpp @@ -25,9 +25,7 @@ using namespace lldb; using namespace lldb_private; -SBBlock::SBBlock() : m_opaque_ptr(nullptr) { - LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBBlock); -} +SBBlock::SBBlock() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBBlock); } SBBlock::SBBlock(lldb_private::Block *lldb_object_ptr) : m_opaque_ptr(lldb_object_ptr) {} diff --git a/contrib/llvm-project/lldb/source/API/SBBreakpoint.cpp b/contrib/llvm-project/lldb/source/API/SBBreakpoint.cpp index 96ae305ffce5..0f0a93519993 100644 --- a/contrib/llvm-project/lldb/source/API/SBBreakpoint.cpp +++ b/contrib/llvm-project/lldb/source/API/SBBreakpoint.cpp @@ -384,7 +384,7 @@ void SBBreakpoint::SetThreadIndex(uint32_t index) { if (bkpt_sp) { std::lock_guard<std::recursive_mutex> guard( bkpt_sp->GetTarget().GetAPIMutex()); - bkpt_sp->GetOptions()->GetThreadSpec()->SetIndex(index); + bkpt_sp->GetOptions().GetThreadSpec()->SetIndex(index); } } @@ -397,7 +397,7 @@ uint32_t SBBreakpoint::GetThreadIndex() const { std::lock_guard<std::recursive_mutex> guard( bkpt_sp->GetTarget().GetAPIMutex()); const ThreadSpec *thread_spec = - bkpt_sp->GetOptions()->GetThreadSpecNoCreate(); + bkpt_sp->GetOptions().GetThreadSpecNoCreate(); if (thread_spec != nullptr) thread_idx = thread_spec->GetIndex(); } @@ -414,7 +414,7 @@ void SBBreakpoint::SetThreadName(const char *thread_name) { if (bkpt_sp) { std::lock_guard<std::recursive_mutex> guard( bkpt_sp->GetTarget().GetAPIMutex()); - bkpt_sp->GetOptions()->GetThreadSpec()->SetName(thread_name); + bkpt_sp->GetOptions().GetThreadSpec()->SetName(thread_name); } } @@ -427,7 +427,7 @@ const char *SBBreakpoint::GetThreadName() const { std::lock_guard<std::recursive_mutex> guard( bkpt_sp->GetTarget().GetAPIMutex()); const ThreadSpec *thread_spec = - bkpt_sp->GetOptions()->GetThreadSpecNoCreate(); + bkpt_sp->GetOptions().GetThreadSpecNoCreate(); if (thread_spec != nullptr) name = thread_spec->GetName(); } @@ -443,7 +443,7 @@ void SBBreakpoint::SetQueueName(const char *queue_name) { if (bkpt_sp) { std::lock_guard<std::recursive_mutex> guard( bkpt_sp->GetTarget().GetAPIMutex()); - bkpt_sp->GetOptions()->GetThreadSpec()->SetQueueName(queue_name); + bkpt_sp->GetOptions().GetThreadSpec()->SetQueueName(queue_name); } } @@ -456,7 +456,7 @@ const char *SBBreakpoint::GetQueueName() const { std::lock_guard<std::recursive_mutex> guard( bkpt_sp->GetTarget().GetAPIMutex()); const ThreadSpec *thread_spec = - bkpt_sp->GetOptions()->GetThreadSpecNoCreate(); + bkpt_sp->GetOptions().GetThreadSpecNoCreate(); if (thread_spec) name = thread_spec->GetQueueName(); } @@ -506,7 +506,7 @@ void SBBreakpoint::SetCommandLineCommands(SBStringList &commands) { std::unique_ptr<BreakpointOptions::CommandData> cmd_data_up( new BreakpointOptions::CommandData(*commands, eScriptLanguageNone)); - bkpt_sp->GetOptions()->SetCommandDataCallback(cmd_data_up); + bkpt_sp->GetOptions().SetCommandDataCallback(cmd_data_up); } bool SBBreakpoint::GetCommandLineCommands(SBStringList &commands) { @@ -518,7 +518,7 @@ bool SBBreakpoint::GetCommandLineCommands(SBStringList &commands) { return false; StringList command_list; bool has_commands = - bkpt_sp->GetOptions()->GetCommandLineCallbacks(command_list); + bkpt_sp->GetOptions().GetCommandLineCallbacks(command_list); if (has_commands) commands.AppendList(command_list); return has_commands; @@ -636,7 +636,7 @@ SBError SBBreakpoint::SetScriptCallbackFunction( Status error; std::lock_guard<std::recursive_mutex> guard( bkpt_sp->GetTarget().GetAPIMutex()); - BreakpointOptions *bp_options = bkpt_sp->GetOptions(); + BreakpointOptions &bp_options = bkpt_sp->GetOptions(); error = bkpt_sp->GetTarget() .GetDebugger() .GetScriptInterpreter() @@ -661,7 +661,7 @@ SBError SBBreakpoint::SetScriptCallbackBody(const char *callback_body_text) { if (bkpt_sp) { std::lock_guard<std::recursive_mutex> guard( bkpt_sp->GetTarget().GetAPIMutex()); - BreakpointOptions *bp_options = bkpt_sp->GetOptions(); + BreakpointOptions &bp_options = bkpt_sp->GetOptions(); Status error = bkpt_sp->GetTarget() .GetDebugger() diff --git a/contrib/llvm-project/lldb/source/API/SBBreakpointLocation.cpp b/contrib/llvm-project/lldb/source/API/SBBreakpointLocation.cpp index d6bbb5faf041..175120429925 100644 --- a/contrib/llvm-project/lldb/source/API/SBBreakpointLocation.cpp +++ b/contrib/llvm-project/lldb/source/API/SBBreakpointLocation.cpp @@ -227,7 +227,7 @@ SBError SBBreakpointLocation::SetScriptCallbackFunction( Status error; std::lock_guard<std::recursive_mutex> guard( loc_sp->GetTarget().GetAPIMutex()); - BreakpointOptions *bp_options = loc_sp->GetLocationOptions(); + BreakpointOptions &bp_options = loc_sp->GetLocationOptions(); error = loc_sp->GetBreakpoint() .GetTarget() .GetDebugger() @@ -254,7 +254,7 @@ SBBreakpointLocation::SetScriptCallbackBody(const char *callback_body_text) { if (loc_sp) { std::lock_guard<std::recursive_mutex> guard( loc_sp->GetTarget().GetAPIMutex()); - BreakpointOptions *bp_options = loc_sp->GetLocationOptions(); + BreakpointOptions &bp_options = loc_sp->GetLocationOptions(); Status error = loc_sp->GetBreakpoint() .GetTarget() @@ -283,7 +283,7 @@ void SBBreakpointLocation::SetCommandLineCommands(SBStringList &commands) { std::unique_ptr<BreakpointOptions::CommandData> cmd_data_up( new BreakpointOptions::CommandData(*commands, eScriptLanguageNone)); - loc_sp->GetLocationOptions()->SetCommandDataCallback(cmd_data_up); + loc_sp->GetLocationOptions().SetCommandDataCallback(cmd_data_up); } bool SBBreakpointLocation::GetCommandLineCommands(SBStringList &commands) { @@ -295,7 +295,7 @@ bool SBBreakpointLocation::GetCommandLineCommands(SBStringList &commands) { return false; StringList command_list; bool has_commands = - loc_sp->GetLocationOptions()->GetCommandLineCallbacks(command_list); + loc_sp->GetLocationOptions().GetCommandLineCallbacks(command_list); if (has_commands) commands.AppendList(command_list); return has_commands; diff --git a/contrib/llvm-project/lldb/source/API/SBBreakpointName.cpp b/contrib/llvm-project/lldb/source/API/SBBreakpointName.cpp index 3995defcf97c..b5c700c78bbb 100644 --- a/contrib/llvm-project/lldb/source/API/SBBreakpointName.cpp +++ b/contrib/llvm-project/lldb/source/API/SBBreakpointName.cpp @@ -144,7 +144,7 @@ SBBreakpointName::SBBreakpointName(SBBreakpoint &sb_bkpt, const char *name) { } // Now copy over the breakpoint's options: - target.ConfigureBreakpointName(*bp_name, *bkpt_sp->GetOptions(), + target.ConfigureBreakpointName(*bp_name, bkpt_sp->GetOptions(), BreakpointName::Permissions()); } @@ -594,12 +594,11 @@ SBError SBBreakpointName::SetScriptCallbackFunction( BreakpointOptions &bp_options = bp_name->GetOptions(); Status error; error = m_impl_up->GetTarget() - ->GetDebugger() - .GetScriptInterpreter() - ->SetBreakpointCommandCallbackFunction(&bp_options, - callback_function_name, - extra_args.m_impl_up - ->GetObjectSP()); + ->GetDebugger() + .GetScriptInterpreter() + ->SetBreakpointCommandCallbackFunction( + bp_options, callback_function_name, + extra_args.m_impl_up->GetObjectSP()); sb_error.SetError(error); UpdateName(*bp_name); return LLDB_RECORD_RESULT(sb_error); @@ -623,7 +622,7 @@ SBBreakpointName::SetScriptCallbackBody(const char *callback_body_text) { m_impl_up->GetTarget() ->GetDebugger() .GetScriptInterpreter() - ->SetBreakpointCommandCallback(&bp_options, callback_body_text); + ->SetBreakpointCommandCallback(bp_options, callback_body_text); sb_error.SetError(error); if (!sb_error.Fail()) UpdateName(*bp_name); diff --git a/contrib/llvm-project/lldb/source/API/SBBroadcaster.cpp b/contrib/llvm-project/lldb/source/API/SBBroadcaster.cpp index d42d7ce2a536..2e6d837f102b 100644 --- a/contrib/llvm-project/lldb/source/API/SBBroadcaster.cpp +++ b/contrib/llvm-project/lldb/source/API/SBBroadcaster.cpp @@ -16,7 +16,7 @@ using namespace lldb; using namespace lldb_private; -SBBroadcaster::SBBroadcaster() : m_opaque_sp(), m_opaque_ptr(nullptr) { +SBBroadcaster::SBBroadcaster() : m_opaque_sp() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBBroadcaster); } diff --git a/contrib/llvm-project/lldb/source/API/SBCommandInterpreter.cpp b/contrib/llvm-project/lldb/source/API/SBCommandInterpreter.cpp index 31e7da8323b8..b4a69c3e972a 100644 --- a/contrib/llvm-project/lldb/source/API/SBCommandInterpreter.cpp +++ b/contrib/llvm-project/lldb/source/API/SBCommandInterpreter.cpp @@ -171,27 +171,22 @@ lldb::ReturnStatus SBCommandInterpreter::HandleCommand( lldb::SBCommandReturnObject &, bool), command_line, override_context, result, add_to_history); - - ExecutionContext ctx, *ctx_ptr; - if (override_context.get()) { - ctx = override_context.get()->Lock(true); - ctx_ptr = &ctx; - } else - ctx_ptr = nullptr; - result.Clear(); if (command_line && IsValid()) { result.ref().SetInteractive(false); - m_opaque_ptr->HandleCommand(command_line, - add_to_history ? eLazyBoolYes : eLazyBoolNo, - result.ref(), ctx_ptr); + auto do_add_to_history = add_to_history ? eLazyBoolYes : eLazyBoolNo; + if (override_context.get()) + m_opaque_ptr->HandleCommand(command_line, do_add_to_history, + override_context.get()->Lock(true), + result.ref()); + else + m_opaque_ptr->HandleCommand(command_line, do_add_to_history, + result.ref()); } else { result->AppendError( "SBCommandInterpreter or the command line is not valid"); - result->SetStatus(eReturnStatusFailed); } - return result.GetStatus(); } @@ -207,7 +202,6 @@ void SBCommandInterpreter::HandleCommandsFromFile( if (!IsValid()) { result->AppendError("SBCommandInterpreter is not valid."); - result->SetStatus(eReturnStatusFailed); return; } @@ -215,19 +209,17 @@ void SBCommandInterpreter::HandleCommandsFromFile( SBStream s; file.GetDescription(s); result->AppendErrorWithFormat("File is not valid: %s.", s.GetData()); - result->SetStatus(eReturnStatusFailed); } FileSpec tmp_spec = file.ref(); - ExecutionContext ctx, *ctx_ptr; - if (override_context.get()) { - ctx = override_context.get()->Lock(true); - ctx_ptr = &ctx; - } else - ctx_ptr = nullptr; + if (override_context.get()) + m_opaque_ptr->HandleCommandsFromFile(tmp_spec, + override_context.get()->Lock(true), + options.ref(), + result.ref()); - m_opaque_ptr->HandleCommandsFromFile(tmp_spec, ctx_ptr, options.ref(), - result.ref()); + else + m_opaque_ptr->HandleCommandsFromFile(tmp_spec, options.ref(), result.ref()); } int SBCommandInterpreter::HandleCompletion( @@ -444,7 +436,6 @@ void SBCommandInterpreter::ResolveCommand(const char *command_line, } else { result->AppendError( "SBCommandInterpreter or the command line is not valid"); - result->SetStatus(eReturnStatusFailed); } } @@ -474,7 +465,6 @@ void SBCommandInterpreter::SourceInitFileInHomeDirectory( m_opaque_ptr->SourceInitFileHome(result.ref()); } else { result->AppendError("SBCommandInterpreter is not valid"); - result->SetStatus(eReturnStatusFailed); } } @@ -492,7 +482,6 @@ void SBCommandInterpreter::SourceInitFileInHomeDirectory( m_opaque_ptr->SourceInitFileHome(result.ref(), is_repl); } else { result->AppendError("SBCommandInterpreter is not valid"); - result->SetStatus(eReturnStatusFailed); } } @@ -511,7 +500,6 @@ void SBCommandInterpreter::SourceInitFileInCurrentWorkingDirectory( m_opaque_ptr->SourceInitFileCwd(result.ref()); } else { result->AppendError("SBCommandInterpreter is not valid"); - result->SetStatus(eReturnStatusFailed); } } diff --git a/contrib/llvm-project/lldb/source/API/SBCommandInterpreterRunOptions.cpp b/contrib/llvm-project/lldb/source/API/SBCommandInterpreterRunOptions.cpp index da800e8b7804..317ec6d37127 100644 --- a/contrib/llvm-project/lldb/source/API/SBCommandInterpreterRunOptions.cpp +++ b/contrib/llvm-project/lldb/source/API/SBCommandInterpreterRunOptions.cpp @@ -131,6 +131,20 @@ void SBCommandInterpreterRunOptions::SetPrintResults(bool print_results) { m_opaque_up->SetPrintResults(print_results); } +bool SBCommandInterpreterRunOptions::GetPrintErrors() const { + LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreterRunOptions, + GetPrintErrors); + + return m_opaque_up->GetPrintErrors(); +} + +void SBCommandInterpreterRunOptions::SetPrintErrors(bool print_errors) { + LLDB_RECORD_METHOD(void, SBCommandInterpreterRunOptions, SetPrintErrors, + (bool), print_errors); + + m_opaque_up->SetPrintErrors(print_errors); +} + bool SBCommandInterpreterRunOptions::GetAddToHistory() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreterRunOptions, GetAddToHistory); @@ -270,6 +284,10 @@ template <> void RegisterMethods<SBCommandInterpreterRunOptions>(Registry &R) { LLDB_REGISTER_METHOD(void, SBCommandInterpreterRunOptions, SetPrintResults, (bool)); LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreterRunOptions, + GetPrintErrors, ()); + LLDB_REGISTER_METHOD(void, SBCommandInterpreterRunOptions, SetPrintErrors, + (bool)); + LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreterRunOptions, GetAddToHistory, ()); LLDB_REGISTER_METHOD(void, SBCommandInterpreterRunOptions, SetAddToHistory, (bool)); diff --git a/contrib/llvm-project/lldb/source/API/SBCommandReturnObject.cpp b/contrib/llvm-project/lldb/source/API/SBCommandReturnObject.cpp index fddf90b66481..00150d198fca 100644 --- a/contrib/llvm-project/lldb/source/API/SBCommandReturnObject.cpp +++ b/contrib/llvm-project/lldb/source/API/SBCommandReturnObject.cpp @@ -21,8 +21,7 @@ using namespace lldb_private; class lldb_private::SBCommandReturnObjectImpl { public: - SBCommandReturnObjectImpl() - : m_ptr(new CommandReturnObject(false)), m_owned(true) {} + SBCommandReturnObjectImpl() : m_ptr(new CommandReturnObject(false)) {} SBCommandReturnObjectImpl(CommandReturnObject &ref) : m_ptr(&ref), m_owned(false) {} SBCommandReturnObjectImpl(const SBCommandReturnObjectImpl &rhs) @@ -42,7 +41,7 @@ public: private: CommandReturnObject *m_ptr; - bool m_owned; + bool m_owned = true; }; SBCommandReturnObject::SBCommandReturnObject() @@ -364,7 +363,7 @@ void SBCommandReturnObject::SetError(const char *error_cstr) { error_cstr); if (error_cstr) - ref().SetError(error_cstr); + ref().AppendError(error_cstr); } namespace lldb_private { diff --git a/contrib/llvm-project/lldb/source/API/SBCommunication.cpp b/contrib/llvm-project/lldb/source/API/SBCommunication.cpp index d55ecd35b557..9a2ab89d5e4e 100644 --- a/contrib/llvm-project/lldb/source/API/SBCommunication.cpp +++ b/contrib/llvm-project/lldb/source/API/SBCommunication.cpp @@ -16,7 +16,7 @@ using namespace lldb; using namespace lldb_private; -SBCommunication::SBCommunication() : m_opaque(nullptr), m_opaque_owned(false) { +SBCommunication::SBCommunication() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBCommunication); } diff --git a/contrib/llvm-project/lldb/source/API/SBCompileUnit.cpp b/contrib/llvm-project/lldb/source/API/SBCompileUnit.cpp index 765957d680c9..a44d3b897110 100644 --- a/contrib/llvm-project/lldb/source/API/SBCompileUnit.cpp +++ b/contrib/llvm-project/lldb/source/API/SBCompileUnit.cpp @@ -21,7 +21,7 @@ using namespace lldb; using namespace lldb_private; -SBCompileUnit::SBCompileUnit() : m_opaque_ptr(nullptr) { +SBCompileUnit::SBCompileUnit() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBCompileUnit); } @@ -108,9 +108,10 @@ uint32_t SBCompileUnit::FindLineEntryIndex(uint32_t start_idx, uint32_t line, else file_spec = m_opaque_ptr->GetPrimaryFile(); + LineEntry line_entry; index = m_opaque_ptr->FindLineEntry( start_idx, line, inline_file_spec ? inline_file_spec->get() : nullptr, - exact, nullptr); + exact, &line_entry); } return index; diff --git a/contrib/llvm-project/lldb/source/API/SBDebugger.cpp b/contrib/llvm-project/lldb/source/API/SBDebugger.cpp index 6245b3a83565..a854c22bb214 100644 --- a/contrib/llvm-project/lldb/source/API/SBDebugger.cpp +++ b/contrib/llvm-project/lldb/source/API/SBDebugger.cpp @@ -38,6 +38,7 @@ #include "lldb/Core/Debugger.h" #include "lldb/Core/PluginManager.h" +#include "lldb/Core/Progress.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/StructuredDataImpl.h" #include "lldb/DataFormatters/DataVisualization.h" @@ -149,6 +150,41 @@ SBDebugger &SBDebugger::operator=(const SBDebugger &rhs) { return LLDB_RECORD_RESULT(*this); } +const char *SBDebugger::GetBroadcasterClass() { + LLDB_RECORD_STATIC_METHOD_NO_ARGS(const char *, SBDebugger, + GetBroadcasterClass); + + return Debugger::GetStaticBroadcasterClass().AsCString(); +} + +const char *SBDebugger::GetProgressFromEvent(const lldb::SBEvent &event, + uint64_t &progress_id, + uint64_t &completed, + uint64_t &total, + bool &is_debugger_specific) { + const Debugger::ProgressEventData *progress_data = + Debugger::ProgressEventData::GetEventDataFromEvent(event.get()); + if (progress_data == nullptr) + return nullptr; + progress_id = progress_data->GetID(); + completed = progress_data->GetCompleted(); + total = progress_data->GetTotal(); + is_debugger_specific = progress_data->IsDebuggerSpecific(); + // We must record the static method _after_ the out parameters have been + // filled in. + LLDB_RECORD_STATIC_METHOD( + const char *, SBDebugger, GetProgressFromEvent, + (const lldb::SBEvent &, uint64_t &, uint64_t &, uint64_t &, bool &), + event, progress_id, completed, total, is_debugger_specific); + return LLDB_RECORD_RESULT(progress_data->GetMessage().c_str()) +} + +SBBroadcaster SBDebugger::GetBroadcaster() { + LLDB_RECORD_METHOD_NO_ARGS(lldb::SBBroadcaster, SBDebugger, GetBroadcaster); + SBBroadcaster broadcaster(&m_opaque_sp->GetBroadcaster(), false); + return LLDB_RECORD_RESULT(broadcaster); +} + void SBDebugger::Initialize() { LLDB_RECORD_STATIC_METHOD_NO_ARGS(void, SBDebugger, Initialize); SBError ignored = SBDebugger::InitializeWithErrorHandling(); @@ -824,7 +860,7 @@ SBTarget SBDebugger::CreateTargetWithFileAndArch(const char *filename, if (error.Success()) sb_target.SetSP(target_sp); } - + LLDB_LOGF(log, "SBDebugger(%p)::CreateTargetWithFileAndArch (filename=\"%s\", " "arch=%s) => SBTarget(%p)", @@ -1298,7 +1334,6 @@ SBDebugger::GetInternalVariableValue(const char *var_name, lldb::SBStringList, SBDebugger, GetInternalVariableValue, (const char *, const char *), var_name, debugger_instance_name); - SBStringList ret_value; DebuggerSP debugger_sp(Debugger::FindDebuggerWithInstanceName( ConstString(debugger_instance_name))); Status error; @@ -1351,7 +1386,7 @@ void SBDebugger::SetPrompt(const char *prompt) { LLDB_RECORD_METHOD(void, SBDebugger, SetPrompt, (const char *), prompt); if (m_opaque_sp) - m_opaque_sp->SetPrompt(llvm::StringRef::withNullAsEmpty(prompt)); + m_opaque_sp->SetPrompt(llvm::StringRef(prompt)); } const char *SBDebugger::GetReproducerPath() const { @@ -1711,6 +1746,12 @@ template <> void RegisterMethods<SBDebugger>(Registry &R) { LLDB_REGISTER_METHOD(void, SBDebugger, Clear, ()); LLDB_REGISTER_STATIC_METHOD(lldb::SBDebugger, SBDebugger, Create, ()); LLDB_REGISTER_STATIC_METHOD(lldb::SBDebugger, SBDebugger, Create, (bool)); + LLDB_REGISTER_STATIC_METHOD( + const char *, SBDebugger, GetProgressFromEvent, + (const lldb::SBEvent &, uint64_t &, uint64_t &, uint64_t &, bool &)); + LLDB_REGISTER_STATIC_METHOD(const char *, SBDebugger, GetBroadcasterClass, + ()); + LLDB_REGISTER_METHOD(SBBroadcaster, SBDebugger, GetBroadcaster, ()); LLDB_REGISTER_STATIC_METHOD(void, SBDebugger, Destroy, (lldb::SBDebugger &)); LLDB_REGISTER_STATIC_METHOD(void, SBDebugger, MemoryPressureDetected, ()); LLDB_REGISTER_METHOD_CONST(bool, SBDebugger, IsValid, ()); diff --git a/contrib/llvm-project/lldb/source/API/SBDeclaration.cpp b/contrib/llvm-project/lldb/source/API/SBDeclaration.cpp index f1066d63c06a..1496096e46d1 100644 --- a/contrib/llvm-project/lldb/source/API/SBDeclaration.cpp +++ b/contrib/llvm-project/lldb/source/API/SBDeclaration.cpp @@ -10,11 +10,11 @@ #include "SBReproducerPrivate.h" #include "Utils.h" #include "lldb/API/SBStream.h" +#include "lldb/Core/Declaration.h" #include "lldb/Host/PosixApi.h" -#include "lldb/Symbol/Declaration.h" #include "lldb/Utility/Stream.h" -#include <limits.h> +#include <climits> using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm-project/lldb/source/API/SBError.cpp b/contrib/llvm-project/lldb/source/API/SBError.cpp index f979572778e0..89b5f26fd80c 100644 --- a/contrib/llvm-project/lldb/source/API/SBError.cpp +++ b/contrib/llvm-project/lldb/source/API/SBError.cpp @@ -12,7 +12,7 @@ #include "lldb/API/SBStream.h" #include "lldb/Utility/Status.h" -#include <stdarg.h> +#include <cstdarg> using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm-project/lldb/source/API/SBEvent.cpp b/contrib/llvm-project/lldb/source/API/SBEvent.cpp index 2776ec49c092..a0b606e3812e 100644 --- a/contrib/llvm-project/lldb/source/API/SBEvent.cpp +++ b/contrib/llvm-project/lldb/source/API/SBEvent.cpp @@ -22,9 +22,7 @@ using namespace lldb; using namespace lldb_private; -SBEvent::SBEvent() : m_event_sp(), m_opaque_ptr(nullptr) { - LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBEvent); -} +SBEvent::SBEvent() : m_event_sp() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBEvent); } SBEvent::SBEvent(uint32_t event_type, const char *cstr, uint32_t cstr_len) : m_event_sp(new Event(event_type, new EventDataBytes(cstr, cstr_len))), diff --git a/contrib/llvm-project/lldb/source/API/SBFileSpec.cpp b/contrib/llvm-project/lldb/source/API/SBFileSpec.cpp index 7bfb665df4fb..0a6b63bb460c 100644 --- a/contrib/llvm-project/lldb/source/API/SBFileSpec.cpp +++ b/contrib/llvm-project/lldb/source/API/SBFileSpec.cpp @@ -17,8 +17,8 @@ #include "llvm/ADT/SmallString.h" -#include <inttypes.h> -#include <limits.h> +#include <cinttypes> +#include <climits> using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm-project/lldb/source/API/SBFileSpecList.cpp b/contrib/llvm-project/lldb/source/API/SBFileSpecList.cpp index 7afa34363271..768ff0affd15 100644 --- a/contrib/llvm-project/lldb/source/API/SBFileSpecList.cpp +++ b/contrib/llvm-project/lldb/source/API/SBFileSpecList.cpp @@ -16,7 +16,7 @@ #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Stream.h" -#include <limits.h> +#include <climits> using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm-project/lldb/source/API/SBFunction.cpp b/contrib/llvm-project/lldb/source/API/SBFunction.cpp index 9f3cf817fc8c..2d0cb239de75 100644 --- a/contrib/llvm-project/lldb/source/API/SBFunction.cpp +++ b/contrib/llvm-project/lldb/source/API/SBFunction.cpp @@ -22,9 +22,7 @@ using namespace lldb; using namespace lldb_private; -SBFunction::SBFunction() : m_opaque_ptr(nullptr) { - LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBFunction); -} +SBFunction::SBFunction() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBFunction); } SBFunction::SBFunction(lldb_private::Function *lldb_object_ptr) : m_opaque_ptr(lldb_object_ptr) {} @@ -132,10 +130,10 @@ SBInstructionList SBFunction::GetInstructions(SBTarget target, m_opaque_ptr->GetAddressRange().GetBaseAddress().GetModule()); if (target_sp && module_sp) { lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex()); - const bool prefer_file_cache = false; + const bool force_live_memory = true; sb_instructions.SetDisassembler(Disassembler::DisassembleRange( module_sp->GetArchitecture(), nullptr, flavor, *target_sp, - m_opaque_ptr->GetAddressRange(), prefer_file_cache)); + m_opaque_ptr->GetAddressRange(), force_live_memory)); } } return LLDB_RECORD_RESULT(sb_instructions); diff --git a/contrib/llvm-project/lldb/source/API/SBLanguageRuntime.cpp b/contrib/llvm-project/lldb/source/API/SBLanguageRuntime.cpp index 33c900d20c31..e65b58270517 100644 --- a/contrib/llvm-project/lldb/source/API/SBLanguageRuntime.cpp +++ b/contrib/llvm-project/lldb/source/API/SBLanguageRuntime.cpp @@ -18,8 +18,7 @@ SBLanguageRuntime::GetLanguageTypeFromString(const char *string) { LLDB_RECORD_STATIC_METHOD(lldb::LanguageType, SBLanguageRuntime, GetLanguageTypeFromString, (const char *), string); - return Language::GetLanguageTypeFromString( - llvm::StringRef::withNullAsEmpty(string)); + return Language::GetLanguageTypeFromString(llvm::StringRef(string)); } const char * diff --git a/contrib/llvm-project/lldb/source/API/SBLaunchInfo.cpp b/contrib/llvm-project/lldb/source/API/SBLaunchInfo.cpp index cda8134c9853..70cd1c6ecf74 100644 --- a/contrib/llvm-project/lldb/source/API/SBLaunchInfo.cpp +++ b/contrib/llvm-project/lldb/source/API/SBLaunchInfo.cpp @@ -10,8 +10,12 @@ #include "SBReproducerPrivate.h" #include "lldb/API/SBEnvironment.h" +#include "lldb/API/SBError.h" #include "lldb/API/SBFileSpec.h" #include "lldb/API/SBListener.h" +#include "lldb/API/SBStream.h" +#include "lldb/API/SBStructuredData.h" +#include "lldb/Core/StructuredDataImpl.h" #include "lldb/Host/ProcessLaunchInfo.h" using namespace lldb; @@ -343,6 +347,53 @@ bool SBLaunchInfo::GetDetachOnError() const { return m_opaque_sp->GetDetachOnError(); } +const char *SBLaunchInfo::GetScriptedProcessClassName() const { + LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBLaunchInfo, + GetScriptedProcessClassName); + + // Constify this string so that it is saved in the string pool. Otherwise it + // would be freed when this function goes out of scope. + ConstString class_name(m_opaque_sp->GetScriptedProcessClassName().c_str()); + return class_name.AsCString(); +} + +void SBLaunchInfo::SetScriptedProcessClassName(const char *class_name) { + LLDB_RECORD_METHOD(void, SBLaunchInfo, SetScriptedProcessClassName, + (const char *), class_name); + + m_opaque_sp->SetScriptedProcessClassName(class_name); +} + +lldb::SBStructuredData SBLaunchInfo::GetScriptedProcessDictionary() const { + LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBStructuredData, SBLaunchInfo, + GetScriptedProcessDictionary); + + lldb_private::StructuredData::DictionarySP dict_sp = + m_opaque_sp->GetScriptedProcessDictionarySP(); + + SBStructuredData data; + data.m_impl_up->SetObjectSP(dict_sp); + + return LLDB_RECORD_RESULT(data); +} + +void SBLaunchInfo::SetScriptedProcessDictionary(lldb::SBStructuredData dict) { + LLDB_RECORD_METHOD(void, SBLaunchInfo, SetScriptedProcessDictionary, + (lldb::SBStructuredData), dict); + + SBStream stream; + SBError error = dict.GetAsJSON(stream); + + if (error.Fail()) + return; + + StructuredData::DictionarySP dict_sp; + llvm::json::OStream s(stream.ref().AsRawOstream()); + dict_sp->Serialize(s); + + m_opaque_sp->SetScriptedProcessDictionarySP(dict_sp); +} + namespace lldb_private { namespace repro { @@ -403,6 +454,14 @@ void RegisterMethods<SBLaunchInfo>(Registry &R) { ()); LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetDetachOnError, (bool)); LLDB_REGISTER_METHOD_CONST(bool, SBLaunchInfo, GetDetachOnError, ()); + LLDB_REGISTER_METHOD_CONST(const char *, SBLaunchInfo, + GetScriptedProcessClassName, ()); + LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetScriptedProcessClassName, + (const char *)); + LLDB_REGISTER_METHOD_CONST(lldb::SBStructuredData, SBLaunchInfo, + GetScriptedProcessDictionary, ()); + LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetScriptedProcessDictionary, + (lldb::SBStructuredData)); LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetEnvironment, (const lldb::SBEnvironment &, bool)); LLDB_REGISTER_METHOD(lldb::SBEnvironment, SBLaunchInfo, GetEnvironment, ()); diff --git a/contrib/llvm-project/lldb/source/API/SBLineEntry.cpp b/contrib/llvm-project/lldb/source/API/SBLineEntry.cpp index 9866acbcbec3..29ffda9b0471 100644 --- a/contrib/llvm-project/lldb/source/API/SBLineEntry.cpp +++ b/contrib/llvm-project/lldb/source/API/SBLineEntry.cpp @@ -14,7 +14,7 @@ #include "lldb/Symbol/LineEntry.h" #include "lldb/Utility/StreamString.h" -#include <limits.h> +#include <climits> using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm-project/lldb/source/API/SBListener.cpp b/contrib/llvm-project/lldb/source/API/SBListener.cpp index f3463268b3b5..6e5e15de7b3d 100644 --- a/contrib/llvm-project/lldb/source/API/SBListener.cpp +++ b/contrib/llvm-project/lldb/source/API/SBListener.cpp @@ -20,7 +20,7 @@ using namespace lldb; using namespace lldb_private; -SBListener::SBListener() : m_opaque_sp(), m_unused_ptr(nullptr) { +SBListener::SBListener() : m_opaque_sp() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBListener); } diff --git a/contrib/llvm-project/lldb/source/API/SBMemoryRegionInfo.cpp b/contrib/llvm-project/lldb/source/API/SBMemoryRegionInfo.cpp index 2a28b99c72d7..ab74d559387f 100644 --- a/contrib/llvm-project/lldb/source/API/SBMemoryRegionInfo.cpp +++ b/contrib/llvm-project/lldb/source/API/SBMemoryRegionInfo.cpp @@ -116,6 +116,42 @@ const char *SBMemoryRegionInfo::GetName() { return m_opaque_up->GetName().AsCString(); } +bool SBMemoryRegionInfo::HasDirtyMemoryPageList() { + LLDB_RECORD_METHOD_NO_ARGS(bool, SBMemoryRegionInfo, HasDirtyMemoryPageList); + + return m_opaque_up->GetDirtyPageList().hasValue(); +} + +uint32_t SBMemoryRegionInfo::GetNumDirtyPages() { + LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBMemoryRegionInfo, GetNumDirtyPages); + + uint32_t num_dirty_pages = 0; + llvm::Optional<std::vector<addr_t>> dirty_page_list = + m_opaque_up->GetDirtyPageList(); + if (dirty_page_list.hasValue()) + num_dirty_pages = dirty_page_list.getValue().size(); + + return num_dirty_pages; +} + +addr_t SBMemoryRegionInfo::GetDirtyPageAddressAtIndex(uint32_t idx) { + LLDB_RECORD_METHOD(addr_t, SBMemoryRegionInfo, GetDirtyPageAddressAtIndex, + (uint32_t), idx); + + addr_t dirty_page_addr = LLDB_INVALID_ADDRESS; + const llvm::Optional<std::vector<addr_t>> &dirty_page_list = + m_opaque_up->GetDirtyPageList(); + if (dirty_page_list.hasValue() && idx < dirty_page_list.getValue().size()) + dirty_page_addr = dirty_page_list.getValue()[idx]; + + return dirty_page_addr; +} + +int SBMemoryRegionInfo::GetPageSize() { + LLDB_RECORD_METHOD_NO_ARGS(int, SBMemoryRegionInfo, GetPageSize); + return m_opaque_up->GetPageSize(); +} + bool SBMemoryRegionInfo::GetDescription(SBStream &description) { LLDB_RECORD_METHOD(bool, SBMemoryRegionInfo, GetDescription, (lldb::SBStream &), description); diff --git a/contrib/llvm-project/lldb/source/API/SBPlatform.cpp b/contrib/llvm-project/lldb/source/API/SBPlatform.cpp index f118048156b9..496c40a0678f 100644 --- a/contrib/llvm-project/lldb/source/API/SBPlatform.cpp +++ b/contrib/llvm-project/lldb/source/API/SBPlatform.cpp @@ -32,7 +32,7 @@ using namespace lldb_private; struct PlatformConnectOptions { PlatformConnectOptions(const char *url = nullptr) : m_url(), m_rsync_options(), m_rsync_remote_path_prefix(), - m_rsync_enabled(false), m_rsync_omit_hostname_from_remote_path(false), + m_local_cache_directory() { if (url && url[0]) m_url = url; @@ -43,8 +43,8 @@ struct PlatformConnectOptions { std::string m_url; std::string m_rsync_options; std::string m_rsync_remote_path_prefix; - bool m_rsync_enabled; - bool m_rsync_omit_hostname_from_remote_path; + bool m_rsync_enabled = false; + bool m_rsync_omit_hostname_from_remote_path = false; ConstString m_local_cache_directory; }; @@ -61,7 +61,7 @@ struct PlatformShellCommand { } PlatformShellCommand(llvm::StringRef shell_command = llvm::StringRef()) - : m_shell(), m_command(), m_working_dir(), m_status(0), m_signo(0) { + : m_shell(), m_command(), m_working_dir() { if (!shell_command.empty()) m_command = shell_command.str(); } @@ -72,8 +72,8 @@ struct PlatformShellCommand { std::string m_command; std::string m_working_dir; std::string m_output; - int m_status; - int m_signo; + int m_status = 0; + int m_signo = 0; Timeout<std::ratio<1>> m_timeout = llvm::None; }; // SBPlatformConnectOptions @@ -413,8 +413,7 @@ SBError SBPlatform::ConnectRemote(SBPlatformConnectOptions &connect_options) { PlatformSP platform_sp(GetSP()); if (platform_sp && connect_options.GetURL()) { Args args; - args.AppendArgument( - llvm::StringRef::withNullAsEmpty(connect_options.GetURL())); + args.AppendArgument(connect_options.GetURL()); sb_error.ref() = platform_sp->ConnectRemote(args); } else { sb_error.SetErrorString("invalid platform"); diff --git a/contrib/llvm-project/lldb/source/API/SBProcess.cpp b/contrib/llvm-project/lldb/source/API/SBProcess.cpp index d7b7fd7cacad..47c35a23b078 100644 --- a/contrib/llvm-project/lldb/source/API/SBProcess.cpp +++ b/contrib/llvm-project/lldb/source/API/SBProcess.cpp @@ -9,7 +9,7 @@ #include "lldb/API/SBProcess.h" #include "SBReproducerPrivate.h" -#include <inttypes.h> +#include <cinttypes> #include "lldb/lldb-defines.h" #include "lldb/lldb-types.h" @@ -44,7 +44,6 @@ #include "lldb/API/SBThread.h" #include "lldb/API/SBThreadCollection.h" #include "lldb/API/SBTrace.h" -#include "lldb/API/SBTraceOptions.h" #include "lldb/API/SBUnixSignals.h" using namespace lldb; @@ -312,26 +311,6 @@ size_t SBProcess::GetAsyncProfileData(char *dst, size_t dst_len) const { return bytes_read; } -lldb::SBTrace SBProcess::StartTrace(SBTraceOptions &options, - lldb::SBError &error) { - LLDB_RECORD_METHOD(lldb::SBTrace, SBProcess, StartTrace, - (lldb::SBTraceOptions &, lldb::SBError &), options, error); - - ProcessSP process_sp(GetSP()); - error.Clear(); - SBTrace trace_instance; - trace_instance.SetSP(process_sp); - lldb::user_id_t uid = LLDB_INVALID_UID; - - if (!process_sp) { - error.SetErrorString("invalid process"); - } else { - uid = process_sp->StartTrace(*(options.m_traceoptions_sp), error.ref()); - trace_instance.SetTraceUID(uid); - } - return LLDB_RECORD_RESULT(trace_instance); -} - void SBProcess::ReportEventState(const SBEvent &event, SBFile out) const { LLDB_RECORD_METHOD_CONST(void, SBProcess, ReportEventState, (const SBEvent &, SBFile), event, out); @@ -1248,7 +1227,8 @@ lldb::SBError SBProcess::SaveCore(const char *file_name) { } FileSpec core_file(file_name); - error.ref() = PluginManager::SaveCore(process_sp, core_file); + SaveCoreStyle core_style = SaveCoreStyle::eSaveCoreFull; + error.ref() = PluginManager::SaveCore(process_sp, core_file, core_style); return LLDB_RECORD_RESULT(error); } @@ -1308,6 +1288,51 @@ lldb::SBProcessInfo SBProcess::GetProcessInfo() { return LLDB_RECORD_RESULT(sb_proc_info); } +lldb::addr_t SBProcess::AllocateMemory(size_t size, uint32_t permissions, + lldb::SBError &sb_error) { + LLDB_RECORD_METHOD(lldb::addr_t, SBProcess, AllocateMemory, + (size_t, uint32_t, lldb::SBError &), size, permissions, + sb_error); + + lldb::addr_t addr = LLDB_INVALID_ADDRESS; + ProcessSP process_sp(GetSP()); + if (process_sp) { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process_sp->GetRunLock())) { + std::lock_guard<std::recursive_mutex> guard( + process_sp->GetTarget().GetAPIMutex()); + addr = process_sp->AllocateMemory(size, permissions, sb_error.ref()); + } else { + sb_error.SetErrorString("process is running"); + } + } else { + sb_error.SetErrorString("SBProcess is invalid"); + } + return addr; +} + +lldb::SBError SBProcess::DeallocateMemory(lldb::addr_t ptr) { + LLDB_RECORD_METHOD(lldb::SBError, SBProcess, DeallocateMemory, (lldb::addr_t), + ptr); + + lldb::SBError sb_error; + ProcessSP process_sp(GetSP()); + if (process_sp) { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process_sp->GetRunLock())) { + std::lock_guard<std::recursive_mutex> guard( + process_sp->GetTarget().GetAPIMutex()); + Status error = process_sp->DeallocateMemory(ptr); + sb_error.SetError(error); + } else { + sb_error.SetErrorString("process is running"); + } + } else { + sb_error.SetErrorString("SBProcess is invalid"); + } + return sb_error; +} + namespace lldb_private { namespace repro { @@ -1338,8 +1363,6 @@ void RegisterMethods<SBProcess>(Registry &R) { (lldb::tid_t, lldb::addr_t)); LLDB_REGISTER_METHOD_CONST(lldb::SBTarget, SBProcess, GetTarget, ()); LLDB_REGISTER_METHOD(size_t, SBProcess, PutSTDIN, (const char *, size_t)); - LLDB_REGISTER_METHOD(lldb::SBTrace, SBProcess, StartTrace, - (lldb::SBTraceOptions &, lldb::SBError &)); LLDB_REGISTER_METHOD_CONST(void, SBProcess, ReportEventState, (const lldb::SBEvent &, FILE *)); LLDB_REGISTER_METHOD_CONST(void, SBProcess, ReportEventState, @@ -1439,6 +1462,10 @@ void RegisterMethods<SBProcess>(Registry &R) { LLDB_REGISTER_METHOD(lldb::SBMemoryRegionInfoList, SBProcess, GetMemoryRegions, ()); LLDB_REGISTER_METHOD(lldb::SBProcessInfo, SBProcess, GetProcessInfo, ()); + LLDB_REGISTER_METHOD(lldb::addr_t, SBProcess, AllocateMemory, + (size_t, uint32_t, lldb::SBError &)); + LLDB_REGISTER_METHOD(lldb::SBError, SBProcess, DeallocateMemory, + (lldb::addr_t)); LLDB_REGISTER_CHAR_PTR_METHOD_CONST(size_t, SBProcess, GetSTDOUT); LLDB_REGISTER_CHAR_PTR_METHOD_CONST(size_t, SBProcess, GetSTDERR); diff --git a/contrib/llvm-project/lldb/source/API/SBProcessInfo.cpp b/contrib/llvm-project/lldb/source/API/SBProcessInfo.cpp index 29a9c7b24b5a..cba3bdc179f3 100644 --- a/contrib/llvm-project/lldb/source/API/SBProcessInfo.cpp +++ b/contrib/llvm-project/lldb/source/API/SBProcessInfo.cpp @@ -179,6 +179,21 @@ lldb::pid_t SBProcessInfo::GetParentProcessID() { return proc_id; } +const char *SBProcessInfo::GetTriple() { + LLDB_RECORD_METHOD_NO_ARGS(const char *, SBProcessInfo, GetTriple); + + const char *triple = nullptr; + if (m_opaque_up) { + const auto &arch = m_opaque_up->GetArchitecture(); + if (arch.IsValid()) { + // Const-ify the string so we don't need to worry about the lifetime of + // the string + triple = ConstString(arch.GetTriple().getTriple().c_str()).GetCString(); + } + } + return triple; +} + namespace lldb_private { namespace repro { @@ -204,6 +219,7 @@ void RegisterMethods<SBProcessInfo>(Registry &R) { LLDB_REGISTER_METHOD(bool, SBProcessInfo, EffectiveUserIDIsValid, ()); LLDB_REGISTER_METHOD(bool, SBProcessInfo, EffectiveGroupIDIsValid, ()); LLDB_REGISTER_METHOD(lldb::pid_t, SBProcessInfo, GetParentProcessID, ()); + LLDB_REGISTER_METHOD(const char *, SBProcessInfo, GetTriple, ()); } } diff --git a/contrib/llvm-project/lldb/source/API/SBQueue.cpp b/contrib/llvm-project/lldb/source/API/SBQueue.cpp index 2e6571392ea1..746df9e79d61 100644 --- a/contrib/llvm-project/lldb/source/API/SBQueue.cpp +++ b/contrib/llvm-project/lldb/source/API/SBQueue.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include <inttypes.h> +#include <cinttypes> #include "SBReproducerPrivate.h" #include "lldb/API/SBQueue.h" @@ -27,9 +27,7 @@ namespace lldb_private { class QueueImpl { public: - QueueImpl() - : m_queue_wp(), m_threads(), m_thread_list_fetched(false), - m_pending_items(), m_pending_items_fetched(false) {} + QueueImpl() : m_queue_wp(), m_threads(), m_pending_items() {} QueueImpl(const lldb::QueueSP &queue_sp) : m_queue_wp(), m_threads(), m_thread_list_fetched(false), @@ -210,10 +208,11 @@ private: lldb::QueueWP m_queue_wp; std::vector<lldb::ThreadWP> m_threads; // threads currently executing this queue's items - bool - m_thread_list_fetched; // have we tried to fetch the threads list already? + bool m_thread_list_fetched = + false; // have we tried to fetch the threads list already? std::vector<lldb::QueueItemSP> m_pending_items; // items currently enqueued - bool m_pending_items_fetched; // have we tried to fetch the item list already? + bool m_pending_items_fetched = + false; // have we tried to fetch the item list already? }; } diff --git a/contrib/llvm-project/lldb/source/API/SBReproducer.cpp b/contrib/llvm-project/lldb/source/API/SBReproducer.cpp index 4d25fcc4a8f6..68e632da1bde 100644 --- a/contrib/llvm-project/lldb/source/API/SBReproducer.cpp +++ b/contrib/llvm-project/lldb/source/API/SBReproducer.cpp @@ -117,7 +117,6 @@ SBRegistry::SBRegistry() { RegisterMethods<SBThreadCollection>(R); RegisterMethods<SBThreadPlan>(R); RegisterMethods<SBTrace>(R); - RegisterMethods<SBTraceOptions>(R); RegisterMethods<SBType>(R); RegisterMethods<SBTypeCategory>(R); RegisterMethods<SBTypeEnumMember>(R); diff --git a/contrib/llvm-project/lldb/source/API/SBStream.cpp b/contrib/llvm-project/lldb/source/API/SBStream.cpp index eb81153084e8..66172d248bf3 100644 --- a/contrib/llvm-project/lldb/source/API/SBStream.cpp +++ b/contrib/llvm-project/lldb/source/API/SBStream.cpp @@ -19,7 +19,7 @@ using namespace lldb; using namespace lldb_private; -SBStream::SBStream() : m_opaque_up(new StreamString()), m_is_file(false) { +SBStream::SBStream() : m_opaque_up(new StreamString()) { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBStream); } diff --git a/contrib/llvm-project/lldb/source/API/SBStructuredData.cpp b/contrib/llvm-project/lldb/source/API/SBStructuredData.cpp index 2ae3005fd8d1..97a9eadcaf07 100644 --- a/contrib/llvm-project/lldb/source/API/SBStructuredData.cpp +++ b/contrib/llvm-project/lldb/source/API/SBStructuredData.cpp @@ -29,7 +29,7 @@ SBStructuredData::SBStructuredData() : m_impl_up(new StructuredDataImpl()) { } SBStructuredData::SBStructuredData(const lldb::SBStructuredData &rhs) - : m_impl_up(new StructuredDataImpl(*rhs.m_impl_up.get())) { + : m_impl_up(new StructuredDataImpl(*rhs.m_impl_up)) { LLDB_RECORD_CONSTRUCTOR(SBStructuredData, (const lldb::SBStructuredData &), rhs); } @@ -40,7 +40,7 @@ SBStructuredData::SBStructuredData(const lldb::EventSP &event_sp) } SBStructuredData::SBStructuredData(lldb_private::StructuredDataImpl *impl) - : m_impl_up(impl) { + : m_impl_up(impl ? impl : new StructuredDataImpl()) { LLDB_RECORD_CONSTRUCTOR(SBStructuredData, (lldb_private::StructuredDataImpl *), impl); } @@ -72,10 +72,19 @@ lldb::SBError SBStructuredData::SetFromJSON(lldb::SBStream &stream) { return LLDB_RECORD_RESULT(error); } +lldb::SBError SBStructuredData::SetFromJSON(const char *json) { + LLDB_RECORD_METHOD(lldb::SBError, SBStructuredData, SetFromJSON, + (const char *), json); + lldb::SBStream s; + s.Print(json); + return LLDB_RECORD_RESULT(SetFromJSON(s)); +} + bool SBStructuredData::IsValid() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBStructuredData, IsValid); return this->operator bool(); } + SBStructuredData::operator bool() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBStructuredData, operator bool); @@ -111,22 +120,19 @@ StructuredDataType SBStructuredData::GetType() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::StructuredDataType, SBStructuredData, GetType); - return (m_impl_up ? m_impl_up->GetType() : eStructuredDataTypeInvalid); + return m_impl_up->GetType(); } size_t SBStructuredData::GetSize() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(size_t, SBStructuredData, GetSize); - return (m_impl_up ? m_impl_up->GetSize() : 0); + return m_impl_up->GetSize(); } bool SBStructuredData::GetKeys(lldb::SBStringList &keys) const { LLDB_RECORD_METHOD_CONST(bool, SBStructuredData, GetKeys, (lldb::SBStringList &), keys); - if (!m_impl_up) - return false; - if (GetType() != eStructuredDataTypeDictionary) return false; @@ -154,9 +160,6 @@ lldb::SBStructuredData SBStructuredData::GetValueForKey(const char *key) const { LLDB_RECORD_METHOD_CONST(lldb::SBStructuredData, SBStructuredData, GetValueForKey, (const char *), key); - if (!m_impl_up) - return LLDB_RECORD_RESULT(SBStructuredData()); - SBStructuredData result; result.m_impl_up->SetObjectSP(m_impl_up->GetValueForKey(key)); return LLDB_RECORD_RESULT(result); @@ -166,9 +169,6 @@ lldb::SBStructuredData SBStructuredData::GetItemAtIndex(size_t idx) const { LLDB_RECORD_METHOD_CONST(lldb::SBStructuredData, SBStructuredData, GetItemAtIndex, (size_t), idx); - if (!m_impl_up) - return LLDB_RECORD_RESULT(SBStructuredData()); - SBStructuredData result; result.m_impl_up->SetObjectSP(m_impl_up->GetItemAtIndex(idx)); return LLDB_RECORD_RESULT(result); @@ -178,28 +178,28 @@ uint64_t SBStructuredData::GetIntegerValue(uint64_t fail_value) const { LLDB_RECORD_METHOD_CONST(uint64_t, SBStructuredData, GetIntegerValue, (uint64_t), fail_value); - return (m_impl_up ? m_impl_up->GetIntegerValue(fail_value) : fail_value); + return m_impl_up->GetIntegerValue(fail_value); } double SBStructuredData::GetFloatValue(double fail_value) const { LLDB_RECORD_METHOD_CONST(double, SBStructuredData, GetFloatValue, (double), fail_value); - return (m_impl_up ? m_impl_up->GetFloatValue(fail_value) : fail_value); + return m_impl_up->GetFloatValue(fail_value); } bool SBStructuredData::GetBooleanValue(bool fail_value) const { LLDB_RECORD_METHOD_CONST(bool, SBStructuredData, GetBooleanValue, (bool), fail_value); - return (m_impl_up ? m_impl_up->GetBooleanValue(fail_value) : fail_value); + return m_impl_up->GetBooleanValue(fail_value); } size_t SBStructuredData::GetStringValue(char *dst, size_t dst_len) const { LLDB_RECORD_CHAR_PTR_METHOD_CONST(size_t, SBStructuredData, GetStringValue, (char *, size_t), dst, "", dst_len); - return (m_impl_up ? m_impl_up->GetStringValue(dst, dst_len) : 0); + return m_impl_up->GetStringValue(dst, dst_len); } namespace lldb_private { @@ -216,6 +216,8 @@ template <> void RegisterMethods<SBStructuredData>(Registry &R) { SBStructuredData, operator=,(const lldb::SBStructuredData &)); LLDB_REGISTER_METHOD(lldb::SBError, SBStructuredData, SetFromJSON, (lldb::SBStream &)); + LLDB_REGISTER_METHOD(lldb::SBError, SBStructuredData, SetFromJSON, + (const char *)); LLDB_REGISTER_METHOD_CONST(bool, SBStructuredData, IsValid, ()); LLDB_REGISTER_METHOD_CONST(bool, SBStructuredData, operator bool, ()); LLDB_REGISTER_METHOD(void, SBStructuredData, Clear, ()); diff --git a/contrib/llvm-project/lldb/source/API/SBSymbol.cpp b/contrib/llvm-project/lldb/source/API/SBSymbol.cpp index eafc3e630bcd..d3abc13675f5 100644 --- a/contrib/llvm-project/lldb/source/API/SBSymbol.cpp +++ b/contrib/llvm-project/lldb/source/API/SBSymbol.cpp @@ -18,9 +18,7 @@ using namespace lldb; using namespace lldb_private; -SBSymbol::SBSymbol() : m_opaque_ptr(nullptr) { - LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBSymbol); -} +SBSymbol::SBSymbol() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBSymbol); } SBSymbol::SBSymbol(lldb_private::Symbol *lldb_object_ptr) : m_opaque_ptr(lldb_object_ptr) {} @@ -132,10 +130,10 @@ SBInstructionList SBSymbol::GetInstructions(SBTarget target, ModuleSP module_sp = symbol_addr.GetModule(); if (module_sp) { AddressRange symbol_range(symbol_addr, m_opaque_ptr->GetByteSize()); - const bool prefer_file_cache = false; + const bool force_live_memory = true; sb_instructions.SetDisassembler(Disassembler::DisassembleRange( module_sp->GetArchitecture(), nullptr, flavor_string, *target_sp, - symbol_range, prefer_file_cache)); + symbol_range, force_live_memory)); } } } diff --git a/contrib/llvm-project/lldb/source/API/SBTarget.cpp b/contrib/llvm-project/lldb/source/API/SBTarget.cpp index 6128c04de32b..6f0633288a2b 100644 --- a/contrib/llvm-project/lldb/source/API/SBTarget.cpp +++ b/contrib/llvm-project/lldb/source/API/SBTarget.cpp @@ -26,13 +26,13 @@ #include "lldb/API/SBStringList.h" #include "lldb/API/SBStructuredData.h" #include "lldb/API/SBSymbolContextList.h" +#include "lldb/API/SBTrace.h" #include "lldb/Breakpoint/BreakpointID.h" #include "lldb/Breakpoint/BreakpointIDList.h" #include "lldb/Breakpoint/BreakpointList.h" #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Address.h" #include "lldb/Core/AddressResolver.h" -#include "lldb/Core/AddressResolverName.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Disassembler.h" #include "lldb/Core/Module.h" @@ -706,7 +706,7 @@ size_t SBTarget::ReadMemory(const SBAddress addr, void *buf, size_t size, if (target_sp) { std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex()); bytes_read = - target_sp->ReadMemory(addr.ref(), false, buf, size, sb_error.ref()); + target_sp->ReadMemory(addr.ref(), buf, size, sb_error.ref(), true); } else { sb_error.SetErrorString("invalid target"); } @@ -2086,12 +2086,12 @@ lldb::SBInstructionList SBTarget::ReadInstructions(lldb::SBAddress base_addr, if (addr_ptr) { DataBufferHeap data( target_sp->GetArchitecture().GetMaximumOpcodeByteSize() * count, 0); - bool prefer_file_cache = false; + bool force_live_memory = true; lldb_private::Status error; lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; const size_t bytes_read = - target_sp->ReadMemory(*addr_ptr, prefer_file_cache, data.GetBytes(), - data.GetByteSize(), error, &load_addr); + target_sp->ReadMemory(*addr_ptr, data.GetBytes(), data.GetByteSize(), + error, force_live_memory, &load_addr); const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS; sb_instructions.SetDisassembler(Disassembler::DisassembleBytes( target_sp->GetArchitecture(), nullptr, flavor_string, *addr_ptr, @@ -2410,6 +2410,21 @@ lldb::addr_t SBTarget::GetStackRedZoneSize() { return 0; } +bool SBTarget::IsLoaded(const SBModule &module) const { + LLDB_RECORD_METHOD_CONST(bool, SBTarget, IsLoaded, (const lldb::SBModule &), + module); + + TargetSP target_sp(GetSP()); + if (!target_sp) + return false; + + ModuleSP module_sp(module.GetSP()); + if (!module_sp) + return false; + + return module_sp->IsLoadedInTarget(target_sp.get()); +} + lldb::SBLaunchInfo SBTarget::GetLaunchInfo() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBLaunchInfo, SBTarget, GetLaunchInfo); @@ -2440,6 +2455,34 @@ SBEnvironment SBTarget::GetEnvironment() { return LLDB_RECORD_RESULT(SBEnvironment()); } +lldb::SBTrace SBTarget::GetTrace() { + LLDB_RECORD_METHOD_NO_ARGS(lldb::SBTrace, SBTarget, GetTrace); + TargetSP target_sp(GetSP()); + + if (target_sp) + return LLDB_RECORD_RESULT(SBTrace(target_sp->GetTrace())); + + return LLDB_RECORD_RESULT(SBTrace()); +} + +lldb::SBTrace SBTarget::CreateTrace(lldb::SBError &error) { + LLDB_RECORD_METHOD(lldb::SBTrace, SBTarget, CreateTrace, (lldb::SBError &), + error); + TargetSP target_sp(GetSP()); + error.Clear(); + + if (target_sp) { + if (llvm::Expected<lldb::TraceSP> trace_sp = target_sp->CreateTrace()) { + return LLDB_RECORD_RESULT(SBTrace(*trace_sp)); + } else { + error.SetErrorString(llvm::toString(trace_sp.takeError()).c_str()); + } + } else { + error.SetErrorString("missing target"); + } + return LLDB_RECORD_RESULT(SBTrace()); +} + namespace lldb_private { namespace repro { @@ -2682,6 +2725,8 @@ void RegisterMethods<SBTarget>(Registry &R) { LLDB_REGISTER_METHOD(lldb::SBValue, SBTarget, EvaluateExpression, (const char *, const lldb::SBExpressionOptions &)); LLDB_REGISTER_METHOD(lldb::addr_t, SBTarget, GetStackRedZoneSize, ()); + LLDB_REGISTER_METHOD_CONST(bool, SBTarget, IsLoaded, + (const lldb::SBModule &)); LLDB_REGISTER_METHOD_CONST(lldb::SBLaunchInfo, SBTarget, GetLaunchInfo, ()); LLDB_REGISTER_METHOD(void, SBTarget, SetLaunchInfo, (const lldb::SBLaunchInfo &)); @@ -2699,6 +2744,8 @@ void RegisterMethods<SBTarget>(Registry &R) { GetInstructionsWithFlavor, (lldb::addr_t, const char *, const void *, size_t)); LLDB_REGISTER_METHOD(lldb::SBEnvironment, SBTarget, GetEnvironment, ()); + LLDB_REGISTER_METHOD(lldb::SBTrace, SBTarget, GetTrace, ()); + LLDB_REGISTER_METHOD(lldb::SBTrace, SBTarget, CreateTrace, (lldb::SBError &)); } } diff --git a/contrib/llvm-project/lldb/source/API/SBThread.cpp b/contrib/llvm-project/lldb/source/API/SBThread.cpp index 0d50aceee5e4..e0ab8b2e9fa8 100644 --- a/contrib/llvm-project/lldb/source/API/SBThread.cpp +++ b/contrib/llvm-project/lldb/source/API/SBThread.cpp @@ -172,6 +172,8 @@ size_t SBThread::GetStopReasonDataCount() { case eStopReasonPlanComplete: case eStopReasonThreadExiting: case eStopReasonInstrumentation: + case eStopReasonProcessorTrace: + case eStopReasonVForkDone: // There is no data for these stop reasons. return 0; @@ -194,6 +196,12 @@ size_t SBThread::GetStopReasonDataCount() { case eStopReasonException: return 1; + + case eStopReasonFork: + return 1; + + case eStopReasonVFork: + return 1; } } } @@ -223,6 +231,8 @@ uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) { case eStopReasonPlanComplete: case eStopReasonThreadExiting: case eStopReasonInstrumentation: + case eStopReasonProcessorTrace: + case eStopReasonVForkDone: // There is no data for these stop reasons. return 0; @@ -256,6 +266,12 @@ uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) { case eStopReasonException: return stop_info_sp->GetValue(); + + case eStopReasonFork: + return stop_info_sp->GetValue(); + + case eStopReasonVFork: + return stop_info_sp->GetValue(); } } } @@ -841,12 +857,13 @@ SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame, std::vector<addr_t> step_over_until_addrs; const bool abort_other_plans = false; const bool stop_other_threads = false; - const bool check_inlines = true; - const bool exact = false; + // TODO: Handle SourceLocationSpec column information + SourceLocationSpec location_spec( + step_file_spec, line, /*column=*/llvm::None, /*check_inlines=*/true, + /*exact_match=*/false); SymbolContextList sc_list; - frame_sc.comp_unit->ResolveSymbolContext(step_file_spec, line, - check_inlines, exact, + frame_sc.comp_unit->ResolveSymbolContext(location_spec, eSymbolContextLineEntry, sc_list); const uint32_t num_matches = sc_list.GetSize(); if (num_matches > 0) { diff --git a/contrib/llvm-project/lldb/source/API/SBTrace.cpp b/contrib/llvm-project/lldb/source/API/SBTrace.cpp index 3fdabaa29ac2..079c33a562c0 100644 --- a/contrib/llvm-project/lldb/source/API/SBTrace.cpp +++ b/contrib/llvm-project/lldb/source/API/SBTrace.cpp @@ -9,123 +9,88 @@ #include "SBReproducerPrivate.h" #include "lldb/Target/Process.h" +#include "lldb/API/SBStructuredData.h" +#include "lldb/API/SBThread.h" #include "lldb/API/SBTrace.h" -#include "lldb/API/SBTraceOptions.h" + +#include "lldb/Core/StructuredDataImpl.h" #include <memory> using namespace lldb; using namespace lldb_private; -class TraceImpl { -public: - lldb::user_id_t uid; -}; - -lldb::ProcessSP SBTrace::GetSP() const { return m_opaque_wp.lock(); } - -size_t SBTrace::GetTraceData(SBError &error, void *buf, size_t size, - size_t offset, lldb::tid_t thread_id) { - LLDB_RECORD_DUMMY(size_t, SBTrace, GetTraceData, - (lldb::SBError &, void *, size_t, size_t, lldb::tid_t), - error, buf, size, offset, thread_id); +SBTrace::SBTrace() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBTrace); } - ProcessSP process_sp(GetSP()); - llvm::MutableArrayRef<uint8_t> buffer(static_cast<uint8_t *>(buf), size); - error.Clear(); - - if (!process_sp) { - error.SetErrorString("invalid process"); - } else { - error.SetError( - process_sp->GetData(GetTraceUID(), thread_id, buffer, offset)); - } - return buffer.size(); +SBTrace::SBTrace(const lldb::TraceSP &trace_sp) : m_opaque_sp(trace_sp) { + LLDB_RECORD_CONSTRUCTOR(SBTrace, (const lldb::TraceSP &), trace_sp); } -size_t SBTrace::GetMetaData(SBError &error, void *buf, size_t size, - size_t offset, lldb::tid_t thread_id) { - LLDB_RECORD_DUMMY(size_t, SBTrace, GetMetaData, - (lldb::SBError &, void *, size_t, size_t, lldb::tid_t), - error, buf, size, offset, thread_id); - - ProcessSP process_sp(GetSP()); - llvm::MutableArrayRef<uint8_t> buffer(static_cast<uint8_t *>(buf), size); - error.Clear(); - - if (!process_sp) { - error.SetErrorString("invalid process"); - } else { - error.SetError( - process_sp->GetMetaData(GetTraceUID(), thread_id, buffer, offset)); - } - return buffer.size(); +const char *SBTrace::GetStartConfigurationHelp() { + LLDB_RECORD_METHOD_NO_ARGS(const char *, SBTrace, GetStartConfigurationHelp); + return LLDB_RECORD_RESULT( + m_opaque_sp ? m_opaque_sp->GetStartConfigurationHelp() : nullptr); } -void SBTrace::StopTrace(SBError &error, lldb::tid_t thread_id) { - LLDB_RECORD_METHOD(void, SBTrace, StopTrace, (lldb::SBError &, lldb::tid_t), - error, thread_id); - - ProcessSP process_sp(GetSP()); - error.Clear(); - - if (!process_sp) { - error.SetErrorString("invalid process"); - return; - } - error.SetError(process_sp->StopTrace(GetTraceUID(), thread_id)); +SBError SBTrace::Start(const SBStructuredData &configuration) { + LLDB_RECORD_METHOD(SBError, SBTrace, Start, (const SBStructuredData &), + configuration); + SBError error; + if (!m_opaque_sp) + error.SetErrorString("error: invalid trace"); + else if (llvm::Error err = + m_opaque_sp->Start(configuration.m_impl_up->GetObjectSP())) + error.SetErrorString(llvm::toString(std::move(err)).c_str()); + return LLDB_RECORD_RESULT(error); } -void SBTrace::GetTraceConfig(SBTraceOptions &options, SBError &error) { - LLDB_RECORD_METHOD(void, SBTrace, GetTraceConfig, - (lldb::SBTraceOptions &, lldb::SBError &), options, error); - - ProcessSP process_sp(GetSP()); - error.Clear(); - - if (!process_sp) { - error.SetErrorString("invalid process"); - } else { - error.SetError(process_sp->GetTraceConfig(GetTraceUID(), - *(options.m_traceoptions_sp))); +SBError SBTrace::Start(const SBThread &thread, + const SBStructuredData &configuration) { + LLDB_RECORD_METHOD(SBError, SBTrace, Start, + (const SBThread &, const SBStructuredData &), thread, + configuration); + + SBError error; + if (!m_opaque_sp) + error.SetErrorString("error: invalid trace"); + else { + if (llvm::Error err = + m_opaque_sp->Start(std::vector<lldb::tid_t>{thread.GetThreadID()}, + configuration.m_impl_up->GetObjectSP())) + error.SetErrorString(llvm::toString(std::move(err)).c_str()); } -} - -lldb::user_id_t SBTrace::GetTraceUID() { - LLDB_RECORD_METHOD_NO_ARGS(lldb::user_id_t, SBTrace, GetTraceUID); - if (m_trace_impl_sp) - return m_trace_impl_sp->uid; - return LLDB_INVALID_UID; + return LLDB_RECORD_RESULT(error); } -void SBTrace::SetTraceUID(lldb::user_id_t uid) { - if (m_trace_impl_sp) - m_trace_impl_sp->uid = uid; +SBError SBTrace::Stop() { + LLDB_RECORD_METHOD_NO_ARGS(SBError, SBTrace, Stop); + SBError error; + if (!m_opaque_sp) + error.SetErrorString("error: invalid trace"); + else if (llvm::Error err = m_opaque_sp->Stop()) + error.SetErrorString(llvm::toString(std::move(err)).c_str()); + return LLDB_RECORD_RESULT(error); } -SBTrace::SBTrace() { - LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBTrace); - - m_trace_impl_sp = std::make_shared<TraceImpl>(); - if (m_trace_impl_sp) - m_trace_impl_sp->uid = LLDB_INVALID_UID; +SBError SBTrace::Stop(const SBThread &thread) { + LLDB_RECORD_METHOD(SBError, SBTrace, Stop, (const SBThread &), thread); + SBError error; + if (!m_opaque_sp) + error.SetErrorString("error: invalid trace"); + else if (llvm::Error err = m_opaque_sp->Stop({thread.GetThreadID()})) + error.SetErrorString(llvm::toString(std::move(err)).c_str()); + return LLDB_RECORD_RESULT(error); } -void SBTrace::SetSP(const ProcessSP &process_sp) { m_opaque_wp = process_sp; } - bool SBTrace::IsValid() { LLDB_RECORD_METHOD_NO_ARGS(bool, SBTrace, IsValid); return this->operator bool(); } + SBTrace::operator bool() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBTrace, operator bool); - - if (!m_trace_impl_sp) - return false; - if (!GetSP()) - return false; - return true; + return (bool)m_opaque_sp; } namespace lldb_private { @@ -133,13 +98,15 @@ namespace repro { template <> void RegisterMethods<SBTrace>(Registry &R) { - LLDB_REGISTER_METHOD(void, SBTrace, StopTrace, - (lldb::SBError &, lldb::tid_t)); - LLDB_REGISTER_METHOD(void, SBTrace, GetTraceConfig, - (lldb::SBTraceOptions &, lldb::SBError &)); - LLDB_REGISTER_METHOD(lldb::user_id_t, SBTrace, GetTraceUID, ()); LLDB_REGISTER_CONSTRUCTOR(SBTrace, ()); + LLDB_REGISTER_CONSTRUCTOR(SBTrace, (const lldb::TraceSP &)); + LLDB_REGISTER_METHOD(SBError, SBTrace, Start, (const SBStructuredData &)); + LLDB_REGISTER_METHOD(SBError, SBTrace, Start, + (const SBThread &, const SBStructuredData &)); + LLDB_REGISTER_METHOD(SBError, SBTrace, Stop, (const SBThread &)); + LLDB_REGISTER_METHOD(SBError, SBTrace, Stop, ()); LLDB_REGISTER_METHOD(bool, SBTrace, IsValid, ()); + LLDB_REGISTER_METHOD(const char *, SBTrace, GetStartConfigurationHelp, ()); LLDB_REGISTER_METHOD_CONST(bool, SBTrace, operator bool, ()); } diff --git a/contrib/llvm-project/lldb/source/API/SBTraceOptions.cpp b/contrib/llvm-project/lldb/source/API/SBTraceOptions.cpp deleted file mode 100644 index f1f5a63edf06..000000000000 --- a/contrib/llvm-project/lldb/source/API/SBTraceOptions.cpp +++ /dev/null @@ -1,159 +0,0 @@ -//===-- SBTraceOptions.cpp ------------------------------------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#include "lldb/API/SBTraceOptions.h" -#include "SBReproducerPrivate.h" -#include "lldb/API/SBError.h" -#include "lldb/API/SBStructuredData.h" -#include "lldb/Core/StructuredDataImpl.h" -#include "lldb/Utility/Log.h" -#include "lldb/Utility/TraceOptions.h" - -#include <memory> - -using namespace lldb; -using namespace lldb_private; - -SBTraceOptions::SBTraceOptions() { - LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBTraceOptions); - - m_traceoptions_sp = std::make_shared<TraceOptions>(); -} - -lldb::TraceType SBTraceOptions::getType() const { - LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::TraceType, SBTraceOptions, getType); - - if (m_traceoptions_sp) - return m_traceoptions_sp->getType(); - return lldb::TraceType::eTraceTypeNone; -} - -uint64_t SBTraceOptions::getTraceBufferSize() const { - LLDB_RECORD_METHOD_CONST_NO_ARGS(uint64_t, SBTraceOptions, - getTraceBufferSize); - - if (m_traceoptions_sp) - return m_traceoptions_sp->getTraceBufferSize(); - return 0; -} - -lldb::SBStructuredData SBTraceOptions::getTraceParams(lldb::SBError &error) { - LLDB_RECORD_METHOD(lldb::SBStructuredData, SBTraceOptions, getTraceParams, - (lldb::SBError &), error); - - error.Clear(); - const lldb_private::StructuredData::DictionarySP dict_obj = - m_traceoptions_sp->getTraceParams(); - lldb::SBStructuredData structData; - if (dict_obj && structData.m_impl_up) - structData.m_impl_up->SetObjectSP(dict_obj->shared_from_this()); - else - error.SetErrorString("Empty trace params"); - return LLDB_RECORD_RESULT(structData); -} - -uint64_t SBTraceOptions::getMetaDataBufferSize() const { - LLDB_RECORD_METHOD_CONST_NO_ARGS(uint64_t, SBTraceOptions, - getMetaDataBufferSize); - - if (m_traceoptions_sp) - return m_traceoptions_sp->getTraceBufferSize(); - return 0; -} - -void SBTraceOptions::setTraceParams(lldb::SBStructuredData ¶ms) { - LLDB_RECORD_METHOD(void, SBTraceOptions, setTraceParams, - (lldb::SBStructuredData &), params); - - if (m_traceoptions_sp && params.m_impl_up) { - StructuredData::ObjectSP obj_sp = params.m_impl_up->GetObjectSP(); - if (obj_sp && obj_sp->GetAsDictionary() != nullptr) - m_traceoptions_sp->setTraceParams( - std::static_pointer_cast<StructuredData::Dictionary>(obj_sp)); - } - return; -} - -void SBTraceOptions::setType(lldb::TraceType type) { - LLDB_RECORD_METHOD(void, SBTraceOptions, setType, (lldb::TraceType), type); - - if (m_traceoptions_sp) - m_traceoptions_sp->setType(type); -} - -void SBTraceOptions::setTraceBufferSize(uint64_t size) { - LLDB_RECORD_METHOD(void, SBTraceOptions, setTraceBufferSize, (uint64_t), - size); - - if (m_traceoptions_sp) - m_traceoptions_sp->setTraceBufferSize(size); -} - -void SBTraceOptions::setMetaDataBufferSize(uint64_t size) { - LLDB_RECORD_METHOD(void, SBTraceOptions, setMetaDataBufferSize, (uint64_t), - size); - - if (m_traceoptions_sp) - m_traceoptions_sp->setMetaDataBufferSize(size); -} - -bool SBTraceOptions::IsValid() { - LLDB_RECORD_METHOD_NO_ARGS(bool, SBTraceOptions, IsValid); - return this->operator bool(); -} -SBTraceOptions::operator bool() const { - LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBTraceOptions, operator bool); - - if (m_traceoptions_sp) - return true; - return false; -} - -void SBTraceOptions::setThreadID(lldb::tid_t thread_id) { - LLDB_RECORD_METHOD(void, SBTraceOptions, setThreadID, (lldb::tid_t), - thread_id); - - if (m_traceoptions_sp) - m_traceoptions_sp->setThreadID(thread_id); -} - -lldb::tid_t SBTraceOptions::getThreadID() { - LLDB_RECORD_METHOD_NO_ARGS(lldb::tid_t, SBTraceOptions, getThreadID); - - if (m_traceoptions_sp) - return m_traceoptions_sp->getThreadID(); - return LLDB_INVALID_THREAD_ID; -} - -namespace lldb_private { -namespace repro { - -template <> -void RegisterMethods<SBTraceOptions>(Registry &R) { - LLDB_REGISTER_CONSTRUCTOR(SBTraceOptions, ()); - LLDB_REGISTER_METHOD_CONST(lldb::TraceType, SBTraceOptions, getType, ()); - LLDB_REGISTER_METHOD_CONST(uint64_t, SBTraceOptions, getTraceBufferSize, - ()); - LLDB_REGISTER_METHOD(lldb::SBStructuredData, SBTraceOptions, getTraceParams, - (lldb::SBError &)); - LLDB_REGISTER_METHOD_CONST(uint64_t, SBTraceOptions, getMetaDataBufferSize, - ()); - LLDB_REGISTER_METHOD(void, SBTraceOptions, setTraceParams, - (lldb::SBStructuredData &)); - LLDB_REGISTER_METHOD(void, SBTraceOptions, setType, (lldb::TraceType)); - LLDB_REGISTER_METHOD(void, SBTraceOptions, setTraceBufferSize, (uint64_t)); - LLDB_REGISTER_METHOD(void, SBTraceOptions, setMetaDataBufferSize, - (uint64_t)); - LLDB_REGISTER_METHOD(bool, SBTraceOptions, IsValid, ()); - LLDB_REGISTER_METHOD_CONST(bool, SBTraceOptions, operator bool, ()); - LLDB_REGISTER_METHOD(void, SBTraceOptions, setThreadID, (lldb::tid_t)); - LLDB_REGISTER_METHOD(lldb::tid_t, SBTraceOptions, getThreadID, ()); -} - -} -} diff --git a/contrib/llvm-project/lldb/source/API/SBTypeCategory.cpp b/contrib/llvm-project/lldb/source/API/SBTypeCategory.cpp index 9ce1a57ec4f7..e7432959b260 100644 --- a/contrib/llvm-project/lldb/source/API/SBTypeCategory.cpp +++ b/contrib/llvm-project/lldb/source/API/SBTypeCategory.cpp @@ -363,9 +363,7 @@ bool SBTypeCategory::AddTypeFormat(SBTypeNameSpecifier type_name, if (type_name.IsRegex()) m_opaque_sp->GetRegexTypeFormatsContainer()->Add( - RegularExpression( - llvm::StringRef::withNullAsEmpty(type_name.GetName())), - format.GetSP()); + RegularExpression(type_name.GetName()), format.GetSP()); else m_opaque_sp->GetTypeFormatsContainer()->Add( ConstString(type_name.GetName()), format.GetSP()); @@ -442,9 +440,7 @@ bool SBTypeCategory::AddTypeSummary(SBTypeNameSpecifier type_name, if (type_name.IsRegex()) m_opaque_sp->GetRegexTypeSummariesContainer()->Add( - RegularExpression( - llvm::StringRef::withNullAsEmpty(type_name.GetName())), - summary.GetSP()); + RegularExpression(type_name.GetName()), summary.GetSP()); else m_opaque_sp->GetTypeSummariesContainer()->Add( ConstString(type_name.GetName()), summary.GetSP()); @@ -487,9 +483,7 @@ bool SBTypeCategory::AddTypeFilter(SBTypeNameSpecifier type_name, if (type_name.IsRegex()) m_opaque_sp->GetRegexTypeFiltersContainer()->Add( - RegularExpression( - llvm::StringRef::withNullAsEmpty(type_name.GetName())), - filter.GetSP()); + RegularExpression(type_name.GetName()), filter.GetSP()); else m_opaque_sp->GetTypeFiltersContainer()->Add( ConstString(type_name.GetName()), filter.GetSP()); @@ -566,9 +560,7 @@ bool SBTypeCategory::AddTypeSynthetic(SBTypeNameSpecifier type_name, if (type_name.IsRegex()) m_opaque_sp->GetRegexTypeSyntheticsContainer()->Add( - RegularExpression( - llvm::StringRef::withNullAsEmpty(type_name.GetName())), - synth.GetSP()); + RegularExpression(type_name.GetName()), synth.GetSP()); else m_opaque_sp->GetTypeSyntheticsContainer()->Add( ConstString(type_name.GetName()), synth.GetSP()); diff --git a/contrib/llvm-project/lldb/source/API/SBValue.cpp b/contrib/llvm-project/lldb/source/API/SBValue.cpp index 0a95cf41263d..9faee102c5e3 100644 --- a/contrib/llvm-project/lldb/source/API/SBValue.cpp +++ b/contrib/llvm-project/lldb/source/API/SBValue.cpp @@ -17,6 +17,7 @@ #include "lldb/API/SBTypeSynthetic.h" #include "lldb/Breakpoint/Watchpoint.h" +#include "lldb/Core/Declaration.h" #include "lldb/Core/Module.h" #include "lldb/Core/Section.h" #include "lldb/Core/StreamFile.h" @@ -25,7 +26,6 @@ #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/DataFormatters/DataVisualization.h" #include "lldb/Symbol/Block.h" -#include "lldb/Symbol/Declaration.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/Type.h" #include "lldb/Symbol/Variable.h" diff --git a/contrib/llvm-project/lldb/source/API/SBVariablesOptions.cpp b/contrib/llvm-project/lldb/source/API/SBVariablesOptions.cpp index 4ef16364e628..1af582a0c3d7 100644 --- a/contrib/llvm-project/lldb/source/API/SBVariablesOptions.cpp +++ b/contrib/llvm-project/lldb/source/API/SBVariablesOptions.cpp @@ -21,9 +21,7 @@ public: VariablesOptionsImpl() : m_include_arguments(false), m_include_locals(false), m_include_statics(false), m_in_scope_only(false), - m_include_runtime_support_values(false), - m_include_recognized_arguments(eLazyBoolCalculate), - m_use_dynamic(lldb::eNoDynamicValues) {} + m_include_runtime_support_values(false) {} VariablesOptionsImpl(const VariablesOptionsImpl &) = default; @@ -75,8 +73,9 @@ private: bool m_include_statics : 1; bool m_in_scope_only : 1; bool m_include_runtime_support_values : 1; - LazyBool m_include_recognized_arguments; // can be overridden with a setting - lldb::DynamicValueType m_use_dynamic; + LazyBool m_include_recognized_arguments = + eLazyBoolCalculate; // can be overridden with a setting + lldb::DynamicValueType m_use_dynamic = lldb::eNoDynamicValues; }; SBVariablesOptions::SBVariablesOptions() diff --git a/contrib/llvm-project/lldb/source/API/SystemInitializerFull.cpp b/contrib/llvm-project/lldb/source/API/SystemInitializerFull.cpp index 0530f94580b3..cc6cb6925bd0 100644 --- a/contrib/llvm-project/lldb/source/API/SystemInitializerFull.cpp +++ b/contrib/llvm-project/lldb/source/API/SystemInitializerFull.cpp @@ -17,6 +17,7 @@ #include "lldb/Target/ProcessTrace.h" #include "lldb/Utility/Reproducer.h" #include "lldb/Utility/Timer.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/TargetSelect.h" #pragma clang diagnostic push @@ -29,9 +30,22 @@ #define LLDB_PLUGIN(p) LLDB_PLUGIN_DECLARE(p) #include "Plugins/Plugins.def" +#if LLDB_ENABLE_PYTHON +#include "Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h" + +constexpr lldb_private::HostInfo::SharedLibraryDirectoryHelper + *g_shlib_dir_helper = + lldb_private::ScriptInterpreterPython::SharedLibraryDirectoryHelper; + +#else +constexpr lldb_private::HostInfo::SharedLibraryDirectoryHelper + *g_shlib_dir_helper = 0; +#endif + using namespace lldb_private; -SystemInitializerFull::SystemInitializerFull() = default; +SystemInitializerFull::SystemInitializerFull() + : SystemInitializerCommon(g_shlib_dir_helper) {} SystemInitializerFull::~SystemInitializerFull() = default; llvm::Error SystemInitializerFull::Initialize() { @@ -51,6 +65,13 @@ llvm::Error SystemInitializerFull::Initialize() { llvm::InitializeAllAsmPrinters(); llvm::InitializeAllTargetMCs(); llvm::InitializeAllDisassemblers(); + // Initialize the command line parser in LLVM. This usually isn't necessary + // as we aren't dealing with command line options here, but otherwise some + // other code in Clang/LLVM might be tempted to call this function from a + // different thread later on which won't work (as the function isn't + // thread-safe). + const char *arg0 = "lldb"; + llvm::cl::ParseCommandLineOptions(1, &arg0); #define LLDB_PLUGIN(p) LLDB_PLUGIN_INITIALIZE(p); #include "Plugins/Plugins.def" diff --git a/contrib/llvm-project/lldb/source/Breakpoint/Breakpoint.cpp b/contrib/llvm-project/lldb/source/Breakpoint/Breakpoint.cpp index d7bca308ca99..8d5d5a31337c 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/Breakpoint.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/Breakpoint.cpp @@ -49,17 +49,16 @@ Breakpoint::Breakpoint(Target &target, SearchFilterSP &filter_sp, BreakpointResolverSP &resolver_sp, bool hardware, bool resolve_indirect_symbols) : m_being_created(true), m_hardware(hardware), m_target(target), - m_filter_sp(filter_sp), m_resolver_sp(resolver_sp), - m_options_up(new BreakpointOptions(true)), m_locations(*this), - m_resolve_indirect_symbols(resolve_indirect_symbols), m_hit_counter() { + m_filter_sp(filter_sp), m_resolver_sp(resolver_sp), m_options(true), + m_locations(*this), m_resolve_indirect_symbols(resolve_indirect_symbols), + m_hit_counter() { m_being_created = false; } Breakpoint::Breakpoint(Target &new_target, const Breakpoint &source_bp) : m_being_created(true), m_hardware(source_bp.m_hardware), m_target(new_target), m_name_list(source_bp.m_name_list), - m_options_up(new BreakpointOptions(*source_bp.m_options_up)), - m_locations(*this), + m_options(source_bp.m_options), m_locations(*this), m_resolve_indirect_symbols(source_bp.m_resolve_indirect_symbols), m_hit_counter() {} @@ -116,7 +115,7 @@ StructuredData::ObjectSP Breakpoint::SerializeToStructuredData() { filter_dict_sp); StructuredData::ObjectSP options_dict_sp( - m_options_up->SerializeToStructuredData()); + m_options.SerializeToStructuredData()); if (!options_dict_sp) return StructuredData::ObjectSP(); @@ -201,7 +200,7 @@ lldb::BreakpointSP Breakpoint::CreateFromStructuredData( hardware, true); if (result_sp && options_up) { - result_sp->m_options_up = std::move(options_up); + result_sp->m_options = *options_up; } StructuredData::Array *names_array; @@ -293,10 +292,10 @@ void Breakpoint::RemoveInvalidLocations(const ArchSpec &arch) { // individual settings. void Breakpoint::SetEnabled(bool enable) { - if (enable == m_options_up->IsEnabled()) + if (enable == m_options.IsEnabled()) return; - m_options_up->SetEnabled(enable); + m_options.SetEnabled(enable); if (enable) m_locations.ResolveAllBreakpointSites(); else @@ -306,123 +305,107 @@ void Breakpoint::SetEnabled(bool enable) { : eBreakpointEventTypeDisabled); } -bool Breakpoint::IsEnabled() { return m_options_up->IsEnabled(); } +bool Breakpoint::IsEnabled() { return m_options.IsEnabled(); } void Breakpoint::SetIgnoreCount(uint32_t n) { - if (m_options_up->GetIgnoreCount() == n) + if (m_options.GetIgnoreCount() == n) return; - m_options_up->SetIgnoreCount(n); + m_options.SetIgnoreCount(n); SendBreakpointChangedEvent(eBreakpointEventTypeIgnoreChanged); } void Breakpoint::DecrementIgnoreCount() { - uint32_t ignore = m_options_up->GetIgnoreCount(); + uint32_t ignore = m_options.GetIgnoreCount(); if (ignore != 0) - m_options_up->SetIgnoreCount(ignore - 1); + m_options.SetIgnoreCount(ignore - 1); } uint32_t Breakpoint::GetIgnoreCount() const { - return m_options_up->GetIgnoreCount(); -} - -bool Breakpoint::IgnoreCountShouldStop() { - uint32_t ignore = GetIgnoreCount(); - if (ignore != 0) { - // When we get here we know the location that caused the stop doesn't have - // an ignore count, since by contract we call it first... So we don't have - // to find & decrement it, we only have to decrement our own ignore count. - DecrementIgnoreCount(); - return false; - } else - return true; + return m_options.GetIgnoreCount(); } uint32_t Breakpoint::GetHitCount() const { return m_hit_counter.GetValue(); } -bool Breakpoint::IsOneShot() const { return m_options_up->IsOneShot(); } +bool Breakpoint::IsOneShot() const { return m_options.IsOneShot(); } -void Breakpoint::SetOneShot(bool one_shot) { - m_options_up->SetOneShot(one_shot); -} +void Breakpoint::SetOneShot(bool one_shot) { m_options.SetOneShot(one_shot); } -bool Breakpoint::IsAutoContinue() const { - return m_options_up->IsAutoContinue(); -} +bool Breakpoint::IsAutoContinue() const { return m_options.IsAutoContinue(); } void Breakpoint::SetAutoContinue(bool auto_continue) { - m_options_up->SetAutoContinue(auto_continue); + m_options.SetAutoContinue(auto_continue); } void Breakpoint::SetThreadID(lldb::tid_t thread_id) { - if (m_options_up->GetThreadSpec()->GetTID() == thread_id) + if (m_options.GetThreadSpec()->GetTID() == thread_id) return; - m_options_up->GetThreadSpec()->SetTID(thread_id); + m_options.GetThreadSpec()->SetTID(thread_id); SendBreakpointChangedEvent(eBreakpointEventTypeThreadChanged); } lldb::tid_t Breakpoint::GetThreadID() const { - if (m_options_up->GetThreadSpecNoCreate() == nullptr) + if (m_options.GetThreadSpecNoCreate() == nullptr) return LLDB_INVALID_THREAD_ID; else - return m_options_up->GetThreadSpecNoCreate()->GetTID(); + return m_options.GetThreadSpecNoCreate()->GetTID(); } void Breakpoint::SetThreadIndex(uint32_t index) { - if (m_options_up->GetThreadSpec()->GetIndex() == index) + if (m_options.GetThreadSpec()->GetIndex() == index) return; - m_options_up->GetThreadSpec()->SetIndex(index); + m_options.GetThreadSpec()->SetIndex(index); SendBreakpointChangedEvent(eBreakpointEventTypeThreadChanged); } uint32_t Breakpoint::GetThreadIndex() const { - if (m_options_up->GetThreadSpecNoCreate() == nullptr) + if (m_options.GetThreadSpecNoCreate() == nullptr) return 0; else - return m_options_up->GetThreadSpecNoCreate()->GetIndex(); + return m_options.GetThreadSpecNoCreate()->GetIndex(); } void Breakpoint::SetThreadName(const char *thread_name) { - if (m_options_up->GetThreadSpec()->GetName() != nullptr && - ::strcmp(m_options_up->GetThreadSpec()->GetName(), thread_name) == 0) + if (m_options.GetThreadSpec()->GetName() != nullptr && + ::strcmp(m_options.GetThreadSpec()->GetName(), thread_name) == 0) return; - m_options_up->GetThreadSpec()->SetName(thread_name); + m_options.GetThreadSpec()->SetName(thread_name); SendBreakpointChangedEvent(eBreakpointEventTypeThreadChanged); } const char *Breakpoint::GetThreadName() const { - if (m_options_up->GetThreadSpecNoCreate() == nullptr) + if (m_options.GetThreadSpecNoCreate() == nullptr) return nullptr; else - return m_options_up->GetThreadSpecNoCreate()->GetName(); + return m_options.GetThreadSpecNoCreate()->GetName(); } void Breakpoint::SetQueueName(const char *queue_name) { - if (m_options_up->GetThreadSpec()->GetQueueName() != nullptr && - ::strcmp(m_options_up->GetThreadSpec()->GetQueueName(), queue_name) == 0) + if (m_options.GetThreadSpec()->GetQueueName() != nullptr && + ::strcmp(m_options.GetThreadSpec()->GetQueueName(), queue_name) == 0) return; - m_options_up->GetThreadSpec()->SetQueueName(queue_name); + m_options.GetThreadSpec()->SetQueueName(queue_name); SendBreakpointChangedEvent(eBreakpointEventTypeThreadChanged); } const char *Breakpoint::GetQueueName() const { - if (m_options_up->GetThreadSpecNoCreate() == nullptr) + if (m_options.GetThreadSpecNoCreate() == nullptr) return nullptr; else - return m_options_up->GetThreadSpecNoCreate()->GetQueueName(); + return m_options.GetThreadSpecNoCreate()->GetQueueName(); } void Breakpoint::SetCondition(const char *condition) { - m_options_up->SetCondition(condition); + m_options.SetCondition(condition); SendBreakpointChangedEvent(eBreakpointEventTypeConditionChanged); } const char *Breakpoint::GetConditionText() const { - return m_options_up->GetConditionText(); + return m_options.GetConditionText(); } // This function is used when "baton" doesn't need to be freed @@ -430,8 +413,8 @@ void Breakpoint::SetCallback(BreakpointHitCallback callback, void *baton, bool is_synchronous) { // The default "Baton" class will keep a copy of "baton" and won't free or // delete it when it goes goes out of scope. - m_options_up->SetCallback(callback, std::make_shared<UntypedBaton>(baton), - is_synchronous); + m_options.SetCallback(callback, std::make_shared<UntypedBaton>(baton), + is_synchronous); SendBreakpointChangedEvent(eBreakpointEventTypeCommandChanged); } @@ -441,21 +424,19 @@ void Breakpoint::SetCallback(BreakpointHitCallback callback, void *baton, void Breakpoint::SetCallback(BreakpointHitCallback callback, const BatonSP &callback_baton_sp, bool is_synchronous) { - m_options_up->SetCallback(callback, callback_baton_sp, is_synchronous); + m_options.SetCallback(callback, callback_baton_sp, is_synchronous); } -void Breakpoint::ClearCallback() { m_options_up->ClearCallback(); } +void Breakpoint::ClearCallback() { m_options.ClearCallback(); } bool Breakpoint::InvokeCallback(StoppointCallbackContext *context, break_id_t bp_loc_id) { - return m_options_up->InvokeCallback(context, GetID(), bp_loc_id); + return m_options.InvokeCallback(context, GetID(), bp_loc_id); } -BreakpointOptions *Breakpoint::GetOptions() { return m_options_up.get(); } +BreakpointOptions &Breakpoint::GetOptions() { return m_options; } -const BreakpointOptions *Breakpoint::GetOptions() const { - return m_options_up.get(); -} +const BreakpointOptions &Breakpoint::GetOptions() const { return m_options; } void Breakpoint::ResolveBreakpoint() { if (m_resolver_sp) @@ -902,7 +883,7 @@ void Breakpoint::GetDescription(Stream *s, lldb::DescriptionLevel level, s->Printf(", locations = 0 (pending)"); } - GetOptions()->GetDescription(s, level); + m_options.GetDescription(s, level); if (m_precondition_sp) m_precondition_sp->GetDescription(*s, level); @@ -944,7 +925,7 @@ void Breakpoint::GetDescription(Stream *s, lldb::DescriptionLevel level, Dump(s); s->EOL(); // s->Indent(); - GetOptions()->GetDescription(s, level); + m_options.GetDescription(s, level); break; default: @@ -980,9 +961,12 @@ bool Breakpoint::GetMatchingFileLine(ConstString filename, if (m_resolver_sp) { BreakpointResolverFileLine *resolverFileLine = dyn_cast<BreakpointResolverFileLine>(m_resolver_sp.get()); + + // TODO: Handle SourceLocationSpec column information if (resolverFileLine && - resolverFileLine->m_file_spec.GetFilename() == filename && - resolverFileLine->m_line_number == line_number) { + resolverFileLine->m_location_spec.GetFileSpec().GetFilename() == + filename && + resolverFileLine->m_location_spec.GetLine() == line_number) { return true; } } diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointID.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointID.cpp index a37abcfa52ab..f20572144068 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointID.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointID.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include <stdio.h> +#include <cstdio> #include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Breakpoint/BreakpointID.h" diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointIDList.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointIDList.cpp index e6a5dceeb93b..172674dc2dd2 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointIDList.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointIDList.cpp @@ -141,7 +141,6 @@ void BreakpointIDList::FindAndReplaceIDRanges(Args &old_args, Target *target, if (!error.Success()) { new_args.Clear(); result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); return; } else names_found.insert(std::string(current_arg)); @@ -170,7 +169,6 @@ void BreakpointIDList::FindAndReplaceIDRanges(Args &old_args, Target *target, new_args.Clear(); result.AppendErrorWithFormat("'%d' is not a valid breakpoint ID.\n", bp_id->GetBreakpointID()); - result.SetStatus(eReturnStatusFailed); return; } const size_t num_locations = breakpoint_sp->GetNumLocations(); @@ -199,7 +197,6 @@ void BreakpointIDList::FindAndReplaceIDRanges(Args &old_args, Target *target, new_args.Clear(); result.AppendErrorWithFormat("'%s' is not a valid breakpoint ID.\n", range_from.str().c_str()); - result.SetStatus(eReturnStatusFailed); return; } @@ -208,7 +205,6 @@ void BreakpointIDList::FindAndReplaceIDRanges(Args &old_args, Target *target, new_args.Clear(); result.AppendErrorWithFormat("'%s' is not a valid breakpoint ID.\n", range_to.str().c_str()); - result.SetStatus(eReturnStatusFailed); return; } break_id_t start_bp_id = start_bp->GetBreakpointID(); @@ -224,7 +220,6 @@ void BreakpointIDList::FindAndReplaceIDRanges(Args &old_args, Target *target, "both ends of range must specify" " a breakpoint location, or neither can " "specify a breakpoint location."); - result.SetStatus(eReturnStatusFailed); return; } @@ -247,7 +242,6 @@ void BreakpointIDList::FindAndReplaceIDRanges(Args &old_args, Target *target, " must be within the same major breakpoint; you specified two" " different major breakpoints, %d and %d.\n", start_bp_id, end_bp_id); - result.SetStatus(eReturnStatusFailed); return; } } diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointList.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointList.cpp index a962703b9518..a00f6bed6181 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointList.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointList.cpp @@ -26,7 +26,7 @@ BreakpointList::BreakpointList(bool is_internal) : m_mutex(), m_breakpoints(), m_next_break_id(0), m_is_internal(is_internal) {} -BreakpointList::~BreakpointList() {} +BreakpointList::~BreakpointList() = default; break_id_t BreakpointList::Add(BreakpointSP &bp_sp, bool notify) { std::lock_guard<std::recursive_mutex> guard(m_mutex); diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointLocation.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointLocation.cpp index d3d6ea08bdb3..0c4d3e052c53 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointLocation.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointLocation.cpp @@ -52,11 +52,10 @@ lldb::addr_t BreakpointLocation::GetLoadAddress() const { return m_address.GetOpcodeLoadAddress(&m_owner.GetTarget()); } -const BreakpointOptions * -BreakpointLocation::GetOptionsSpecifyingKind(BreakpointOptions::OptionKind kind) -const { +const BreakpointOptions &BreakpointLocation::GetOptionsSpecifyingKind( + BreakpointOptions::OptionKind kind) const { if (m_options_up && m_options_up->IsOptionSet(kind)) - return m_options_up.get(); + return *m_options_up; else return m_owner.GetOptions(); } @@ -77,7 +76,7 @@ bool BreakpointLocation::IsEnabled() const { } void BreakpointLocation::SetEnabled(bool enabled) { - GetLocationOptions()->SetEnabled(enabled); + GetLocationOptions().SetEnabled(enabled); if (enabled) { ResolveBreakpointSite(); } else { @@ -96,13 +95,13 @@ bool BreakpointLocation::IsAutoContinue() const { } void BreakpointLocation::SetAutoContinue(bool auto_continue) { - GetLocationOptions()->SetAutoContinue(auto_continue); + GetLocationOptions().SetAutoContinue(auto_continue); SendBreakpointLocationChangedEvent(eBreakpointEventTypeAutoContinueChanged); } void BreakpointLocation::SetThreadID(lldb::tid_t thread_id) { if (thread_id != LLDB_INVALID_THREAD_ID) - GetLocationOptions()->SetThreadID(thread_id); + GetLocationOptions().SetThreadID(thread_id); else { // If we're resetting this to an invalid thread id, then don't make an // options pointer just to do that. @@ -113,9 +112,9 @@ void BreakpointLocation::SetThreadID(lldb::tid_t thread_id) { } lldb::tid_t BreakpointLocation::GetThreadID() { - const ThreadSpec *thread_spec = + const ThreadSpec *thread_spec = GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec) - ->GetThreadSpecNoCreate(); + .GetThreadSpecNoCreate(); if (thread_spec) return thread_spec->GetTID(); else @@ -124,7 +123,7 @@ lldb::tid_t BreakpointLocation::GetThreadID() { void BreakpointLocation::SetThreadIndex(uint32_t index) { if (index != 0) - GetLocationOptions()->GetThreadSpec()->SetIndex(index); + GetLocationOptions().GetThreadSpec()->SetIndex(index); else { // If we're resetting this to an invalid thread id, then don't make an // options pointer just to do that. @@ -135,9 +134,9 @@ void BreakpointLocation::SetThreadIndex(uint32_t index) { } uint32_t BreakpointLocation::GetThreadIndex() const { - const ThreadSpec *thread_spec = + const ThreadSpec *thread_spec = GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec) - ->GetThreadSpecNoCreate(); + .GetThreadSpecNoCreate(); if (thread_spec) return thread_spec->GetIndex(); else @@ -146,7 +145,7 @@ uint32_t BreakpointLocation::GetThreadIndex() const { void BreakpointLocation::SetThreadName(const char *thread_name) { if (thread_name != nullptr) - GetLocationOptions()->GetThreadSpec()->SetName(thread_name); + GetLocationOptions().GetThreadSpec()->SetName(thread_name); else { // If we're resetting this to an invalid thread id, then don't make an // options pointer just to do that. @@ -157,9 +156,9 @@ void BreakpointLocation::SetThreadName(const char *thread_name) { } const char *BreakpointLocation::GetThreadName() const { - const ThreadSpec *thread_spec = + const ThreadSpec *thread_spec = GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec) - ->GetThreadSpecNoCreate(); + .GetThreadSpecNoCreate(); if (thread_spec) return thread_spec->GetName(); else @@ -168,7 +167,7 @@ const char *BreakpointLocation::GetThreadName() const { void BreakpointLocation::SetQueueName(const char *queue_name) { if (queue_name != nullptr) - GetLocationOptions()->GetThreadSpec()->SetQueueName(queue_name); + GetLocationOptions().GetThreadSpec()->SetQueueName(queue_name); else { // If we're resetting this to an invalid thread id, then don't make an // options pointer just to do that. @@ -179,9 +178,9 @@ void BreakpointLocation::SetQueueName(const char *queue_name) { } const char *BreakpointLocation::GetQueueName() const { - const ThreadSpec *thread_spec = + const ThreadSpec *thread_spec = GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec) - ->GetThreadSpecNoCreate(); + .GetThreadSpecNoCreate(); if (thread_spec) return thread_spec->GetQueueName(); else @@ -195,11 +194,18 @@ bool BreakpointLocation::InvokeCallback(StoppointCallbackContext *context) { return m_owner.InvokeCallback(context, GetID()); } +bool BreakpointLocation::IsCallbackSynchronous() { + if (m_options_up != nullptr && m_options_up->HasCallback()) + return m_options_up->IsCallbackSynchronous(); + else + return m_owner.GetOptions().IsCallbackSynchronous(); +} + void BreakpointLocation::SetCallback(BreakpointHitCallback callback, void *baton, bool is_synchronous) { // The default "Baton" class will keep a copy of "baton" and won't free or // delete it when it goes goes out of scope. - GetLocationOptions()->SetCallback( + GetLocationOptions().SetCallback( callback, std::make_shared<UntypedBaton>(baton), is_synchronous); SendBreakpointLocationChangedEvent(eBreakpointEventTypeCommandChanged); } @@ -207,22 +213,22 @@ void BreakpointLocation::SetCallback(BreakpointHitCallback callback, void BreakpointLocation::SetCallback(BreakpointHitCallback callback, const BatonSP &baton_sp, bool is_synchronous) { - GetLocationOptions()->SetCallback(callback, baton_sp, is_synchronous); + GetLocationOptions().SetCallback(callback, baton_sp, is_synchronous); SendBreakpointLocationChangedEvent(eBreakpointEventTypeCommandChanged); } void BreakpointLocation::ClearCallback() { - GetLocationOptions()->ClearCallback(); + GetLocationOptions().ClearCallback(); } void BreakpointLocation::SetCondition(const char *condition) { - GetLocationOptions()->SetCondition(condition); + GetLocationOptions().SetCondition(condition); SendBreakpointLocationChangedEvent(eBreakpointEventTypeConditionChanged); } const char *BreakpointLocation::GetConditionText(size_t *hash) const { return GetOptionsSpecifyingKind(BreakpointOptions::eCondition) - ->GetConditionText(hash); + .GetConditionText(hash); } bool BreakpointLocation::ConditionSaysStop(ExecutionContext &exe_ctx, @@ -333,11 +339,11 @@ bool BreakpointLocation::ConditionSaysStop(ExecutionContext &exe_ctx, uint32_t BreakpointLocation::GetIgnoreCount() const { return GetOptionsSpecifyingKind(BreakpointOptions::eIgnoreCount) - ->GetIgnoreCount(); + .GetIgnoreCount(); } void BreakpointLocation::SetIgnoreCount(uint32_t n) { - GetLocationOptions()->SetIgnoreCount(n); + GetLocationOptions().SetIgnoreCount(n); SendBreakpointLocationChangedEvent(eBreakpointEventTypeIgnoreChanged); } @@ -350,33 +356,34 @@ void BreakpointLocation::DecrementIgnoreCount() { } bool BreakpointLocation::IgnoreCountShouldStop() { - if (m_options_up != nullptr) { - uint32_t loc_ignore = m_options_up->GetIgnoreCount(); - if (loc_ignore != 0) { - m_owner.DecrementIgnoreCount(); - DecrementIgnoreCount(); // Have to decrement our owners' ignore count, - // since it won't get a - // chance to. - return false; - } + uint32_t owner_ignore = GetBreakpoint().GetIgnoreCount(); + uint32_t loc_ignore = 0; + if (m_options_up != nullptr) + loc_ignore = m_options_up->GetIgnoreCount(); + + if (loc_ignore != 0 || owner_ignore != 0) { + m_owner.DecrementIgnoreCount(); + DecrementIgnoreCount(); // Have to decrement our owners' ignore count, + // since it won't get a chance to. + return false; } return true; } -BreakpointOptions *BreakpointLocation::GetLocationOptions() { +BreakpointOptions &BreakpointLocation::GetLocationOptions() { // If we make the copy we don't copy the callbacks because that is // potentially expensive and we don't want to do that for the simple case // where someone is just disabling the location. if (m_options_up == nullptr) m_options_up = std::make_unique<BreakpointOptions>(false); - return m_options_up.get(); + return *m_options_up; } -bool BreakpointLocation::ValidForThisThread(Thread *thread) { - return thread - ->MatchesSpec(GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec) - ->GetThreadSpecNoCreate()); +bool BreakpointLocation::ValidForThisThread(Thread &thread) { + return thread.MatchesSpec( + GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec) + .GetThreadSpecNoCreate()); } // RETURNS - true if we should stop at this breakpoint, false if we @@ -393,12 +400,6 @@ bool BreakpointLocation::ShouldStop(StoppointCallbackContext *context) { if (!IsEnabled()) return false; - if (!IgnoreCountShouldStop()) - return false; - - if (!m_owner.IgnoreCountShouldStop()) - return false; - // We only run synchronous callbacks in ShouldStop: context->is_synchronous = true; should_stop = InvokeCallback(context); @@ -629,7 +630,8 @@ void BreakpointLocation::Dump(Stream *s) const { m_bp_site_sp->GetHardwareIndex() : LLDB_INVALID_INDEX32; lldb::tid_t tid = GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec) - ->GetThreadSpecNoCreate()->GetTID(); + .GetThreadSpecNoCreate() + ->GetTID(); s->Printf("BreakpointLocation %u: tid = %4.4" PRIx64 " load addr = 0x%8.8" PRIx64 " state = %s type = %s breakpoint " "hw_index = %i hit_count = %-4u ignore_count = %-4u", @@ -638,9 +640,10 @@ void BreakpointLocation::Dump(Stream *s) const { (m_options_up ? m_options_up->IsEnabled() : m_owner.IsEnabled()) ? "enabled " : "disabled", - is_hardware ? "hardware" : "software", hardware_index, GetHitCount(), + is_hardware ? "hardware" : "software", hardware_index, + GetHitCount(), GetOptionsSpecifyingKind(BreakpointOptions::eIgnoreCount) - ->GetIgnoreCount()); + .GetIgnoreCount()); } void BreakpointLocation::SendBreakpointLocationChangedEvent( diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointLocationCollection.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointLocationCollection.cpp index 1eb13cb12ba3..6c55629b5aad 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointLocationCollection.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointLocationCollection.cpp @@ -21,7 +21,7 @@ BreakpointLocationCollection::BreakpointLocationCollection() : m_break_loc_collection(), m_collection_mutex() {} // Destructor -BreakpointLocationCollection::~BreakpointLocationCollection() {} +BreakpointLocationCollection::~BreakpointLocationCollection() = default; void BreakpointLocationCollection::Add(const BreakpointLocationSP &bp_loc) { std::lock_guard<std::mutex> guard(m_collection_mutex); @@ -134,7 +134,7 @@ bool BreakpointLocationCollection::ShouldStop( return shouldStop; } -bool BreakpointLocationCollection::ValidForThisThread(Thread *thread) { +bool BreakpointLocationCollection::ValidForThisThread(Thread &thread) { std::lock_guard<std::mutex> guard(m_collection_mutex); collection::iterator pos, begin = m_break_loc_collection.begin(), end = m_break_loc_collection.end(); diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointName.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointName.cpp index 37903a002363..cb513fb436d6 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointName.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointName.cpp @@ -81,6 +81,6 @@ bool BreakpointName::GetDescription(Stream *s, lldb::DescriptionLevel level) { void BreakpointName::ConfigureBreakpoint(lldb::BreakpointSP bp_sp) { - bp_sp->GetOptions()->CopyOverSetOptions(GetOptions()); - bp_sp->GetPermissions().MergeInto(GetPermissions()); + bp_sp->GetOptions().CopyOverSetOptions(GetOptions()); + bp_sp->GetPermissions().MergeInto(GetPermissions()); } diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointOptions.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointOptions.cpp index f6bb7633d0a9..86a7c483df83 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointOptions.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointOptions.cpp @@ -332,7 +332,7 @@ std::unique_ptr<BreakpointOptions> BreakpointOptions::CreateFromStructuredData( } Status script_error; script_error = - interp->SetBreakpointCommandCallback(bp_options.get(), cmd_data_up); + interp->SetBreakpointCommandCallback(*bp_options, cmd_data_up); if (script_error.Fail()) { error.SetErrorStringWithFormat("Error generating script callback: %s.", error.AsCString()); @@ -453,8 +453,6 @@ bool BreakpointOptions::InvokeCallback(StoppointCallbackContext *context, : nullptr, context, break_id, break_loc_id); } else if (IsCallbackSynchronous()) { - // If a synchronous callback is called at async time, it should not say - // to stop. return false; } } @@ -649,7 +647,7 @@ bool BreakpointOptions::BreakpointOptionsCallbackFunction( options.SetPrintErrors(true); options.SetAddToHistory(false); - debugger.GetCommandInterpreter().HandleCommands(commands, &exe_ctx, + debugger.GetCommandInterpreter().HandleCommands(commands, exe_ctx, options, result); result.GetImmediateOutputStream()->Flush(); result.GetImmediateErrorStream()->Flush(); diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolver.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolver.cpp index cfd073367b00..d3d57a282d09 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolver.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolver.cpp @@ -65,7 +65,7 @@ BreakpointResolver::BreakpointResolver(const BreakpointSP &bkpt, lldb::addr_t offset) : m_breakpoint(bkpt), m_offset(offset), SubclassID(resolverTy) {} -BreakpointResolver::~BreakpointResolver() {} +BreakpointResolver::~BreakpointResolver() = default; BreakpointResolverSP BreakpointResolver::CreateFromStructuredData( const StructuredData::Dictionary &resolver_dict, Status &error) { @@ -180,29 +180,29 @@ void BreakpointResolver::ResolveBreakpoint(SearchFilter &filter) { namespace { struct SourceLoc { uint32_t line = UINT32_MAX; - uint32_t column; - SourceLoc(uint32_t l, uint32_t c) : line(l), column(c ? c : UINT32_MAX) {} + uint16_t column; + SourceLoc(uint32_t l, llvm::Optional<uint16_t> c) + : line(l), column(c ? *c : LLDB_INVALID_COLUMN_NUMBER) {} SourceLoc(const SymbolContext &sc) : line(sc.line_entry.line), - column(sc.line_entry.column ? sc.line_entry.column : UINT32_MAX) {} + column(sc.line_entry.column ? sc.line_entry.column + : LLDB_INVALID_COLUMN_NUMBER) {} }; -bool operator<(const SourceLoc a, const SourceLoc b) { - if (a.line < b.line) +bool operator<(const SourceLoc lhs, const SourceLoc rhs) { + if (lhs.line < rhs.line) return true; - if (a.line > b.line) + if (lhs.line > rhs.line) return false; - uint32_t a_col = a.column ? a.column : UINT32_MAX; - uint32_t b_col = b.column ? b.column : UINT32_MAX; - return a_col < b_col; + // uint32_t a_col = lhs.column ? lhs.column : LLDB_INVALID_COLUMN_NUMBER; + // uint32_t b_col = rhs.column ? rhs.column : LLDB_INVALID_COLUMN_NUMBER; + return lhs.column < rhs.column; } } // namespace -void BreakpointResolver::SetSCMatchesByLine(SearchFilter &filter, - SymbolContextList &sc_list, - bool skip_prologue, - llvm::StringRef log_ident, - uint32_t line, uint32_t column) { +void BreakpointResolver::SetSCMatchesByLine( + SearchFilter &filter, SymbolContextList &sc_list, bool skip_prologue, + llvm::StringRef log_ident, uint32_t line, llvm::Optional<uint16_t> column) { llvm::SmallVector<SymbolContext, 16> all_scs; for (uint32_t i = 0; i < sc_list.GetSize(); ++i) all_scs.push_back(sc_list[i]); @@ -228,13 +228,13 @@ void BreakpointResolver::SetSCMatchesByLine(SearchFilter &filter, if (column) { // If a column was requested, do a more precise match and only - // return the first location that comes after or at the + // return the first location that comes before or at the // requested location. - SourceLoc requested(line, column); + SourceLoc requested(line, *column); // First, filter out all entries left of the requested column. worklist_end = std::remove_if( worklist_begin, worklist_end, - [&](const SymbolContext &sc) { return SourceLoc(sc) < requested; }); + [&](const SymbolContext &sc) { return requested < SourceLoc(sc); }); // Sort the remaining entries by (line, column). llvm::sort(worklist_begin, worklist_end, [](const SymbolContext &a, const SymbolContext &b) { diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp index 5ca4ef5834e0..1d1ac2e90bdc 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp @@ -20,20 +20,17 @@ using namespace lldb_private; // BreakpointResolverFileLine: BreakpointResolverFileLine::BreakpointResolverFileLine( - const BreakpointSP &bkpt, const FileSpec &file_spec, uint32_t line_no, - uint32_t column, lldb::addr_t offset, bool check_inlines, - bool skip_prologue, bool exact_match) + const BreakpointSP &bkpt, lldb::addr_t offset, bool skip_prologue, + const SourceLocationSpec &location_spec) : BreakpointResolver(bkpt, BreakpointResolver::FileLineResolver, offset), - m_file_spec(file_spec), m_line_number(line_no), m_column(column), - m_inlines(check_inlines), m_skip_prologue(skip_prologue), - m_exact_match(exact_match) {} + m_location_spec(location_spec), m_skip_prologue(skip_prologue) {} BreakpointResolver *BreakpointResolverFileLine::CreateFromStructuredData( const BreakpointSP &bkpt, const StructuredData::Dictionary &options_dict, Status &error) { llvm::StringRef filename; - uint32_t line_no; - uint32_t column; + uint32_t line; + uint16_t column; bool check_inlines; bool skip_prologue; bool exact_match; @@ -49,7 +46,7 @@ BreakpointResolver *BreakpointResolverFileLine::CreateFromStructuredData( } success = options_dict.GetValueForKeyAsInteger( - GetKey(OptionNames::LineNumber), line_no); + GetKey(OptionNames::LineNumber), line); if (!success) { error.SetErrorString("BRFL::CFSD: Couldn't find line number entry."); return nullptr; @@ -83,11 +80,13 @@ BreakpointResolver *BreakpointResolverFileLine::CreateFromStructuredData( return nullptr; } - FileSpec file_spec(filename); + SourceLocationSpec location_spec(FileSpec(filename), line, column, + check_inlines, exact_match); + if (!location_spec) + return nullptr; - return new BreakpointResolverFileLine(bkpt, file_spec, line_no, column, - offset, check_inlines, skip_prologue, - exact_match); + return new BreakpointResolverFileLine(bkpt, offset, skip_prologue, + location_spec); } StructuredData::ObjectSP @@ -95,17 +94,19 @@ BreakpointResolverFileLine::SerializeToStructuredData() { StructuredData::DictionarySP options_dict_sp( new StructuredData::Dictionary()); - options_dict_sp->AddStringItem(GetKey(OptionNames::FileName), - m_file_spec.GetPath()); - options_dict_sp->AddIntegerItem(GetKey(OptionNames::LineNumber), - m_line_number); - options_dict_sp->AddIntegerItem(GetKey(OptionNames::Column), - m_column); - options_dict_sp->AddBooleanItem(GetKey(OptionNames::Inlines), m_inlines); options_dict_sp->AddBooleanItem(GetKey(OptionNames::SkipPrologue), m_skip_prologue); + options_dict_sp->AddStringItem(GetKey(OptionNames::FileName), + m_location_spec.GetFileSpec().GetPath()); + options_dict_sp->AddIntegerItem(GetKey(OptionNames::LineNumber), + m_location_spec.GetLine().getValueOr(0)); + options_dict_sp->AddIntegerItem( + GetKey(OptionNames::Column), + m_location_spec.GetColumn().getValueOr(LLDB_INVALID_COLUMN_NUMBER)); + options_dict_sp->AddBooleanItem(GetKey(OptionNames::Inlines), + m_location_spec.GetCheckInlines()); options_dict_sp->AddBooleanItem(GetKey(OptionNames::ExactMatch), - m_exact_match); + m_location_spec.GetExactMatch()); return WrapOptionsDict(options_dict_sp); } @@ -119,12 +120,12 @@ BreakpointResolverFileLine::SerializeToStructuredData() { // inlined into. void BreakpointResolverFileLine::FilterContexts(SymbolContextList &sc_list, bool is_relative) { - if (m_exact_match) + if (m_location_spec.GetExactMatch()) return; // Nothing to do. Contexts are precise. llvm::StringRef relative_path; if (is_relative) - relative_path = m_file_spec.GetDirectory().GetStringRef(); + relative_path = m_location_spec.GetFileSpec().GetDirectory().GetStringRef(); Log * log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS); for(uint32_t i = 0; i < sc_list.GetSize(); ++i) { @@ -191,12 +192,13 @@ void BreakpointResolverFileLine::FilterContexts(SymbolContextList &sc_list, // But only do this calculation if the line number we found in the SC // was different from the one requested in the source file. If we actually // found an exact match it must be valid. - - if (m_line_number == sc.line_entry.line) + + if (m_location_spec.GetLine() == sc.line_entry.line) continue; const int decl_line_is_too_late_fudge = 1; - if (line && m_line_number < line - decl_line_is_too_late_fudge) { + if (line && + m_location_spec.GetLine() < line - decl_line_is_too_late_fudge) { LLDB_LOG(log, "removing symbol context at {0}:{1}", file, line); sc_list.RemoveContextAtIndex(i); --i; @@ -224,8 +226,11 @@ Searcher::CallbackReturn BreakpointResolverFileLine::SearchCallback( // file. So we go through the match list and pull out the sets that have the // same file spec in their line_entry and treat each set separately. - FileSpec search_file_spec = m_file_spec; - const bool is_relative = m_file_spec.IsRelative(); + const uint32_t line = m_location_spec.GetLine().getValueOr(0); + const llvm::Optional<uint16_t> column = m_location_spec.GetColumn(); + + FileSpec search_file_spec = m_location_spec.GetFileSpec(); + const bool is_relative = search_file_spec.IsRelative(); if (is_relative) search_file_spec.GetDirectory().Clear(); @@ -234,8 +239,7 @@ Searcher::CallbackReturn BreakpointResolverFileLine::SearchCallback( CompUnitSP cu_sp(context.module_sp->GetCompileUnitAtIndex(i)); if (cu_sp) { if (filter.CompUnitPasses(*cu_sp)) - cu_sp->ResolveSymbolContext(search_file_spec, m_line_number, m_inlines, - m_exact_match, eSymbolContextEverything, + cu_sp->ResolveSymbolContext(m_location_spec, eSymbolContextEverything, sc_list); } } @@ -243,11 +247,12 @@ Searcher::CallbackReturn BreakpointResolverFileLine::SearchCallback( FilterContexts(sc_list, is_relative); StreamString s; - s.Printf("for %s:%d ", m_file_spec.GetFilename().AsCString("<Unknown>"), - m_line_number); + s.Printf("for %s:%d ", + m_location_spec.GetFileSpec().GetFilename().AsCString("<Unknown>"), + line); - SetSCMatchesByLine(filter, sc_list, m_skip_prologue, s.GetString(), - m_line_number, m_column); + SetSCMatchesByLine(filter, sc_list, m_skip_prologue, s.GetString(), line, + column); return Searcher::eCallbackReturnContinue; } @@ -257,11 +262,13 @@ lldb::SearchDepth BreakpointResolverFileLine::GetDepth() { } void BreakpointResolverFileLine::GetDescription(Stream *s) { - s->Printf("file = '%s', line = %u, ", m_file_spec.GetPath().c_str(), - m_line_number); - if (m_column) - s->Printf("column = %u, ", m_column); - s->Printf("exact_match = %d", m_exact_match); + s->Printf("file = '%s', line = %u, ", + m_location_spec.GetFileSpec().GetPath().c_str(), + m_location_spec.GetLine().getValueOr(0)); + auto column = m_location_spec.GetColumn(); + if (column) + s->Printf("column = %u, ", *column); + s->Printf("exact_match = %d", m_location_spec.GetExactMatch()); } void BreakpointResolverFileLine::Dump(Stream *s) const {} @@ -269,8 +276,7 @@ void BreakpointResolverFileLine::Dump(Stream *s) const {} lldb::BreakpointResolverSP BreakpointResolverFileLine::CopyForBreakpoint(BreakpointSP &breakpoint) { lldb::BreakpointResolverSP ret_sp(new BreakpointResolverFileLine( - breakpoint, m_file_spec, m_line_number, m_column, GetOffset(), m_inlines, - m_skip_prologue, m_exact_match)); + breakpoint, GetOffset(), m_skip_prologue, m_location_spec)); return ret_sp; } diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp index 62462b2f5441..435983769c05 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp @@ -107,10 +107,11 @@ Searcher::CallbackReturn BreakpointResolverFileRegex::SearchCallback( uint32_t num_matches = line_matches.size(); for (uint32_t i = 0; i < num_matches; i++) { SymbolContextList sc_list; - const bool search_inlines = false; - - cu->ResolveSymbolContext(cu_file_spec, line_matches[i], search_inlines, - m_exact_match, eSymbolContextEverything, sc_list); + // TODO: Handle SourceLocationSpec column information + SourceLocationSpec location_spec(cu_file_spec, line_matches[i], + /*column=*/llvm::None, + /*search_inlines=*/false, m_exact_match); + cu->ResolveSymbolContext(location_spec, eSymbolContextEverything, sc_list); // Find all the function names: if (!m_function_names.empty()) { std::vector<size_t> sc_to_remove; diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverName.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverName.cpp index 6fab20af5e59..121ac5690d70 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverName.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverName.cpp @@ -31,7 +31,7 @@ BreakpointResolverName::BreakpointResolverName(const BreakpointSP &bkpt, m_class_name(), m_regex(), m_match_type(type), m_language(language), m_skip_prologue(skip_prologue) { if (m_match_type == Breakpoint::Regexp) { - m_regex = RegularExpression(llvm::StringRef::withNullAsEmpty(name_cstr)); + m_regex = RegularExpression(name_cstr); if (!m_regex.IsValid()) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); @@ -220,11 +220,15 @@ void BreakpointResolverName::AddNameLookup(ConstString name, m_lookups.emplace_back(lookup); auto add_variant_funcs = [&](Language *lang) { - for (ConstString variant_name : lang->GetMethodNameVariants(name)) { - Module::LookupInfo variant_lookup(name, name_type_mask, - lang->GetLanguageType()); - variant_lookup.SetLookupName(variant_name); - m_lookups.emplace_back(variant_lookup); + for (Language::MethodNameVariant variant : + lang->GetMethodNameVariants(name)) { + // FIXME: Should we be adding variants that aren't of type Full? + if (variant.GetType() & lldb::eFunctionNameTypeFull) { + Module::LookupInfo variant_lookup(name, variant.GetType(), + lang->GetLanguageType()); + variant_lookup.SetLookupName(variant.GetName()); + m_lookups.emplace_back(variant_lookup); + } } return true; }; diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointSite.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointSite.cpp index fb3f0cd06897..f0469326657c 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointSite.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointSite.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include <inttypes.h> +#include <cinttypes> #include "lldb/Breakpoint/BreakpointSite.h" @@ -144,7 +144,7 @@ BreakpointLocationSP BreakpointSite::GetOwnerAtIndex(size_t index) { return m_owners.GetByIndex(index); } -bool BreakpointSite::ValidForThisThread(Thread *thread) { +bool BreakpointSite::ValidForThisThread(Thread &thread) { std::lock_guard<std::recursive_mutex> guard(m_owners_mutex); return m_owners.ValidForThisThread(thread); } diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointSiteList.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointSiteList.cpp index 873ba6236a72..c6966145e42b 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointSiteList.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointSiteList.cpp @@ -16,7 +16,7 @@ using namespace lldb_private; BreakpointSiteList::BreakpointSiteList() : m_mutex(), m_bp_site_list() {} -BreakpointSiteList::~BreakpointSiteList() {} +BreakpointSiteList::~BreakpointSiteList() = default; // Add breakpoint site to the list. However, if the element already exists in // the list, then we don't add it, and return LLDB_INVALID_BREAK_ID. diff --git a/contrib/llvm-project/lldb/source/Breakpoint/Stoppoint.cpp b/contrib/llvm-project/lldb/source/Breakpoint/Stoppoint.cpp index b5c8334333cf..94e97cd4542f 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/Stoppoint.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/Stoppoint.cpp @@ -14,10 +14,10 @@ using namespace lldb; using namespace lldb_private; // Stoppoint constructor -Stoppoint::Stoppoint() : m_bid(LLDB_INVALID_BREAK_ID) {} +Stoppoint::Stoppoint() = default; // Destructor -Stoppoint::~Stoppoint() {} +Stoppoint::~Stoppoint() = default; break_id_t Stoppoint::GetID() const { return m_bid; } diff --git a/contrib/llvm-project/lldb/source/Breakpoint/StoppointCallbackContext.cpp b/contrib/llvm-project/lldb/source/Breakpoint/StoppointCallbackContext.cpp index 640db8bb9c96..a561c99b1d92 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/StoppointCallbackContext.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/StoppointCallbackContext.cpp @@ -10,8 +10,7 @@ using namespace lldb_private; -StoppointCallbackContext::StoppointCallbackContext() - : event(nullptr), exe_ctx_ref(), is_synchronous(false) {} +StoppointCallbackContext::StoppointCallbackContext() : exe_ctx_ref() {} StoppointCallbackContext::StoppointCallbackContext( Event *e, const ExecutionContext &exe_ctx, bool synchronously) diff --git a/contrib/llvm-project/lldb/source/Breakpoint/WatchpointList.cpp b/contrib/llvm-project/lldb/source/Breakpoint/WatchpointList.cpp index a6f651e84955..100c1e51ac5a 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/WatchpointList.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/WatchpointList.cpp @@ -12,10 +12,9 @@ using namespace lldb; using namespace lldb_private; -WatchpointList::WatchpointList() - : m_watchpoints(), m_mutex(), m_next_wp_id(0) {} +WatchpointList::WatchpointList() : m_watchpoints(), m_mutex() {} -WatchpointList::~WatchpointList() {} +WatchpointList::~WatchpointList() = default; // Add a watchpoint to the list. lldb::watch_id_t WatchpointList::Add(const WatchpointSP &wp_sp, bool notify) { diff --git a/contrib/llvm-project/lldb/source/Breakpoint/WatchpointOptions.cpp b/contrib/llvm-project/lldb/source/Breakpoint/WatchpointOptions.cpp index f01f5ad3dd27..a578e8744efb 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/WatchpointOptions.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/WatchpointOptions.cpp @@ -28,7 +28,7 @@ bool WatchpointOptions::NullCallback(void *baton, // WatchpointOptions constructor WatchpointOptions::WatchpointOptions() : m_callback(WatchpointOptions::NullCallback), m_callback_baton_sp(), - m_callback_is_synchronous(false), m_thread_spec_up() {} + m_thread_spec_up() {} // WatchpointOptions copy constructor WatchpointOptions::WatchpointOptions(const WatchpointOptions &rhs) diff --git a/contrib/llvm-project/lldb/source/Commands/CommandCompletions.cpp b/contrib/llvm-project/lldb/source/Commands/CommandCompletions.cpp index 0ea6d4288169..55018cef57d4 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandCompletions.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandCompletions.cpp @@ -331,7 +331,7 @@ static void DiskFilesOrDirectories(const llvm::Twine &partial_name, llvm::StringRef PartialItem; if (CompletionBuffer.startswith("~")) { - llvm::StringRef Buffer(CompletionBuffer); + llvm::StringRef Buffer = CompletionBuffer; size_t FirstSep = Buffer.find_if([](char c) { return path::is_separator(c); }); @@ -774,9 +774,7 @@ void CommandCompletions::WatchPointIDs(CommandInterpreter &interpreter, return; const WatchpointList &wp_list = exe_ctx.GetTargetPtr()->GetWatchpointList(); - const size_t wp_num = wp_list.GetSize(); - for (size_t idx = 0; idx < wp_num; ++idx) { - const lldb::WatchpointSP wp_sp = wp_list.GetByIndex(idx); + for (lldb::WatchpointSP wp_sp : wp_list.Watchpoints()) { StreamString strm; wp_sp->Dump(&strm); request.TryCompleteCurrentArg(std::to_string(wp_sp->GetID()), diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectApropos.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectApropos.cpp index 6e1e1f061733..656487169a34 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectApropos.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectApropos.cpp @@ -86,11 +86,9 @@ bool CommandObjectApropos::DoExecute(Args &args, CommandReturnObject &result) { result.SetStatus(eReturnStatusSuccessFinishNoResult); } else { result.AppendError("'' is not a valid search word.\n"); - result.SetStatus(eReturnStatusFailed); } } else { result.AppendError("'apropos' must be called with exactly one argument.\n"); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.cpp index 0844c56cef2f..722d5c4d8f47 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.cpp @@ -242,15 +242,8 @@ public: class CommandOptions : public OptionGroup { public: CommandOptions() - : OptionGroup(), m_condition(), m_filenames(), m_line_num(0), - m_column(0), m_func_names(), - m_func_name_type_mask(eFunctionNameTypeNone), m_func_regexp(), - m_source_text_regexp(), m_modules(), m_load_addr(), m_catch_bp(false), - m_throw_bp(true), m_hardware(false), - m_exception_language(eLanguageTypeUnknown), - m_language(lldb::eLanguageTypeUnknown), - m_skip_prologue(eLazyBoolCalculate), m_all_files(false), - m_move_to_nearest_code(eLazyBoolCalculate) {} + : OptionGroup(), m_condition(), m_filenames(), m_func_names(), + m_func_regexp(), m_source_text_regexp(), m_modules() {} ~CommandOptions() override = default; @@ -500,25 +493,25 @@ public: std::string m_condition; FileSpecList m_filenames; - uint32_t m_line_num; - uint32_t m_column; + uint32_t m_line_num = 0; + uint32_t m_column = 0; std::vector<std::string> m_func_names; std::vector<std::string> m_breakpoint_names; - lldb::FunctionNameType m_func_name_type_mask; + lldb::FunctionNameType m_func_name_type_mask = eFunctionNameTypeNone; std::string m_func_regexp; std::string m_source_text_regexp; FileSpecList m_modules; - lldb::addr_t m_load_addr; + lldb::addr_t m_load_addr = 0; lldb::addr_t m_offset_addr; - bool m_catch_bp; - bool m_throw_bp; - bool m_hardware; // Request to use hardware breakpoints - lldb::LanguageType m_exception_language; - lldb::LanguageType m_language; - LazyBool m_skip_prologue; - bool m_all_files; + bool m_catch_bp = false; + bool m_throw_bp = true; + bool m_hardware = false; // Request to use hardware breakpoints + lldb::LanguageType m_exception_language = eLanguageTypeUnknown; + lldb::LanguageType m_language = lldb::eLanguageTypeUnknown; + LazyBool m_skip_prologue = eLazyBoolCalculate; + bool m_all_files = false; Args m_exception_extra_args; - LazyBool m_move_to_nearest_code; + LazyBool m_move_to_nearest_code = eLazyBoolCalculate; std::unordered_set<std::string> m_source_regex_func_names; std::string m_current_key; }; @@ -573,13 +566,11 @@ protected: if (num_files == 0) { if (!GetDefaultFile(target, file, result)) { result.AppendError("No file supplied and no default file available."); - result.SetStatus(eReturnStatusFailed); return false; } } else if (num_files > 1) { result.AppendError("Only one file at a time is allowed for file and " "line breakpoints."); - result.SetStatus(eReturnStatusFailed); return false; } else file = m_options.m_filenames.GetFileSpecAtIndex(0); @@ -611,7 +602,6 @@ protected: } else { result.AppendError("Only one shared library can be specified for " "address breakpoints."); - result.SetStatus(eReturnStatusFailed); return false; } break; @@ -646,7 +636,6 @@ protected: result.AppendWarning( "Function name regex does not accept glob patterns."); } - result.SetStatus(eReturnStatusFailed); return false; } @@ -664,7 +653,6 @@ protected: if (!GetDefaultFile(target, file, result)) { result.AppendError( "No files provided and could not find default file."); - result.SetStatus(eReturnStatusFailed); return false; } else { m_options.m_filenames.Append(file); @@ -676,7 +664,6 @@ protected: result.AppendErrorWithFormat( "Source text regular expression could not be compiled: \"%s\"", llvm::toString(std::move(err)).c_str()); - result.SetStatus(eReturnStatusFailed); return false; } bp_sp = target.CreateSourceRegexBreakpoint( @@ -695,7 +682,6 @@ protected: "Error setting extra exception arguments: %s", precond_error.AsCString()); target.RemoveBreakpointByID(bp_sp->GetID()); - result.SetStatus(eReturnStatusFailed); return false; } } break; @@ -710,7 +696,6 @@ protected: result.AppendErrorWithFormat( "Error setting extra exception arguments: %s", error.AsCString()); target.RemoveBreakpointByID(bp_sp->GetID()); - result.SetStatus(eReturnStatusFailed); return false; } } break; @@ -720,7 +705,7 @@ protected: // Now set the various options that were passed in: if (bp_sp) { - bp_sp->GetOptions()->CopyOverSetOptions(m_bp_opts.GetBreakpointOptions()); + bp_sp->GetOptions().CopyOverSetOptions(m_bp_opts.GetBreakpointOptions()); if (!m_options.m_breakpoint_names.empty()) { Status name_error; @@ -730,7 +715,6 @@ protected: result.AppendErrorWithFormat("Invalid breakpoint name: %s", name.c_str()); target.RemoveBreakpointByID(bp_sp->GetID()); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -757,7 +741,6 @@ protected: result.SetStatus(eReturnStatusSuccessFinishResult); } else if (!bp_sp) { result.AppendError("Breakpoint creation failed: No breakpoint created."); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); @@ -774,12 +757,10 @@ private: if (cur_frame == nullptr) { result.AppendError( "No selected frame to use to find the default file."); - result.SetStatus(eReturnStatusFailed); return false; } else if (!cur_frame->HasDebugInformation()) { result.AppendError("Cannot use the selected frame to find the default " "file, it has no debug info."); - result.SetStatus(eReturnStatusFailed); return false; } else { const SymbolContext &sc = @@ -789,7 +770,6 @@ private: } else { result.AppendError("Can't find the file for the selected frame to " "use as the default file."); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -870,10 +850,10 @@ protected: BreakpointLocation *location = bp->FindLocationByID(cur_bp_id.GetLocationID()).get(); if (location) - location->GetLocationOptions()->CopyOverSetOptions( + location->GetLocationOptions().CopyOverSetOptions( m_bp_opts.GetBreakpointOptions()); } else { - bp->GetOptions()->CopyOverSetOptions( + bp->GetOptions().CopyOverSetOptions( m_bp_opts.GetBreakpointOptions()); } } @@ -930,7 +910,6 @@ protected: if (num_breakpoints == 0) { result.AppendError("No breakpoints exist to be enabled."); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1044,7 +1023,6 @@ protected: if (num_breakpoints == 0) { result.AppendError("No breakpoints exist to be disabled."); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1133,9 +1111,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() - : Options(), m_level(lldb::eDescriptionLevelBrief), m_use_dummy(false) { - } + CommandOptions() : Options() {} ~CommandOptions() override = default; @@ -1179,10 +1155,10 @@ public: // Instance variables to hold the values for command options. - lldb::DescriptionLevel m_level; + lldb::DescriptionLevel m_level = lldb::eDescriptionLevelBrief; bool m_internal; - bool m_use_dummy; + bool m_use_dummy = false; }; protected: @@ -1232,7 +1208,6 @@ protected: result.SetStatus(eReturnStatusSuccessFinishNoResult); } else { result.AppendError("Invalid breakpoint ID."); - result.SetStatus(eReturnStatusFailed); } } @@ -1268,7 +1243,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() : Options(), m_filename(), m_line_num(0) {} + CommandOptions() : Options(), m_filename() {} ~CommandOptions() override = default; @@ -1305,7 +1280,7 @@ public: // Instance variables to hold the values for command options. std::string m_filename; - uint32_t m_line_num; + uint32_t m_line_num = 0; }; protected: @@ -1330,7 +1305,6 @@ protected: // Early return if there's no breakpoint at all. if (num_breakpoints == 0) { result.AppendError("Breakpoint clear: No breakpoint cleared."); - result.SetStatus(eReturnStatusFailed); return result.Succeeded(); } @@ -1377,7 +1351,6 @@ protected: result.SetStatus(eReturnStatusSuccessFinishNoResult); } else { result.AppendError("Breakpoint clear: No breakpoint cleared."); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); @@ -1423,8 +1396,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() : Options(), m_use_dummy(false), m_force(false), - m_delete_disabled(false) {} + CommandOptions() : Options() {} ~CommandOptions() override = default; @@ -1464,9 +1436,9 @@ public: } // Instance variables to hold the values for command options. - bool m_use_dummy; - bool m_force; - bool m_delete_disabled; + bool m_use_dummy = false; + bool m_force = false; + bool m_delete_disabled = false; }; protected: @@ -1483,10 +1455,10 @@ protected: if (num_breakpoints == 0) { result.AppendError("No breakpoints exist to be deleted."); - result.SetStatus(eReturnStatusFailed); return false; } + // Handle the delete all breakpoints case: if (command.empty() && !m_options.m_delete_disabled) { if (!m_options.m_force && !m_interpreter.Confirm( @@ -1500,68 +1472,73 @@ protected: (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : ""); } result.SetStatus(eReturnStatusSuccessFinishNoResult); - } else { - // Particular breakpoint selected; disable that breakpoint. - BreakpointIDList valid_bp_ids; - - if (m_options.m_delete_disabled) { - BreakpointIDList excluded_bp_ids; + return result.Succeeded(); + } + + // Either we have some kind of breakpoint specification(s), + // or we are handling "break disable --deleted". Gather the list + // of breakpoints to delete here, the we'll delete them below. + BreakpointIDList valid_bp_ids; + + if (m_options.m_delete_disabled) { + BreakpointIDList excluded_bp_ids; - if (!command.empty()) { - CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( - command, &target, result, &excluded_bp_ids, - BreakpointName::Permissions::PermissionKinds::deletePerm); - } - for (auto breakpoint_sp : breakpoints.Breakpoints()) { - if (!breakpoint_sp->IsEnabled() && breakpoint_sp->AllowDelete()) { - BreakpointID bp_id(breakpoint_sp->GetID()); - size_t pos = 0; - if (!excluded_bp_ids.FindBreakpointID(bp_id, &pos)) - valid_bp_ids.AddBreakpointID(breakpoint_sp->GetID()); - } - } - if (valid_bp_ids.GetSize() == 0) { - result.AppendError("No disabled breakpoints."); - result.SetStatus(eReturnStatusFailed); - return false; - } - } else { + if (!command.empty()) { CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( - command, &target, result, &valid_bp_ids, + command, &target, result, &excluded_bp_ids, BreakpointName::Permissions::PermissionKinds::deletePerm); + if (!result.Succeeded()) + return false; } - - if (result.Succeeded()) { - int delete_count = 0; - int disable_count = 0; - const size_t count = valid_bp_ids.GetSize(); - for (size_t i = 0; i < count; ++i) { - BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i); - if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) { - if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) { - Breakpoint *breakpoint = - target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); - BreakpointLocation *location = - breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get(); - // It makes no sense to try to delete individual locations, so we - // disable them instead. - if (location) { - location->SetEnabled(false); - ++disable_count; - } - } else { - target.RemoveBreakpointByID(cur_bp_id.GetBreakpointID()); - ++delete_count; - } + for (auto breakpoint_sp : breakpoints.Breakpoints()) { + if (!breakpoint_sp->IsEnabled() && breakpoint_sp->AllowDelete()) { + BreakpointID bp_id(breakpoint_sp->GetID()); + size_t pos = 0; + if (!excluded_bp_ids.FindBreakpointID(bp_id, &pos)) + valid_bp_ids.AddBreakpointID(breakpoint_sp->GetID()); + } + } + if (valid_bp_ids.GetSize() == 0) { + result.AppendError("No disabled breakpoints."); + return false; + } + } else { + CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( + command, &target, result, &valid_bp_ids, + BreakpointName::Permissions::PermissionKinds::deletePerm); + if (!result.Succeeded()) + return false; + } + + int delete_count = 0; + int disable_count = 0; + const size_t count = valid_bp_ids.GetSize(); + for (size_t i = 0; i < count; ++i) { + BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i); + + if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) { + if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) { + Breakpoint *breakpoint = + target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); + BreakpointLocation *location = + breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get(); + // It makes no sense to try to delete individual locations, so we + // disable them instead. + if (location) { + location->SetEnabled(false); + ++disable_count; } + } else { + target.RemoveBreakpointByID(cur_bp_id.GetBreakpointID()); + ++delete_count; } - result.AppendMessageWithFormat( - "%d breakpoints deleted; %d breakpoint locations disabled.\n", - delete_count, disable_count); - result.SetStatus(eReturnStatusSuccessFinishNoResult); } } + result.AppendMessageWithFormat( + "%d breakpoints deleted; %d breakpoint locations disabled.\n", + delete_count, disable_count); + result.SetStatus(eReturnStatusSuccessFinishNoResult); return result.Succeeded(); } @@ -1736,7 +1713,6 @@ protected: const size_t argc = command.GetArgumentCount(); if (argc == 0) { result.AppendError("No names provided."); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1751,7 +1727,6 @@ protected: if (!BreakpointID::StringIsBreakpointName(entry.ref(), error)) { result.AppendErrorWithFormat("Invalid breakpoint name: %s - %s", entry.c_str(), error.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -1764,7 +1739,6 @@ protected: if (!bp_sp) { result.AppendErrorWithFormatv("Could not find specified breakpoint {0}", bp_id); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -1779,7 +1753,7 @@ protected: bp_name->SetHelp(m_bp_id.m_help_string.GetStringValue().str().c_str()); if (bp_sp) - target.ConfigureBreakpointName(*bp_name, *bp_sp->GetOptions(), + target.ConfigureBreakpointName(*bp_name, bp_sp->GetOptions(), m_access_options.GetPermissions()); else target.ConfigureBreakpointName(*bp_name, @@ -1831,7 +1805,7 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { if (!m_name_options.m_name.OptionWasSet()) { - result.SetError("No name option provided."); + result.AppendError("No name option provided."); return false; } @@ -1845,8 +1819,7 @@ protected: size_t num_breakpoints = breakpoints.GetSize(); if (num_breakpoints == 0) { - result.SetError("No breakpoints, cannot add names."); - result.SetStatus(eReturnStatusFailed); + result.AppendError("No breakpoints, cannot add names."); return false; } @@ -1858,8 +1831,7 @@ protected: if (result.Succeeded()) { if (valid_bp_ids.GetSize() == 0) { - result.SetError("No breakpoints specified, cannot add names."); - result.SetStatus(eReturnStatusFailed); + result.AppendError("No breakpoints specified, cannot add names."); return false; } size_t num_valid_ids = valid_bp_ids.GetSize(); @@ -1918,7 +1890,7 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { if (!m_name_options.m_name.OptionWasSet()) { - result.SetError("No name option provided."); + result.AppendError("No name option provided."); return false; } @@ -1932,8 +1904,7 @@ protected: size_t num_breakpoints = breakpoints.GetSize(); if (num_breakpoints == 0) { - result.SetError("No breakpoints, cannot delete names."); - result.SetStatus(eReturnStatusFailed); + result.AppendError("No breakpoints, cannot delete names."); return false; } @@ -1945,8 +1916,7 @@ protected: if (result.Succeeded()) { if (valid_bp_ids.GetSize() == 0) { - result.SetError("No breakpoints specified, cannot delete names."); - result.SetStatus(eReturnStatusFailed); + result.AppendError("No breakpoints specified, cannot delete names."); return false; } ConstString bp_name(m_name_options.m_name.GetCurrentValue()); @@ -2222,7 +2192,6 @@ protected: if (!error.Success()) { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -2351,7 +2320,6 @@ protected: if (!error.Success()) { result.AppendErrorWithFormat("error serializing breakpoints: %s.", error.AsCString()); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -2444,7 +2412,6 @@ void CommandObjectMultiwordBreakpoint::VerifyIDs( } else { result.AppendError( "No breakpoint specified and no last created breakpoint."); - result.SetStatus(eReturnStatusFailed); } return; } @@ -2486,14 +2453,12 @@ void CommandObjectMultiwordBreakpoint::VerifyIDs( result.AppendErrorWithFormat( "'%s' is not a currently valid breakpoint/location id.\n", id_str.GetData()); - result.SetStatus(eReturnStatusFailed); } } else { i = valid_ids->GetSize() + 1; result.AppendErrorWithFormat( "'%d' is not a currently valid breakpoint ID.\n", cur_bp_id.GetBreakpointID()); - result.SetStatus(eReturnStatusFailed); } } } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpointCommand.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpointCommand.cpp index caaf3bfb482f..26d35c82f57d 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpointCommand.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpointCommand.cpp @@ -61,7 +61,9 @@ public: CommandObjectBreakpointCommandAdd(CommandInterpreter &interpreter) : CommandObjectParsed(interpreter, "add", "Add LLDB commands to a breakpoint, to be executed " - "whenever the breakpoint is hit." + "whenever the breakpoint is hit. " + "The commands added to the breakpoint replace any " + "commands previously added to it." " If no breakpoint is specified, adds the " "commands to the last created breakpoint.", nullptr), @@ -117,14 +119,22 @@ to supply the function name prepended by the module name:" --python-function myutils.breakpoint_callback -The function itself must have the following prototype: +The function itself must have either of the following prototypes: -def breakpoint_callback(frame, bp_loc, dict): +def breakpoint_callback(frame, bp_loc, internal_dict): + # Your code goes here + +or: + +def breakpoint_callback(frame, bp_loc, extra_args, internal_dict): # Your code goes here )" "The arguments are the same as the arguments passed to generated functions as \ -described above. Note that the global variable 'lldb.frame' will NOT be updated when \ +described above. In the second form, any -k and -v pairs provided to the command will \ +be packaged into a SBDictionary in an SBStructuredData and passed as the extra_args parameter. \ +\n\n\ +Note that the global variable 'lldb.frame' will NOT be updated when \ this function is called, so be sure to use the 'frame' argument. The 'frame' argument \ can get you to the thread via frame.GetThread(), the thread can get you to the \ process via thread.GetProcess(), and the process can get you back to the target \ @@ -235,20 +245,18 @@ are no syntax errors may indicate that a function was declared but never called. std::string &line) override { io_handler.SetIsDone(true); - std::vector<BreakpointOptions *> *bp_options_vec = - (std::vector<BreakpointOptions *> *)io_handler.GetUserData(); - for (BreakpointOptions *bp_options : *bp_options_vec) { - if (!bp_options) - continue; - + std::vector<std::reference_wrapper<BreakpointOptions>> *bp_options_vec = + (std::vector<std::reference_wrapper<BreakpointOptions>> *) + io_handler.GetUserData(); + for (BreakpointOptions &bp_options : *bp_options_vec) { auto cmd_data = std::make_unique<BreakpointOptions::CommandData>(); cmd_data->user_source.SplitIntoLines(line.c_str(), line.size()); - bp_options->SetCommandDataCallback(cmd_data); + bp_options.SetCommandDataCallback(cmd_data); } } void CollectDataForBreakpointCommandCallback( - std::vector<BreakpointOptions *> &bp_options_vec, + std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec, CommandReturnObject &result) { m_interpreter.GetLLDBCommandsFromIOHandler( "> ", // Prompt @@ -258,25 +266,22 @@ are no syntax errors may indicate that a function was declared but never called. } /// Set a one-liner as the callback for the breakpoint. - void - SetBreakpointCommandCallback(std::vector<BreakpointOptions *> &bp_options_vec, - const char *oneliner) { - for (auto bp_options : bp_options_vec) { + void SetBreakpointCommandCallback( + std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec, + const char *oneliner) { + for (BreakpointOptions &bp_options : bp_options_vec) { auto cmd_data = std::make_unique<BreakpointOptions::CommandData>(); cmd_data->user_source.AppendString(oneliner); cmd_data->stop_on_error = m_options.m_stop_on_error; - bp_options->SetCommandDataCallback(cmd_data); + bp_options.SetCommandDataCallback(cmd_data); } } class CommandOptions : public OptionGroup { public: - CommandOptions() - : OptionGroup(), m_use_commands(false), m_use_script_language(false), - m_script_language(eScriptLanguageNone), m_use_one_liner(false), - m_one_liner() {} + CommandOptions() : OptionGroup(), m_one_liner() {} ~CommandOptions() override = default; @@ -346,12 +351,12 @@ are no syntax errors may indicate that a function was declared but never called. // Instance variables to hold the values for command options. - bool m_use_commands; - bool m_use_script_language; - lldb::ScriptLanguage m_script_language; + bool m_use_commands = false; + bool m_use_script_language = false; + lldb::ScriptLanguage m_script_language = eScriptLanguageNone; // Instance variables to hold the values for one_liner options. - bool m_use_one_liner; + bool m_use_one_liner = false; std::string m_one_liner; bool m_stop_on_error; bool m_use_dummy; @@ -366,7 +371,6 @@ protected: if (num_breakpoints == 0) { result.AppendError("No breakpoints exist to have commands added"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -393,20 +397,17 @@ protected: if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) { Breakpoint *bp = target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); - BreakpointOptions *bp_options = nullptr; if (cur_bp_id.GetLocationID() == LLDB_INVALID_BREAK_ID) { // This breakpoint does not have an associated location. - bp_options = bp->GetOptions(); + m_bp_options_vec.push_back(bp->GetOptions()); } else { BreakpointLocationSP bp_loc_sp( bp->FindLocationByID(cur_bp_id.GetLocationID())); // This breakpoint does have an associated location. Get its // breakpoint options. if (bp_loc_sp) - bp_options = bp_loc_sp->GetLocationOptions(); + m_bp_options_vec.push_back(bp_loc_sp->GetLocationOptions()); } - if (bp_options) - m_bp_options_vec.push_back(bp_options); } } @@ -449,9 +450,10 @@ private: OptionGroupPythonClassWithDict m_func_options; OptionGroupOptions m_all_options; - std::vector<BreakpointOptions *> m_bp_options_vec; // This stores the - // breakpoint options that - // we are currently + std::vector<std::reference_wrapper<BreakpointOptions>> + m_bp_options_vec; // This stores the + // breakpoint options that + // we are currently // collecting commands for. In the CollectData... calls we need to hand this // off to the IOHandler, which may run asynchronously. So we have to have // some way to keep it alive, and not leak it. Making it an ivar of the @@ -500,7 +502,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() : Options(), m_use_dummy(false) {} + CommandOptions() : Options() {} ~CommandOptions() override = default; @@ -530,7 +532,7 @@ public: } // Instance variables to hold the values for command options. - bool m_use_dummy; + bool m_use_dummy = false; }; protected: @@ -542,14 +544,12 @@ protected: if (num_breakpoints == 0) { result.AppendError("No breakpoints exist to have commands deleted"); - result.SetStatus(eReturnStatusFailed); return false; } if (command.empty()) { result.AppendError( "No breakpoint specified from which to delete the commands"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -574,7 +574,6 @@ protected: result.AppendErrorWithFormat("Invalid breakpoint ID: %u.%u.\n", cur_bp_id.GetBreakpointID(), cur_bp_id.GetLocationID()); - result.SetStatus(eReturnStatusFailed); return false; } } else { @@ -625,14 +624,12 @@ protected: if (num_breakpoints == 0) { result.AppendError("No breakpoints exist for which to list commands"); - result.SetStatus(eReturnStatusFailed); return false; } if (command.empty()) { result.AppendError( "No breakpoint specified for which to list the commands"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -657,7 +654,6 @@ protected: result.AppendErrorWithFormat("Invalid breakpoint ID: %u.%u.\n", cur_bp_id.GetBreakpointID(), cur_bp_id.GetLocationID()); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -671,9 +667,9 @@ protected: baton = bp_loc_sp ->GetOptionsSpecifyingKind(BreakpointOptions::eCallback) - ->GetBaton(); + .GetBaton(); else - baton = bp->GetOptions()->GetBaton(); + baton = bp->GetOptions().GetBaton(); if (baton) { result.GetOutputStream().Printf("Breakpoint %s:\n", @@ -692,7 +688,6 @@ protected: } else { result.AppendErrorWithFormat("Invalid breakpoint ID: %u.\n", cur_bp_id.GetBreakpointID()); - result.SetStatus(eReturnStatusFailed); } } } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.cpp index 3b3cdde6ab9a..9a8b81c007ad 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.cpp @@ -128,21 +128,17 @@ protected: result.AppendErrorWithFormat( "'%s' takes exactly one executable filename argument.\n", GetCommandName().str().c_str()); - result.SetStatus(eReturnStatusFailed); return false; } FileSpec cmd_file(command[0].ref()); FileSystem::Instance().Resolve(cmd_file); - ExecutionContext *exe_ctx = nullptr; // Just use the default context. + CommandInterpreterRunOptions options; // If any options were set, then use them if (m_options.m_stop_on_error.OptionWasSet() || m_options.m_silent_run.OptionWasSet() || m_options.m_stop_on_continue.OptionWasSet()) { - // Use user set settings - CommandInterpreterRunOptions options; - if (m_options.m_stop_on_continue.OptionWasSet()) options.SetStopOnContinue( m_options.m_stop_on_continue.GetCurrentValue()); @@ -159,14 +155,9 @@ protected: options.SetEchoCommands(m_interpreter.GetEchoCommands()); options.SetEchoCommentCommands(m_interpreter.GetEchoCommentCommands()); } - - m_interpreter.HandleCommandsFromFile(cmd_file, exe_ctx, options, result); - } else { - // No options were set, inherit any settings from nested "command source" - // commands, or set to sane default settings... - CommandInterpreterRunOptions options; - m_interpreter.HandleCommandsFromFile(cmd_file, exe_ctx, options, result); } + + m_interpreter.HandleCommandsFromFile(cmd_file, options, result); return result.Succeeded(); } @@ -388,7 +379,6 @@ protected: if (args.GetArgumentCount() < 2) { result.AppendError("'command alias' requires at least two arguments"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -401,7 +391,6 @@ protected: result.AppendWarning("if trying to pass options to 'command alias' add " "a -- at the end of the options"); } - result.SetStatus(eReturnStatusFailed); return false; } @@ -415,7 +404,6 @@ protected: raw_command_string = raw_command_string.substr(pos); } else { result.AppendError("Error parsing command string. No alias created."); - result.SetStatus(eReturnStatusFailed); return false; } @@ -424,7 +412,6 @@ protected: result.AppendErrorWithFormat( "'%s' is a permanent debugger command and cannot be redefined.\n", args[0].c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -440,7 +427,6 @@ protected: "'%s' does not begin with a valid command." " No alias created.", original_raw_command_string.str().c_str()); - result.SetStatus(eReturnStatusFailed); return false; } else if (!cmd_obj->WantsRawCommandString()) { // Note that args was initialized with the original command, and has not @@ -480,12 +466,10 @@ protected: result.SetStatus(eReturnStatusSuccessFinishNoResult); } else { result.AppendError("Unable to create requested alias.\n"); - result.SetStatus(eReturnStatusFailed); } } else { result.AppendError("Unable to create requested alias.\n"); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); @@ -496,7 +480,6 @@ protected: if (argc < 2) { result.AppendError("'command alias' requires at least two arguments"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -514,7 +497,6 @@ protected: result.AppendErrorWithFormat( "'%s' is a permanent debugger command and cannot be redefined.\n", alias_command.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -525,7 +507,6 @@ protected: if (!command_obj_sp) { result.AppendErrorWithFormat("'%s' is not an existing command.\n", actual_command.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } CommandObject *cmd_obj = command_obj_sp.get(); @@ -542,7 +523,6 @@ protected: "'%s' is not a valid sub-command of '%s'. " "Unable to create alias.\n", args[0].c_str(), actual_command.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -581,7 +561,6 @@ protected: result.SetStatus(eReturnStatusSuccessFinishNoResult); } else { result.AppendError("Unable to create requested alias.\n"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -634,7 +613,6 @@ protected: if (args.empty()) { result.AppendError("must call 'unalias' with a valid alias"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -645,7 +623,6 @@ protected: "'%s' is not a known command.\nTry 'help' to see a " "current list of commands.\n", args[0].c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -660,7 +637,6 @@ protected: "'%s' is a permanent debugger command and cannot be removed.\n", args[0].c_str()); } - result.SetStatus(eReturnStatusFailed); return false; } @@ -672,7 +648,6 @@ protected: else result.AppendErrorWithFormat("'%s' is not an existing alias.\n", args[0].c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -728,7 +703,6 @@ protected: result.AppendErrorWithFormat("must call '%s' with one or more valid user " "defined regular expression command names", GetCommandName().str().c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -741,7 +715,6 @@ protected: &error_msg_stream, command_name, llvm::StringRef(), llvm::StringRef(), generate_upropos, generate_type_lookup); result.AppendError(error_msg_stream.GetString()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -749,7 +722,6 @@ protected: result.AppendErrorWithFormat( "'%s' is a permanent debugger command and cannot be removed.\n", args[0].c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -854,7 +826,6 @@ protected: if (argc == 0) { result.AppendError("usage: 'command regex <command-name> " "[s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -895,7 +866,6 @@ protected: } if (error.Fail()) { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); @@ -1111,7 +1081,6 @@ protected: m_function_name.c_str(), raw_command_line, m_synchro, result, error, m_exe_ctx)) { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); } else { // Don't change the status if the command already set it... if (result.GetStatus() == eReturnStatusInvalid) { @@ -1197,7 +1166,6 @@ protected: !scripter->RunScriptBasedCommand(m_cmd_obj_sp, raw_command_line, m_synchro, result, error, m_exe_ctx)) { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); } else { // Don't change the status if the command already set it... if (result.GetStatus() == eReturnStatusInvalid) { @@ -1274,6 +1242,9 @@ protected: case 'c': relative_to_command_file = true; break; + case 's': + silent = true; + break; default: llvm_unreachable("Unimplemented option"); } @@ -1289,12 +1260,12 @@ protected: return llvm::makeArrayRef(g_script_import_options); } bool relative_to_command_file = false; + bool silent = false; }; bool DoExecute(Args &command, CommandReturnObject &result) override { if (command.empty()) { result.AppendError("command script import needs one or more arguments"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1304,7 +1275,6 @@ protected: if (!source_dir) { result.AppendError("command script import -c can only be specified " "from a command file"); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -1312,7 +1282,10 @@ protected: for (auto &entry : command.entries()) { Status error; - const bool init_session = true; + LoadScriptOptions options; + options.SetInitSession(true); + options.SetSilent(m_options.silent); + // FIXME: this is necessary because CommandObject::CheckRequirements() // assumes that commands won't ever be recursively invoked, but it's // actually possible to craft a Python script that does other "command @@ -1323,12 +1296,12 @@ protected: // more) m_exe_ctx.Clear(); if (GetDebugger().GetScriptInterpreter()->LoadScriptingModule( - entry.c_str(), init_session, error, nullptr, source_dir)) { + entry.c_str(), options, error, /*module_sp=*/nullptr, + source_dir)) { result.SetStatus(eReturnStatusSuccessFinishNoResult); } else { result.AppendErrorWithFormat("module importing failed: %s", error.AsCString()); - result.SetStatus(eReturnStatusFailed); } } @@ -1395,8 +1368,7 @@ protected: class CommandOptions : public Options { public: CommandOptions() - : Options(), m_class_name(), m_funct_name(), m_short_help(), - m_synchronicity(eScriptedCommandSynchronicitySynchronous) {} + : Options(), m_class_name(), m_funct_name(), m_short_help() {} ~CommandOptions() override = default; @@ -1450,7 +1422,8 @@ protected: std::string m_class_name; std::string m_funct_name; std::string m_short_help; - ScriptedCommandSynchronicity m_synchronicity; + ScriptedCommandSynchronicity m_synchronicity = + eScriptedCommandSynchronicitySynchronous; }; void IOHandlerActivated(IOHandler &io_handler, bool interactive) override { @@ -1513,13 +1486,11 @@ protected: if (GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) { result.AppendError("only scripting language supported for scripted " "commands is currently Python"); - result.SetStatus(eReturnStatusFailed); return false; } if (command.GetArgumentCount() != 1) { result.AppendError("'command script add' requires one argument"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1541,14 +1512,12 @@ protected: result.SetStatus(eReturnStatusSuccessFinishNoResult); } else { result.AppendError("cannot add command"); - result.SetStatus(eReturnStatusFailed); } } } else { ScriptInterpreter *interpreter = GetDebugger().GetScriptInterpreter(); if (!interpreter) { result.AppendError("cannot find ScriptInterpreter"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1556,7 +1525,6 @@ protected: m_options.m_class_name.c_str()); if (!cmd_obj_sp) { result.AppendError("cannot create helper object"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1566,7 +1534,6 @@ protected: result.SetStatus(eReturnStatusSuccessFinishNoResult); } else { result.AppendError("cannot add command"); - result.SetStatus(eReturnStatusFailed); } } @@ -1592,7 +1559,6 @@ public: bool DoExecute(Args &command, CommandReturnObject &result) override { if (command.GetArgumentCount() != 0) { result.AppendError("'command script list' doesn't take any arguments"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1618,7 +1584,6 @@ protected: bool DoExecute(Args &command, CommandReturnObject &result) override { if (command.GetArgumentCount() != 0) { result.AppendError("'command script clear' doesn't take any arguments"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1669,7 +1634,6 @@ protected: if (command.GetArgumentCount() != 1) { result.AppendError("'command script delete' requires one argument"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1678,7 +1642,6 @@ protected: if (cmd_name.empty() || !m_interpreter.HasUserCommands() || !m_interpreter.UserCommandExists(cmd_name)) { result.AppendErrorWithFormat("command %s not found", command[0].c_str()); - result.SetStatus(eReturnStatusFailed); return false; } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectDisassemble.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectDisassemble.cpp index cf4d8ed04f81..5e73fb8218ab 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectDisassemble.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectDisassemble.cpp @@ -23,7 +23,6 @@ static constexpr unsigned default_disasm_byte_size = 32; static constexpr unsigned default_disasm_num_ins = 4; -static constexpr unsigned large_function_threshold = 8000; using namespace lldb; using namespace lldb_private; @@ -32,10 +31,7 @@ using namespace lldb_private; #include "CommandOptions.inc" CommandObjectDisassemble::CommandOptions::CommandOptions() - : Options(), num_lines_context(0), num_instructions(0), func_name(), - current_function(false), start_addr(), end_addr(), at_pc(false), - frame_line(false), plugin_name(), flavor_string(), arch(), - some_location_specified(false), symbol_containing_addr() { + : Options(), func_name(), plugin_name(), flavor_string(), arch() { OptionParsingStarting(nullptr); } @@ -223,7 +219,7 @@ CommandObjectDisassemble::~CommandObjectDisassemble() = default; llvm::Error CommandObjectDisassemble::CheckRangeSize(const AddressRange &range, llvm::StringRef what) { if (m_options.num_instructions > 0 || m_options.force || - range.GetByteSize() < large_function_threshold) + range.GetByteSize() < GetDebugger().GetStopDisassemblyMaxSize()) return llvm::Error::success(); StreamString msg; msg << "Not disassembling " << what << " because it is very large "; @@ -418,7 +414,6 @@ bool CommandObjectDisassemble::DoExecute(Args &command, if (!m_options.arch.IsValid()) { result.AppendError( "use the --arch option or set the target architecture to disassemble"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -438,7 +433,6 @@ bool CommandObjectDisassemble::DoExecute(Args &command, result.AppendErrorWithFormat( "Unable to find Disassembler plug-in for the '%s' architecture.\n", m_options.arch.GetArchitectureName()); - result.SetStatus(eReturnStatusFailed); return false; } else if (flavor_string != nullptr && !disassembler->FlavorValidForArchSpec( m_options.arch, flavor_string)) @@ -454,7 +448,6 @@ bool CommandObjectDisassemble::DoExecute(Args &command, GetCommandInterpreter().GetDebugger().GetTerminalWidth(); GetOptions()->GenerateOptionUsage(result.GetErrorStream(), this, terminal_width); - result.SetStatus(eReturnStatusFailed); return false; } @@ -479,7 +472,6 @@ bool CommandObjectDisassemble::DoExecute(Args &command, GetRangesForSelectedMode(result); if (!ranges) { result.AppendError(toString(ranges.takeError())); - result.SetStatus(eReturnStatusFailed); return result.Succeeded(); } @@ -509,7 +501,6 @@ bool CommandObjectDisassemble::DoExecute(Args &command, "Failed to disassemble memory at 0x%8.8" PRIx64 ".\n", cur_range.GetBaseAddress().GetLoadAddress(target)); } - result.SetStatus(eReturnStatusFailed); } if (print_sc_header) result.GetOutputStream() << "\n"; diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectDisassemble.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectDisassemble.h index 340bf648de17..a4b3df8724da 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectDisassemble.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectDisassemble.h @@ -46,22 +46,22 @@ public: bool show_mixed; // Show mixed source/assembly bool show_bytes; - uint32_t num_lines_context; - uint32_t num_instructions; + uint32_t num_lines_context = 0; + uint32_t num_instructions = 0; bool raw; std::string func_name; - bool current_function; - lldb::addr_t start_addr; - lldb::addr_t end_addr; - bool at_pc; - bool frame_line; + bool current_function = false; + lldb::addr_t start_addr = 0; + lldb::addr_t end_addr = 0; + bool at_pc = false; + bool frame_line = false; std::string plugin_name; std::string flavor_string; ArchSpec arch; - bool some_location_specified; // If no location was specified, we'll select - // "at_pc". This should be set + bool some_location_specified = false; // If no location was specified, we'll + // select "at_pc". This should be set // in SetOptionValue if anything the selects a location is set. - lldb::addr_t symbol_containing_addr; + lldb::addr_t symbol_containing_addr = 0; bool force = false; }; diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.cpp index 58eaa3f973cb..bf62f3f297cc 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.cpp @@ -292,18 +292,12 @@ void CommandObjectExpression::HandleCompletion(CompletionRequest &request) { options.SetAutoApplyFixIts(false); options.SetGenerateDebugInfo(false); - // We need a valid execution context with a frame pointer for this - // completion, so if we don't have one we should try to make a valid - // execution context. - if (m_interpreter.GetExecutionContext().GetFramePtr() == nullptr) - m_interpreter.UpdateExecutionContext(nullptr); - - // This didn't work, so let's get out before we start doing things that - // expect a valid frame pointer. - if (m_interpreter.GetExecutionContext().GetFramePtr() == nullptr) + ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); + + // Get out before we start doing things that expect a valid frame pointer. + if (exe_ctx.GetFramePtr() == nullptr) return; - ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); Target *exe_target = exe_ctx.GetTargetPtr(); Target &target = exe_target ? *exe_target : GetDummyTarget(); @@ -414,6 +408,12 @@ bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr, lldb::ValueObjectSP result_valobj_sp; StackFrame *frame = exe_ctx.GetFramePtr(); + if (m_command_options.top_level && !m_command_options.allow_jit) { + result.AppendErrorWithFormat( + "Can't disable JIT compilation for top-level expressions.\n"); + return false; + } + const EvaluateExpressionOptions options = GetEvalOptions(target); ExpressionResults success = target.EvaluateExpression( expr, frame, result_valobj_sp, options, &m_fixed_expression); @@ -440,7 +440,6 @@ bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr, result.AppendErrorWithFormat( "expression cannot be used with --element-count %s\n", error.AsCString("")); - result.SetStatus(eReturnStatusFailed); return false; } } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.cpp index a656a99a1c71..d90e357bf1aa 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.cpp @@ -141,7 +141,6 @@ protected: if (m_options.reg.hasValue() || m_options.offset.hasValue()) { result.AppendError( "`frame diagnose --address` is incompatible with other arguments."); - result.SetStatus(eReturnStatusFailed); return false; } valobj_sp = frame_sp->GuessValueForAddress(m_options.address.getValue()); @@ -152,7 +151,6 @@ protected: StopInfoSP stop_info_sp = thread->GetStopInfo(); if (!stop_info_sp) { result.AppendError("No arguments provided, and no stop info."); - result.SetStatus(eReturnStatusFailed); return false; } @@ -161,7 +159,6 @@ protected: if (!valobj_sp) { result.AppendError("No diagnosis available."); - result.SetStatus(eReturnStatusFailed); return false; } @@ -323,7 +320,6 @@ protected: // If you are already at the bottom of the stack, then just warn // and don't reset the frame. result.AppendError("Already at the bottom of the stack."); - result.SetStatus(eReturnStatusFailed); return false; } else frame_idx = 0; @@ -342,7 +338,6 @@ protected: // If we are already at the top of the stack, just warn and don't // reset the frame. result.AppendError("Already at the top of the stack."); - result.SetStatus(eReturnStatusFailed); return false; } else frame_idx = num_frames - 1; @@ -363,7 +358,6 @@ protected: if (command[0].ref().getAsInteger(0, frame_idx)) { result.AppendErrorWithFormat("invalid frame index argument '%s'.", command[0].c_str()); - result.SetStatus(eReturnStatusFailed); return false; } } else if (command.GetArgumentCount() == 0) { @@ -382,7 +376,6 @@ protected: } else { result.AppendErrorWithFormat("Frame index (%u) out of range.\n", frame_idx); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); @@ -460,7 +453,7 @@ public: protected: llvm::StringRef GetScopeString(VariableSP var_sp) { if (!var_sp) - return llvm::StringRef::withNullAsEmpty(nullptr); + return llvm::StringRef(); switch (var_sp->GetScope()) { case eValueTypeVariableGlobal: @@ -477,7 +470,7 @@ protected: break; } - return llvm::StringRef::withNullAsEmpty(nullptr); + return llvm::StringRef(); } bool DoExecute(Args &command, CommandReturnObject &result) override { @@ -850,14 +843,12 @@ bool CommandObjectFrameRecognizerAdd::DoExecute(Args &command, if (m_options.m_class_name.empty()) { result.AppendErrorWithFormat( "%s needs a Python class name (-l argument).\n", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } if (m_options.m_module.empty()) { result.AppendErrorWithFormat("%s needs a module name (-s argument).\n", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -865,7 +856,6 @@ bool CommandObjectFrameRecognizerAdd::DoExecute(Args &command, result.AppendErrorWithFormat( "%s needs at least one symbol name (-n argument).\n", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -873,7 +863,6 @@ bool CommandObjectFrameRecognizerAdd::DoExecute(Args &command, result.AppendErrorWithFormat( "%s needs only one symbol regular expression (-n argument).\n", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -968,7 +957,6 @@ protected: "About to delete all frame recognizers, do you want to do that?", true)) { result.AppendMessage("Operation cancelled..."); - result.SetStatus(eReturnStatusFailed); return false; } @@ -982,7 +970,6 @@ protected: if (command.GetArgumentCount() != 1) { result.AppendErrorWithFormat("'%s' takes zero or one arguments.\n", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -990,7 +977,6 @@ protected: if (!llvm::to_integer(command.GetArgumentAtIndex(0), recognizer_id)) { result.AppendErrorWithFormat("'%s' is not a valid recognizer id.\n", command.GetArgumentAtIndex(0)); - result.SetStatus(eReturnStatusFailed); return false; } @@ -999,7 +985,6 @@ protected: .RemoveRecognizerWithID(recognizer_id)) { result.AppendErrorWithFormat("'%s' is not a valid recognizer id.\n", command.GetArgumentAtIndex(0)); - result.SetStatus(eReturnStatusFailed); return false; } result.SetStatus(eReturnStatusSuccessFinishResult); @@ -1084,33 +1069,28 @@ protected: if (!llvm::to_integer(frame_index_str, frame_index)) { result.AppendErrorWithFormat("'%s' is not a valid frame index.", frame_index_str); - result.SetStatus(eReturnStatusFailed); return false; } Process *process = m_exe_ctx.GetProcessPtr(); if (process == nullptr) { result.AppendError("no process"); - result.SetStatus(eReturnStatusFailed); return false; } Thread *thread = m_exe_ctx.GetThreadPtr(); if (thread == nullptr) { result.AppendError("no thread"); - result.SetStatus(eReturnStatusFailed); return false; } if (command.GetArgumentCount() != 1) { result.AppendErrorWithFormat( "'%s' takes exactly one frame index argument.\n", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } StackFrameSP frame_sp = thread->GetStackFrameAtIndex(frame_index); if (!frame_sp) { result.AppendErrorWithFormat("no frame with index %u", frame_index); - result.SetStatus(eReturnStatusFailed); return false; } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectGUI.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectGUI.cpp index 3f45a26de228..86c47a2f0634 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectGUI.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectGUI.cpp @@ -22,7 +22,7 @@ CommandObjectGUI::CommandObjectGUI(CommandInterpreter &interpreter) : CommandObjectParsed(interpreter, "gui", "Switch into the curses based GUI mode.", "gui") {} -CommandObjectGUI::~CommandObjectGUI() {} +CommandObjectGUI::~CommandObjectGUI() = default; bool CommandObjectGUI::DoExecute(Args &args, CommandReturnObject &result) { #if LLDB_ENABLE_CURSES @@ -39,11 +39,9 @@ bool CommandObjectGUI::DoExecute(Args &args, CommandReturnObject &result) { result.SetStatus(eReturnStatusSuccessFinishResult); } else { result.AppendError("the gui command requires an interactive terminal."); - result.SetStatus(eReturnStatusFailed); } } else { result.AppendError("the gui command takes no arguments."); - result.SetStatus(eReturnStatusFailed); } return true; #else diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectHelp.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectHelp.cpp index 6dc1868a2aff..4643ee30f0f9 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectHelp.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectHelp.cpp @@ -139,7 +139,6 @@ bool CommandObjectHelp::DoExecute(Args &command, CommandReturnObject &result) { } s.Printf("\n"); result.AppendError(s.GetString()); - result.SetStatus(eReturnStatusFailed); return false; } else if (!sub_cmd_obj) { StreamString error_msg_stream; @@ -147,7 +146,6 @@ bool CommandObjectHelp::DoExecute(Args &command, CommandReturnObject &result) { &error_msg_stream, cmd_string.c_str(), m_interpreter.GetCommandPrefix(), sub_command.c_str()); result.AppendError(error_msg_stream.GetString()); - result.SetStatus(eReturnStatusFailed); return false; } else { GenerateAdditionalHelpAvenuesMessage( @@ -193,7 +191,6 @@ bool CommandObjectHelp::DoExecute(Args &command, CommandReturnObject &result) { m_interpreter.GetCommandPrefix(), ""); result.AppendError(error_msg_stream.GetString()); - result.SetStatus(eReturnStatusFailed); } } } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectHelp.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectHelp.h index 8f45db55666e..c924dda7c6d4 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectHelp.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectHelp.h @@ -34,7 +34,7 @@ public: public: CommandOptions() : Options() {} - ~CommandOptions() override {} + ~CommandOptions() override = default; Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override { diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectLanguage.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectLanguage.cpp index e6d22ec4ae40..925db599e4ab 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectLanguage.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectLanguage.cpp @@ -23,4 +23,4 @@ CommandObjectLanguage::CommandObjectLanguage(CommandInterpreter &interpreter) LanguageRuntime::InitializeCommands(this); } -CommandObjectLanguage::~CommandObjectLanguage() {} +CommandObjectLanguage::~CommandObjectLanguage() = default; diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectLog.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectLog.cpp index 4016b07c91ed..05ffba27e65f 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectLog.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectLog.cpp @@ -76,7 +76,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() : Options(), log_file(), log_options(0) {} + CommandOptions() : Options(), log_file() {} ~CommandOptions() override = default; @@ -136,7 +136,7 @@ public: // Instance variables to hold the values for command options. FileSpec log_file; - uint32_t log_options; + uint32_t log_options = 0; }; void @@ -151,7 +151,6 @@ protected: result.AppendErrorWithFormat( "%s takes a log channel and one or more log types.\n", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -225,7 +224,6 @@ protected: result.AppendErrorWithFormat( "%s takes a log channel and one or more log types.\n", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp index 7d5c642d0131..5487d94c9019 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "CommandObjectMemory.h" +#include "CommandObjectMemoryTag.h" #include "lldb/Core/DumpDataExtractor.h" #include "lldb/Core/Section.h" #include "lldb/Core/ValueObjectMemory.h" @@ -46,8 +47,8 @@ using namespace lldb_private; class OptionGroupReadMemory : public OptionGroup { public: OptionGroupReadMemory() - : m_num_per_line(1, 1), m_output_as_binary(false), m_view_as_type(), - m_offset(0, 0), m_language_for_type(eLanguageTypeUnknown) {} + : m_num_per_line(1, 1), m_view_as_type(), m_offset(0, 0), + m_language_for_type(eLanguageTypeUnknown) {} ~OptionGroupReadMemory() override = default; @@ -270,7 +271,7 @@ public: } OptionValueUInt64 m_num_per_line; - bool m_output_as_binary; + bool m_output_as_binary = false; OptionValueString m_view_as_type; bool m_force; OptionValueUInt64 m_offset; @@ -356,9 +357,8 @@ protected: result.AppendErrorWithFormat("%s takes a start address expression with " "an optional end address expression.\n", m_cmd_name.c_str()); - result.AppendRawWarning("Expressions should be quoted if they contain " - "spaces or other special characters.\n"); - result.SetStatus(eReturnStatusFailed); + result.AppendWarning("Expressions should be quoted if they contain " + "spaces or other special characters."); return false; } @@ -439,7 +439,6 @@ protected: } else { result.AppendErrorWithFormat("invalid type string: '%s'\n", view_as_type_cstr); - result.SetStatus(eReturnStatusFailed); return false; } break; @@ -489,7 +488,6 @@ protected: "Mutiple types found matching raw type '%s', please disambiguate " "by specifying the language with -x", lookup_type_name.GetCString()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -504,7 +502,6 @@ protected: "the raw type '%s' for full type '%s'\n", lookup_type_name.GetCString(), view_as_type_cstr); - result.SetStatus(eReturnStatusFailed); return false; } else { TypeSP type_sp(type_list.GetTypeAtIndex(0)); @@ -518,7 +515,6 @@ protected: compiler_type = pointer_type; else { result.AppendError("unable make a pointer type\n"); - result.SetStatus(eReturnStatusFailed); return false; } --pointer_count; @@ -529,7 +525,6 @@ protected: result.AppendErrorWithFormat( "unable to get the byte size of the type '%s'\n", view_as_type_cstr); - result.SetStatus(eReturnStatusFailed); return false; } m_format_options.GetByteSizeValue() = *size; @@ -543,7 +538,6 @@ protected: // Look for invalid combinations of settings if (error.Fail()) { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -593,7 +587,6 @@ protected: if (addr == LLDB_INVALID_ADDRESS) { result.AppendError("invalid start address expression."); result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -603,21 +596,18 @@ protected: if (end_addr == LLDB_INVALID_ADDRESS) { result.AppendError("invalid end address expression."); result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } else if (end_addr <= addr) { result.AppendErrorWithFormat( "end address (0x%" PRIx64 - ") must be greater that the start address (0x%" PRIx64 ").\n", + ") must be greater than the start address (0x%" PRIx64 ").\n", end_addr, addr); - result.SetStatus(eReturnStatusFailed); return false; } else if (m_format_options.GetCountValue().OptionWasSet()) { result.AppendErrorWithFormat( "specify either the end address (0x%" PRIx64 ") or the count (--count %" PRIu64 "), not both.\n", end_addr, (uint64_t)item_count); - result.SetStatus(eReturnStatusFailed); return false; } @@ -664,13 +654,12 @@ protected: "can't allocate 0x%" PRIx32 " bytes for the memory read buffer, specify a smaller size to read", (uint32_t)total_byte_size); - result.SetStatus(eReturnStatusFailed); return false; } Address address(addr, nullptr); - bytes_read = target->ReadMemory(address, false, data_sp->GetBytes(), - data_sp->GetByteSize(), error); + bytes_read = target->ReadMemory(address, data_sp->GetBytes(), + data_sp->GetByteSize(), error, true); if (bytes_read == 0) { const char *error_cstr = error.AsCString(); if (error_cstr && error_cstr[0]) { @@ -679,7 +668,6 @@ protected: result.AppendErrorWithFormat( "failed to read memory from 0x%" PRIx64 ".\n", addr); } - result.SetStatus(eReturnStatusFailed); return false; } @@ -706,7 +694,6 @@ protected: "can't allocate 0x%" PRIx64 " bytes for the memory read buffer, specify a smaller size to read", (uint64_t)((item_byte_size + 1) * item_count)); - result.SetStatus(eReturnStatusFailed); return false; } uint8_t *data_ptr = data_sp->GetBytes(); @@ -723,7 +710,6 @@ protected: if (error.Fail()) { result.AppendErrorWithFormat( "failed to read memory from 0x%" PRIx64 ".\n", addr); - result.SetStatus(eReturnStatusFailed); return false; } @@ -767,10 +753,11 @@ protected: std::string path = outfile_spec.GetPath(); if (outfile_spec) { - auto open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate; + File::OpenOptions open_options = + File::eOpenOptionWrite | File::eOpenOptionCanCreate; const bool append = m_outfile_options.GetAppend().GetCurrentValue(); - if (append) - open_options |= File::eOpenOptionAppend; + open_options |= + append ? File::eOpenOptionAppend : File::eOpenOptionTruncate; auto outfile = FileSystem::Instance().Open(outfile_spec, open_options); @@ -789,7 +776,6 @@ protected: result.AppendErrorWithFormat("Failed to write %" PRIu64 " bytes to '%s'.\n", (uint64_t)bytes_read, path.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } } else { @@ -803,7 +789,6 @@ protected: path.c_str(), append ? "append" : "write"); result.AppendError(llvm::toString(outfile.takeError())); - result.SetStatus(eReturnStatusFailed); return false; } } else { @@ -832,7 +817,6 @@ protected: result.AppendErrorWithFormat( "failed to create a value object for: (%s) %s\n", view_as_type_cstr, name_strm.GetData()); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -862,7 +846,6 @@ protected: result.AppendErrorWithFormat( "reading memory as characters of size %" PRIu64 " is not supported", (uint64_t)item_byte_size); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -1293,14 +1276,12 @@ protected: result.AppendErrorWithFormat( "%s takes a destination address when writing file contents.\n", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } } else if (argc < 2) { result.AppendErrorWithFormat( "%s takes a destination address and at least one value.\n", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1319,7 +1300,6 @@ protected: if (addr == LLDB_INVALID_ADDRESS) { result.AppendError("invalid address expression\n"); result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1354,12 +1334,10 @@ protected: result.AppendErrorWithFormat("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString()); - result.SetStatus(eReturnStatusFailed); } } } else { result.AppendErrorWithFormat("Unable to read contents of file.\n"); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } else if (item_byte_size == 0) { @@ -1404,7 +1382,6 @@ protected: case eFormatInstruction: case eFormatVoid: result.AppendError("unsupported format for writing memory"); - result.SetStatus(eReturnStatusFailed); return false; case eFormatDefault: @@ -1423,14 +1400,12 @@ protected: if (!success) { result.AppendErrorWithFormat( "'%s' is not a valid hex string value.\n", entry.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } else if (!llvm::isUIntN(item_byte_size * 8, uval64)) { result.AppendErrorWithFormat("Value 0x%" PRIx64 " is too large to fit in a %" PRIu64 " byte unsigned integer value.\n", uval64, (uint64_t)item_byte_size); - result.SetStatus(eReturnStatusFailed); return false; } buffer.PutMaxHex64(uval64, item_byte_size); @@ -1441,7 +1416,6 @@ protected: if (!success) { result.AppendErrorWithFormat( "'%s' is not a valid boolean string value.\n", entry.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } buffer.PutMaxHex64(uval64, item_byte_size); @@ -1451,14 +1425,12 @@ protected: if (entry.ref().getAsInteger(2, uval64)) { result.AppendErrorWithFormat( "'%s' is not a valid binary string value.\n", entry.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } else if (!llvm::isUIntN(item_byte_size * 8, uval64)) { result.AppendErrorWithFormat("Value 0x%" PRIx64 " is too large to fit in a %" PRIu64 " byte unsigned integer value.\n", uval64, (uint64_t)item_byte_size); - result.SetStatus(eReturnStatusFailed); return false; } buffer.PutMaxHex64(uval64, item_byte_size); @@ -1481,7 +1453,6 @@ protected: result.AppendErrorWithFormat("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } break; @@ -1490,14 +1461,12 @@ protected: if (entry.ref().getAsInteger(0, sval64)) { result.AppendErrorWithFormat( "'%s' is not a valid signed decimal value.\n", entry.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } else if (!llvm::isIntN(item_byte_size * 8, sval64)) { result.AppendErrorWithFormat( "Value %" PRIi64 " is too large or small to fit in a %" PRIu64 " byte signed integer value.\n", sval64, (uint64_t)item_byte_size); - result.SetStatus(eReturnStatusFailed); return false; } buffer.PutMaxHex64(sval64, item_byte_size); @@ -1505,18 +1474,16 @@ protected: case eFormatUnsigned: - if (!entry.ref().getAsInteger(0, uval64)) { + if (entry.ref().getAsInteger(0, uval64)) { result.AppendErrorWithFormat( "'%s' is not a valid unsigned decimal string value.\n", entry.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } else if (!llvm::isUIntN(item_byte_size * 8, uval64)) { result.AppendErrorWithFormat("Value %" PRIu64 " is too large to fit in a %" PRIu64 " byte unsigned integer value.\n", uval64, (uint64_t)item_byte_size); - result.SetStatus(eReturnStatusFailed); return false; } buffer.PutMaxHex64(uval64, item_byte_size); @@ -1526,14 +1493,12 @@ protected: if (entry.ref().getAsInteger(8, uval64)) { result.AppendErrorWithFormat( "'%s' is not a valid octal string value.\n", entry.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } else if (!llvm::isUIntN(item_byte_size * 8, uval64)) { result.AppendErrorWithFormat("Value %" PRIo64 " is too large to fit in a %" PRIu64 " byte unsigned integer value.\n", uval64, (uint64_t)item_byte_size); - result.SetStatus(eReturnStatusFailed); return false; } buffer.PutMaxHex64(uval64, item_byte_size); @@ -1551,7 +1516,6 @@ protected: result.AppendErrorWithFormat("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -1604,7 +1568,6 @@ protected: if (argc == 0 || argc > 1) { result.AppendErrorWithFormat("%s takes an address expression", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1615,7 +1578,6 @@ protected: if (addr == LLDB_INVALID_ADDRESS) { result.AppendError("invalid address expression"); result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1627,7 +1589,6 @@ protected: if (!memory_history) { result.AppendError("no available memory history provider"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1666,7 +1627,6 @@ protected: if (!process_sp) { m_prev_end_addr = LLDB_INVALID_ADDRESS; result.AppendError("invalid process"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1678,7 +1638,6 @@ protected: if (argc > 1 || (argc == 0 && load_addr == LLDB_INVALID_ADDRESS)) { result.AppendErrorWithFormat("'%s' takes one argument:\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1689,7 +1648,6 @@ protected: if (error.Fail() || load_addr == LLDB_INVALID_ADDRESS) { result.AppendErrorWithFormat("invalid address argument \"%s\": %s\n", command[0].c_str(), error.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -1721,12 +1679,33 @@ protected: if (memory_tagged == MemoryRegionInfo::OptionalBool::eYes) result.AppendMessage("memory tagging: enabled"); + const llvm::Optional<std::vector<addr_t>> &dirty_page_list = + range_info.GetDirtyPageList(); + if (dirty_page_list.hasValue()) { + const size_t page_count = dirty_page_list.getValue().size(); + result.AppendMessageWithFormat( + "Modified memory (dirty) page list provided, %zu entries.\n", + page_count); + if (page_count > 0) { + bool print_comma = false; + result.AppendMessageWithFormat("Dirty pages: "); + for (size_t i = 0; i < page_count; i++) { + if (print_comma) + result.AppendMessageWithFormat(", "); + else + print_comma = true; + result.AppendMessageWithFormat("0x%" PRIx64, + dirty_page_list.getValue()[i]); + } + result.AppendMessageWithFormat(".\n"); + } + } + m_prev_end_addr = range_info.GetRange().GetRangeEnd(); result.SetStatus(eReturnStatusSuccessFinishResult); return true; } - result.SetStatus(eReturnStatusFailed); result.AppendErrorWithFormat("%s\n", error.AsCString()); return false; } @@ -1758,6 +1737,8 @@ CommandObjectMemory::CommandObjectMemory(CommandInterpreter &interpreter) CommandObjectSP(new CommandObjectMemoryHistory(interpreter))); LoadSubCommand("region", CommandObjectSP(new CommandObjectMemoryRegion(interpreter))); + LoadSubCommand("tag", + CommandObjectSP(new CommandObjectMemoryTag(interpreter))); } CommandObjectMemory::~CommandObjectMemory() = default; diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectMemoryTag.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectMemoryTag.cpp new file mode 100644 index 000000000000..1dfb32a92f3b --- /dev/null +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectMemoryTag.cpp @@ -0,0 +1,128 @@ +//===-- CommandObjectMemoryTag.cpp ----------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "CommandObjectMemoryTag.h" +#include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/OptionArgParser.h" +#include "lldb/Target/Process.h" + +using namespace lldb; +using namespace lldb_private; + +#define LLDB_OPTIONS_memory_tag_read +#include "CommandOptions.inc" + +class CommandObjectMemoryTagRead : public CommandObjectParsed { +public: + CommandObjectMemoryTagRead(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "tag", + "Read memory tags for the given range of memory.", + nullptr, + eCommandRequiresTarget | eCommandRequiresProcess | + eCommandProcessMustBePaused) { + // Address + m_arguments.push_back( + CommandArgumentEntry{CommandArgumentData(eArgTypeAddressOrExpression)}); + // Optional end address + m_arguments.push_back(CommandArgumentEntry{ + CommandArgumentData(eArgTypeAddressOrExpression, eArgRepeatOptional)}); + } + + ~CommandObjectMemoryTagRead() override = default; + +protected: + bool DoExecute(Args &command, CommandReturnObject &result) override { + if ((command.GetArgumentCount() < 1) || (command.GetArgumentCount() > 2)) { + result.AppendError( + "wrong number of arguments; expected at least <address-expression>, " + "at most <address-expression> <end-address-expression>"); + return false; + } + + Status error; + addr_t start_addr = OptionArgParser::ToAddress( + &m_exe_ctx, command[0].ref(), LLDB_INVALID_ADDRESS, &error); + if (start_addr == LLDB_INVALID_ADDRESS) { + result.AppendErrorWithFormatv("Invalid address expression, {0}", + error.AsCString()); + return false; + } + + // Default 1 byte beyond start, rounds up to at most 1 granule later + addr_t end_addr = start_addr + 1; + + if (command.GetArgumentCount() > 1) { + end_addr = OptionArgParser::ToAddress(&m_exe_ctx, command[1].ref(), + LLDB_INVALID_ADDRESS, &error); + if (end_addr == LLDB_INVALID_ADDRESS) { + result.AppendErrorWithFormatv("Invalid end address expression, {0}", + error.AsCString()); + return false; + } + } + + Process *process = m_exe_ctx.GetProcessPtr(); + llvm::Expected<const MemoryTagManager *> tag_manager_or_err = + process->GetMemoryTagManager(); + + if (!tag_manager_or_err) { + result.SetError(Status(tag_manager_or_err.takeError())); + return false; + } + + const MemoryTagManager *tag_manager = *tag_manager_or_err; + + MemoryRegionInfos memory_regions; + // If this fails the list of regions is cleared, so we don't need to read + // the return status here. + process->GetMemoryRegions(memory_regions); + llvm::Expected<MemoryTagManager::TagRange> tagged_range = + tag_manager->MakeTaggedRange(start_addr, end_addr, memory_regions); + + if (!tagged_range) { + result.SetError(Status(tagged_range.takeError())); + return false; + } + + llvm::Expected<std::vector<lldb::addr_t>> tags = process->ReadMemoryTags( + tagged_range->GetRangeBase(), tagged_range->GetByteSize()); + + if (!tags) { + result.SetError(Status(tags.takeError())); + return false; + } + + result.AppendMessageWithFormatv("Logical tag: {0:x}", + tag_manager->GetLogicalTag(start_addr)); + result.AppendMessage("Allocation tags:"); + + addr_t addr = tagged_range->GetRangeBase(); + for (auto tag : *tags) { + addr_t next_addr = addr + tag_manager->GetGranuleSize(); + // Showing tagged adresses here until we have non address bit handling + result.AppendMessageWithFormatv("[{0:x}, {1:x}): {2:x}", addr, next_addr, + tag); + addr = next_addr; + } + + result.SetStatus(eReturnStatusSuccessFinishResult); + return true; + } +}; + +CommandObjectMemoryTag::CommandObjectMemoryTag(CommandInterpreter &interpreter) + : CommandObjectMultiword( + interpreter, "tag", "Commands for manipulating memory tags", + "memory tag <sub-command> [<sub-command-options>]") { + CommandObjectSP read_command_object( + new CommandObjectMemoryTagRead(interpreter)); + read_command_object->SetCommandName("memory tag read"); + LoadSubCommand("read", read_command_object); +} + +CommandObjectMemoryTag::~CommandObjectMemoryTag() = default; diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectMemoryTag.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectMemoryTag.h new file mode 100644 index 000000000000..54909ac90811 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectMemoryTag.h @@ -0,0 +1,25 @@ +//===-- CommandObjectMemoryTag.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_SOURCE_COMMANDS_COMMANDOBJECTMEMORYTAG_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTMEMORYTAG_H + +#include "lldb/Interpreter/CommandObjectMultiword.h" + +namespace lldb_private { + +class CommandObjectMemoryTag : public CommandObjectMultiword { +public: + CommandObjectMemoryTag(CommandInterpreter &interpreter); + + ~CommandObjectMemoryTag() override; +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTMEMORYTAG_H diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectMultiword.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectMultiword.cpp index 0f20a1d88bd9..a523fd0b1560 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectMultiword.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectMultiword.cpp @@ -98,7 +98,7 @@ bool CommandObjectMultiword::Execute(const char *args_string, return result.Succeeded(); } - if (sub_command.equals_lower("help")) { + if (sub_command.equals_insensitive("help")) { this->CommandObject::GenerateHelpText(result); return result.Succeeded(); } @@ -106,7 +106,6 @@ bool CommandObjectMultiword::Execute(const char *args_string, if (m_subcommand_dict.empty()) { result.AppendErrorWithFormat("'%s' does not have any subcommands.\n", GetCommandName().str().c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -144,7 +143,6 @@ bool CommandObjectMultiword::Execute(const char *args_string, } error_msg.append("\n"); result.AppendRawError(error_msg.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -398,6 +396,6 @@ bool CommandObjectProxy::Execute(const char *args_string, CommandObject *proxy_command = GetProxyCommandObject(); if (proxy_command) return proxy_command->Execute(args_string, result); - result.SetError(GetUnsupportedError()); + result.AppendError(GetUnsupportedError()); return false; } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.cpp index f306da3c8543..bf23c4552aa8 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.cpp @@ -60,7 +60,7 @@ static mode_t ParsePermissionString(llvm::StringRef permissions) { class OptionPermissions : public OptionGroup { public: - OptionPermissions() {} + OptionPermissions() = default; ~OptionPermissions() override = default; @@ -180,16 +180,13 @@ protected: result.SetStatus(eReturnStatusSuccessFinishResult); } else { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); } } else { result.AppendError("invalid platform name"); - result.SetStatus(eReturnStatusFailed); } } else { result.AppendError( "platform create takes a platform name as an argument\n"); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -232,7 +229,6 @@ protected: if (idx == 0) { result.AppendError("no platforms are available\n"); - result.SetStatus(eReturnStatusFailed); } else result.SetStatus(eReturnStatusSuccessFinishResult); return result.Succeeded(); @@ -266,7 +262,6 @@ protected: result.SetStatus(eReturnStatusSuccessFinishResult); } else { result.AppendError("no platform is currently selected\n"); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -298,15 +293,12 @@ protected: platform_sp->ConnectToWaitingProcesses(GetDebugger(), error); if (error.Fail()) { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); } } else { result.AppendErrorWithFormat("%s\n", error.AsCString()); - result.SetStatus(eReturnStatusFailed); } } else { result.AppendError("no platform is currently selected\n"); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -361,24 +353,20 @@ protected: result.SetStatus(eReturnStatusSuccessFinishResult); } else { result.AppendErrorWithFormat("%s", error.AsCString()); - result.SetStatus(eReturnStatusFailed); } } else { // Not connected... result.AppendErrorWithFormat( "not connected to '%s'", platform_sp->GetPluginName().GetCString()); - result.SetStatus(eReturnStatusFailed); } } else { // Bad args result.AppendError( "\"platform disconnect\" doesn't take any arguments"); - result.SetStatus(eReturnStatusFailed); } } else { result.AppendError("no platform is currently selected"); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -412,7 +400,6 @@ protected: m_option_working_dir.GetOptionValue().GetCurrentValue()); } else { result.AppendError("no platform is currently selected"); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -457,11 +444,9 @@ public: result.SetStatus(eReturnStatusSuccessFinishResult); } else { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); } } else { result.AppendError("no platform currently selected\n"); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -521,11 +506,9 @@ public: result.SetStatus(eReturnStatusSuccessFinishResult); } else { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); } } else { result.AppendError("no platform currently selected\n"); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -560,7 +543,6 @@ public: if (!llvm::to_integer(cmd_line, fd)) { result.AppendErrorWithFormatv("'{0}' is not a valid file descriptor.\n", cmd_line); - result.SetStatus(eReturnStatusFailed); return result.Succeeded(); } Status error; @@ -570,11 +552,9 @@ public: result.SetStatus(eReturnStatusSuccessFinishResult); } else { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); } } else { result.AppendError("no platform currently selected\n"); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -605,7 +585,6 @@ public: if (!llvm::to_integer(cmd_line, fd)) { result.AppendErrorWithFormatv("'{0}' is not a valid file descriptor.\n", cmd_line); - result.SetStatus(eReturnStatusFailed); return result.Succeeded(); } std::string buffer(m_options.m_count, 0); @@ -617,7 +596,6 @@ public: result.SetStatus(eReturnStatusSuccessFinishResult); } else { result.AppendError("no platform currently selected\n"); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -698,7 +676,6 @@ public: if (!llvm::to_integer(cmd_line, fd)) { result.AppendErrorWithFormatv("'{0}' is not a valid file descriptor.", cmd_line); - result.SetStatus(eReturnStatusFailed); return result.Succeeded(); } uint32_t retcode = @@ -708,7 +685,6 @@ public: result.SetStatus(eReturnStatusSuccessFinishResult); } else { result.AppendError("no platform currently selected\n"); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -844,10 +820,8 @@ public: bool DoExecute(Args &args, CommandReturnObject &result) override { // If the number of arguments is incorrect, issue an error message. if (args.GetArgumentCount() != 2) { - result.GetErrorStream().Printf("error: required arguments missing; " - "specify both the source and destination " - "file paths\n"); - result.SetStatus(eReturnStatusFailed); + result.AppendError("required arguments missing; specify both the " + "source and destination file paths"); return false; } @@ -866,11 +840,9 @@ public: } else { result.AppendMessageWithFormat("get-file failed: %s\n", error.AsCString()); - result.SetStatus(eReturnStatusFailed); } } else { result.AppendError("no platform currently selected\n"); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -920,10 +892,8 @@ public: bool DoExecute(Args &args, CommandReturnObject &result) override { // If the number of arguments is incorrect, issue an error message. if (args.GetArgumentCount() != 1) { - result.GetErrorStream().Printf("error: required argument missing; " - "specify the source file path as the only " - "argument\n"); - result.SetStatus(eReturnStatusFailed); + result.AppendError("required argument missing; specify the source file " + "path as the only argument"); return false; } @@ -941,11 +911,9 @@ public: result.AppendMessageWithFormat( "Error getting file size of %s (remote)\n", remote_file_path.c_str()); - result.SetStatus(eReturnStatusFailed); } } else { result.AppendError("no platform currently selected\n"); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -991,11 +959,9 @@ public: result.SetStatus(eReturnStatusSuccessFinishNoResult); } else { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); } } else { result.AppendError("no platform currently selected\n"); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -1009,11 +975,14 @@ public: "Launch a new process on a remote platform.", "platform process launch program", eCommandRequiresTarget | eCommandTryTargetAPILock), - m_options() {} + m_options(), m_all_options() { + m_all_options.Append(&m_options); + m_all_options.Finalize(); + } ~CommandObjectPlatformProcessLaunch() override = default; - Options *GetOptions() override { return &m_options; } + Options *GetOptions() override { return &m_all_options; } protected: bool DoExecute(Args &args, CommandReturnObject &result) override { @@ -1070,12 +1039,10 @@ protected: result.AppendError("process launch failed"); else result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); } else { result.AppendError("'platform process launch' uses the current target " "file and arguments, or the executable and its " "arguments can be specified in this command"); - result.SetStatus(eReturnStatusFailed); return false; } } else { @@ -1085,6 +1052,7 @@ protected: } CommandOptionsProcessLaunch m_options; + OptionGroupOptions m_all_options; }; // "platform process list" @@ -1136,7 +1104,6 @@ protected: } else { result.AppendErrorWithFormat( "no process found with pid = %" PRIu64 "\n", pid); - result.SetStatus(eReturnStatusFailed); } } else { ProcessInstanceInfoList proc_infos; @@ -1178,7 +1145,6 @@ protected: result.AppendErrorWithFormat( "no processes were found on the \"%s\" platform\n", platform_sp->GetPluginName().GetCString()); - result.SetStatus(eReturnStatusFailed); } else { result.AppendMessageWithFormat( "%u matching process%s found on \"%s\"", matches, @@ -1200,19 +1166,16 @@ protected: } } else { result.AppendError("invalid args: process list takes only options\n"); - result.SetStatus(eReturnStatusFailed); } } else { result.AppendError("no platform is selected\n"); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } class CommandOptions : public Options { public: - CommandOptions() - : Options(), match_info(), show_args(false), verbose(false) {} + CommandOptions() : Options(), match_info() {} ~CommandOptions() override = default; @@ -1347,8 +1310,8 @@ protected: // Instance variables to hold the values for command options. ProcessInstanceInfoMatch match_info; - bool show_args; - bool verbose; + bool show_args = false; + bool verbose = false; }; CommandOptions m_options; @@ -1410,7 +1373,6 @@ protected: if (entry.ref().getAsInteger(0, pid)) { result.AppendErrorWithFormat("invalid process ID argument '%s'", entry.ref().str().c_str()); - result.SetStatus(eReturnStatusFailed); break; } else { ProcessInstanceInfo proc_info; @@ -1431,16 +1393,13 @@ protected: result.AppendErrorWithFormat( "not connected to '%s'", platform_sp->GetPluginName().GetCString()); - result.SetStatus(eReturnStatusFailed); } } else { // No args result.AppendError("one or more process id(s) must be specified"); - result.SetStatus(eReturnStatusFailed); } } else { result.AppendError("no platform is currently selected"); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -1529,15 +1488,12 @@ public: m_options.attach_info, GetDebugger(), nullptr, err); if (err.Fail()) { result.AppendError(err.AsCString()); - result.SetStatus(eReturnStatusFailed); } else if (!remote_process_sp) { result.AppendError("could not attach: unknown reason"); - result.SetStatus(eReturnStatusFailed); } else result.SetStatus(eReturnStatusSuccessFinishResult); } else { result.AppendError("no platform is currently selected"); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -1715,7 +1671,6 @@ public: if (error.Fail()) { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); } else { result.SetStatus(eReturnStatusSuccessFinishResult); } @@ -1749,7 +1704,6 @@ public: bool DoExecute(Args &args, CommandReturnObject &result) override { if (args.GetArgumentCount() != 2) { result.AppendError("platform target-install takes two arguments"); - result.SetStatus(eReturnStatusFailed); return false; } // TODO: move the bulk of this code over to the platform itself @@ -1758,14 +1712,12 @@ public: FileSpec dst(args.GetArgumentAtIndex(1)); if (!FileSystem::Instance().Exists(src)) { result.AppendError("source location does not exist or is not accessible"); - result.SetStatus(eReturnStatusFailed); return false; } PlatformSP platform_sp( GetDebugger().GetPlatformList().GetSelectedPlatform()); if (!platform_sp) { result.AppendError("no platform currently selected"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1774,7 +1726,6 @@ public: result.SetStatus(eReturnStatusSuccessFinishNoResult); } else { result.AppendErrorWithFormat("install failed: %s", error.AsCString()); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectPlugin.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectPlugin.cpp index 98a212eef0fa..881415a49472 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectPlugin.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectPlugin.cpp @@ -50,7 +50,6 @@ protected: if (argc != 1) { result.AppendError("'plugin load' requires one argument"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -63,7 +62,6 @@ protected: result.SetStatus(eReturnStatusSuccessFinishResult); else { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp index 35835f638557..7aaba3731500 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "CommandObjectProcess.h" +#include "CommandObjectTrace.h" #include "CommandOptionsProcessLaunch.h" #include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Breakpoint/BreakpointLocation.h" @@ -17,6 +18,7 @@ #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionArgParser.h" +#include "lldb/Interpreter/OptionGroupPythonClassWithDict.h" #include "lldb/Interpreter/Options.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" @@ -27,6 +29,8 @@ #include "lldb/Utility/Args.h" #include "lldb/Utility/State.h" +#include <bitset> + using namespace lldb; using namespace lldb_private; @@ -77,7 +81,6 @@ protected: result.AppendErrorWithFormat( "Failed to detach from process: %s\n", detach_error.AsCString()); - result.SetStatus(eReturnStatusFailed); } } else { Status destroy_error(process->Destroy(false)); @@ -87,7 +90,6 @@ protected: } else { result.AppendErrorWithFormat("Failed to kill process: %s\n", destroy_error.AsCString()); - result.SetStatus(eReturnStatusFailed); } } } @@ -108,7 +110,14 @@ public: interpreter, "process launch", "Launch the executable in the debugger.", nullptr, eCommandRequiresTarget, "restart"), - m_options() { + m_options(), + m_class_options("scripted process", true, 'C', 'k', 'v', 0), + m_all_options() { + m_all_options.Append(&m_options); + m_all_options.Append(&m_class_options, LLDB_OPT_SET_1 | LLDB_OPT_SET_2, + LLDB_OPT_SET_ALL); + m_all_options.Finalize(); + CommandArgumentEntry arg; CommandArgumentData run_args_arg; @@ -135,7 +144,7 @@ public: request, nullptr); } - Options *GetOptions() override { return &m_options; } + Options *GetOptions() override { return &m_all_options; } const char *GetRepeatCommand(Args ¤t_command_args, uint32_t index) override { @@ -153,7 +162,6 @@ protected: if (exe_module_sp == nullptr) { result.AppendError("no file in target, create a debug target using the " "'target create' command"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -180,6 +188,15 @@ protected: disable_aslr = target->GetDisableASLR(); } + if (!m_class_options.GetName().empty()) { + m_options.launch_info.SetProcessPluginName("ScriptedProcess"); + m_options.launch_info.SetScriptedProcessClassName( + m_class_options.GetName()); + m_options.launch_info.SetScriptedProcessDictionarySP( + m_class_options.GetStructuredData()); + target->SetProcessLaunchInfo(m_options.launch_info); + } + if (disable_aslr) m_options.launch_info.GetFlags().Set(eLaunchFlagDisableASLR); else @@ -243,16 +260,16 @@ protected: } else { result.AppendError( "no error returned from Target::Launch, and target has no process"); - result.SetStatus(eReturnStatusFailed); } } else { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } CommandOptionsProcessLaunch m_options; + OptionGroupPythonClassWithDict m_class_options; + OptionGroupOptions m_all_options; }; #define LLDB_OPTIONS_process_attach @@ -377,11 +394,9 @@ protected: if (command.GetArgumentCount()) { result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } - m_interpreter.UpdateExecutionContext(nullptr); StreamString stream; const auto error = target->Attach(m_options.attach_info, &stream); if (error.Success()) { @@ -393,11 +408,9 @@ protected: } else { result.AppendError( "no error returned from Target::Attach, and target has no process"); - result.SetStatus(eReturnStatusFailed); } } else { result.AppendErrorWithFormat("attach failed: %s\n", error.AsCString()); - result.SetStatus(eReturnStatusFailed); } if (!result.Succeeded()) @@ -517,7 +530,6 @@ protected: result.AppendErrorWithFormat( "The '%s' command does not take any arguments.\n", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -589,13 +601,11 @@ protected: } else { result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString()); - result.SetStatus(eReturnStatusFailed); } } else { result.AppendErrorWithFormat( "Process cannot be continued from its current state (%s).\n", StateAsCString(state)); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -687,7 +697,6 @@ protected: result.SetStatus(eReturnStatusSuccessFinishResult); } else { result.AppendErrorWithFormat("Detach failed: %s\n", error.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } return result.Succeeded(); @@ -759,7 +768,6 @@ protected: result.AppendErrorWithFormat( "'%s' takes exactly one argument:\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -769,7 +777,6 @@ protected: "Process %" PRIu64 " is currently being debugged, kill the process before connecting.\n", process->GetID()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -791,7 +798,6 @@ protected: error); if (error.Fail() || process_sp == nullptr) { result.AppendError(error.AsCString("Error connecting to the process")); - result.SetStatus(eReturnStatusFailed); return false; } return true; @@ -931,7 +937,6 @@ protected: result.AppendErrorWithFormat("failed to load '%s': %s", image_path.str().c_str(), error.AsCString()); - result.SetStatus(eReturnStatusFailed); } } return result.Succeeded(); @@ -983,7 +988,6 @@ protected: if (entry.ref().getAsInteger(0, image_token)) { result.AppendErrorWithFormat("invalid image index argument '%s'", entry.ref().str().c_str()); - result.SetStatus(eReturnStatusFailed); break; } else { Status error(process->GetTarget().GetPlatform()->UnloadImage( @@ -995,7 +999,6 @@ protected: } else { result.AppendErrorWithFormat("failed to unload image: %s", error.AsCString()); - result.SetStatus(eReturnStatusFailed); break; } } @@ -1040,7 +1043,7 @@ public: UnixSignalsSP signals = m_exe_ctx.GetProcessPtr()->GetUnixSignals(); int signo = signals->GetFirstSignalNumber(); while (signo != LLDB_INVALID_SIGNAL_NUMBER) { - request.AddCompletion(signals->GetSignalAsCString(signo), ""); + request.TryCompleteCurrentArg(signals->GetSignalAsCString(signo)); signo = signals->GetNextSignalNumber(signo); } } @@ -1062,7 +1065,6 @@ protected: if (signo == LLDB_INVALID_SIGNAL_NUMBER) { result.AppendErrorWithFormat("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0)); - result.SetStatus(eReturnStatusFailed); } else { Status error(process->Signal(signo)); if (error.Success()) { @@ -1070,14 +1072,12 @@ protected: } else { result.AppendErrorWithFormat("Failed to send signal %i: %s\n", signo, error.AsCString()); - result.SetStatus(eReturnStatusFailed); } } } else { result.AppendErrorWithFormat( "'%s' takes exactly one signal number argument:\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str()); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -1102,7 +1102,6 @@ protected: Process *process = m_exe_ctx.GetProcessPtr(); if (process == nullptr) { result.AppendError("no process to halt"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1114,12 +1113,10 @@ protected: } else { result.AppendErrorWithFormat("Failed to halt process: %s\n", error.AsCString()); - result.SetStatus(eReturnStatusFailed); } } else { result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str()); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -1144,7 +1141,6 @@ protected: Process *process = m_exe_ctx.GetProcessPtr(); if (process == nullptr) { result.AppendError("no process to kill"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1155,12 +1151,10 @@ protected: } else { result.AppendErrorWithFormat("Failed to kill process: %s\n", error.AsCString()); - result.SetStatus(eReturnStatusFailed); } } else { result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str()); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -1169,45 +1163,109 @@ protected: // CommandObjectProcessSaveCore #pragma mark CommandObjectProcessSaveCore +static constexpr OptionEnumValueElement g_corefile_save_style[] = { + {eSaveCoreFull, "full", "Create a core file with all memory saved"}, + {eSaveCoreDirtyOnly, "modified-memory", + "Create a corefile with only modified memory saved"}}; + +static constexpr OptionEnumValues SaveCoreStyles() { + return OptionEnumValues(g_corefile_save_style); +} + +#define LLDB_OPTIONS_process_save_core +#include "CommandOptions.inc" + class CommandObjectProcessSaveCore : public CommandObjectParsed { public: CommandObjectProcessSaveCore(CommandInterpreter &interpreter) : CommandObjectParsed(interpreter, "process save-core", "Save the current process as a core file using an " "appropriate file type.", - "process save-core FILE", + "process save-core [-s corefile-style] FILE", eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched) {} ~CommandObjectProcessSaveCore() override = default; + Options *GetOptions() override { return &m_options; } + + class CommandOptions : public Options { + public: + CommandOptions() + : Options(), m_requested_save_core_style(eSaveCoreUnspecified) {} + + ~CommandOptions() override = default; + + llvm::ArrayRef<OptionDefinition> GetDefinitions() override { + return llvm::makeArrayRef(g_process_save_core_options); + } + + Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, + ExecutionContext *execution_context) override { + const int short_option = m_getopt_table[option_idx].val; + Status error; + + switch (short_option) { + case 's': + m_requested_save_core_style = + (lldb::SaveCoreStyle)OptionArgParser::ToOptionEnum( + option_arg, GetDefinitions()[option_idx].enum_values, + eSaveCoreUnspecified, error); + break; + default: + llvm_unreachable("Unimplemented option"); + } + + return {}; + } + + void OptionParsingStarting(ExecutionContext *execution_context) override { + m_requested_save_core_style = eSaveCoreUnspecified; + } + + // Instance variables to hold the values for command options. + SaveCoreStyle m_requested_save_core_style; + }; + protected: bool DoExecute(Args &command, CommandReturnObject &result) override { ProcessSP process_sp = m_exe_ctx.GetProcessSP(); if (process_sp) { if (command.GetArgumentCount() == 1) { FileSpec output_file(command.GetArgumentAtIndex(0)); - Status error = PluginManager::SaveCore(process_sp, output_file); + SaveCoreStyle corefile_style = m_options.m_requested_save_core_style; + Status error = + PluginManager::SaveCore(process_sp, output_file, corefile_style); if (error.Success()) { + if (corefile_style == SaveCoreStyle::eSaveCoreDirtyOnly) { + result.AppendMessageWithFormat( + "\nModified-memory only corefile " + "created. This corefile may not show \n" + "library/framework/app binaries " + "on a different system, or when \n" + "those binaries have " + "been updated/modified. Copies are not included\n" + "in this corefile. Use --style full to include all " + "process memory.\n"); + } result.SetStatus(eReturnStatusSuccessFinishResult); } else { result.AppendErrorWithFormat( "Failed to save core file for process: %s\n", error.AsCString()); - result.SetStatus(eReturnStatusFailed); } } else { result.AppendErrorWithFormat("'%s' takes one arguments:\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str()); - result.SetStatus(eReturnStatusFailed); } } else { result.AppendError("invalid process"); - result.SetStatus(eReturnStatusFailed); return false; } return result.Succeeded(); } + + CommandOptions m_options; }; // CommandObjectProcessStatus @@ -1231,7 +1289,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() : Options(), m_verbose(false) {} + CommandOptions() : Options() {} ~CommandOptions() override = default; @@ -1259,7 +1317,7 @@ public: } // Instance variables to hold the values for command options. - bool m_verbose; + bool m_verbose = false; }; protected: @@ -1269,7 +1327,6 @@ protected: if (command.GetArgumentCount()) { result.AppendError("'process status' takes no arguments"); - result.SetStatus(eReturnStatusFailed); return result.Succeeded(); } @@ -1286,10 +1343,21 @@ protected: num_frames, num_frames_with_source, stop_format); if (m_options.m_verbose) { + addr_t code_mask = process->GetCodeAddressMask(); + addr_t data_mask = process->GetDataAddressMask(); + if (code_mask != 0) { + int bits = std::bitset<64>(~code_mask).count(); + result.AppendMessageWithFormat( + "Addressable code address mask: 0x%" PRIx64 "\n", code_mask); + result.AppendMessageWithFormat( + "Addressable data address mask: 0x%" PRIx64 "\n", data_mask); + result.AppendMessageWithFormat( + "Number of bits used in addressing (code): %d\n", bits); + } + PlatformSP platform_sp = process->GetTarget().GetPlatform(); if (!platform_sp) { result.AppendError("Couldn'retrieve the target's platform"); - result.SetStatus(eReturnStatusFailed); return result.Succeeded(); } @@ -1298,7 +1366,6 @@ protected: if (!expected_crash_info) { result.AppendError(llvm::toString(expected_crash_info.takeError())); - result.SetStatus(eReturnStatusFailed); return result.Succeeded(); } @@ -1467,7 +1534,6 @@ protected: if (!process_sp) { result.AppendError("No current process; cannot handle signals until you " "have a valid process.\n"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1479,7 +1545,6 @@ protected: !VerifyCommandOptionValue(m_options.stop, stop_action)) { result.AppendError("Invalid argument for command option --stop; must be " "true or false.\n"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1487,7 +1552,6 @@ protected: !VerifyCommandOptionValue(m_options.notify, notify_action)) { result.AppendError("Invalid argument for command option --notify; must " "be true or false.\n"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1495,7 +1559,6 @@ protected: !VerifyCommandOptionValue(m_options.pass, pass_action)) { result.AppendError("Invalid argument for command option --pass; must be " "true or false.\n"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1559,6 +1622,71 @@ protected: CommandOptions m_options; }; +// Next are the subcommands of CommandObjectMultiwordProcessTrace + +// CommandObjectProcessTraceStart +class CommandObjectProcessTraceStart : public CommandObjectTraceProxy { +public: + CommandObjectProcessTraceStart(CommandInterpreter &interpreter) + : CommandObjectTraceProxy( + /*live_debug_session_only*/ true, interpreter, + "process trace start", + "Start tracing this process with the corresponding trace " + "plug-in.", + "process trace start [<trace-options>]") {} + +protected: + lldb::CommandObjectSP GetDelegateCommand(Trace &trace) override { + return trace.GetProcessTraceStartCommand(m_interpreter); + } +}; + +// CommandObjectProcessTraceStop +class CommandObjectProcessTraceStop : public CommandObjectParsed { +public: + CommandObjectProcessTraceStop(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "process trace stop", + "Stop tracing this process. This does not affect " + "traces started with the " + "\"thread trace start\" command.", + "process trace stop", + eCommandRequiresProcess | eCommandTryTargetAPILock | + eCommandProcessMustBeLaunched | + eCommandProcessMustBePaused | + eCommandProcessMustBeTraced) {} + + ~CommandObjectProcessTraceStop() override = default; + + bool DoExecute(Args &command, CommandReturnObject &result) override { + ProcessSP process_sp = m_exe_ctx.GetProcessSP(); + + TraceSP trace_sp = process_sp->GetTarget().GetTrace(); + + if (llvm::Error err = trace_sp->Stop()) + result.AppendError(toString(std::move(err))); + else + result.SetStatus(eReturnStatusSuccessFinishResult); + + return result.Succeeded(); + } +}; + +// CommandObjectMultiwordProcessTrace +class CommandObjectMultiwordProcessTrace : public CommandObjectMultiword { +public: + CommandObjectMultiwordProcessTrace(CommandInterpreter &interpreter) + : CommandObjectMultiword( + interpreter, "trace", "Commands for tracing the current process.", + "process trace <subcommand> [<subcommand objects>]") { + LoadSubCommand("start", CommandObjectSP(new CommandObjectProcessTraceStart( + interpreter))); + LoadSubCommand("stop", CommandObjectSP( + new CommandObjectProcessTraceStop(interpreter))); + } + + ~CommandObjectMultiwordProcessTrace() override = default; +}; + // CommandObjectMultiwordProcess CommandObjectMultiwordProcess::CommandObjectMultiwordProcess( @@ -1595,6 +1723,9 @@ CommandObjectMultiwordProcess::CommandObjectMultiwordProcess( CommandObjectSP(new CommandObjectProcessPlugin(interpreter))); LoadSubCommand("save-core", CommandObjectSP(new CommandObjectProcessSaveCore( interpreter))); + LoadSubCommand( + "trace", + CommandObjectSP(new CommandObjectMultiwordProcessTrace(interpreter))); } CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess() = default; diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectQuit.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectQuit.cpp index d4d15bea9a8e..c6e2e21de6b6 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectQuit.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectQuit.cpp @@ -22,7 +22,7 @@ CommandObjectQuit::CommandObjectQuit(CommandInterpreter &interpreter) : CommandObjectParsed(interpreter, "quit", "Quit the LLDB debugger.", "quit [exit-code]") {} -CommandObjectQuit::~CommandObjectQuit() {} +CommandObjectQuit::~CommandObjectQuit() = default; // returns true if there is at least one alive process is_a_detach will be true // if all alive processes will be detached when you quit and false if at least @@ -75,7 +75,6 @@ bool CommandObjectQuit::DoExecute(Args &command, CommandReturnObject &result) { if (command.GetArgumentCount() > 1) { result.AppendError("Too many arguments for 'quit'. Only an optional exit " "code is allowed"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -88,13 +87,11 @@ bool CommandObjectQuit::DoExecute(Args &command, CommandReturnObject &result) { std::string arg_str = arg.str(); s.Printf("Couldn't parse '%s' as integer for exit code.", arg_str.data()); result.AppendError(s.GetString()); - result.SetStatus(eReturnStatusFailed); return false; } if (!m_interpreter.SetQuitExitCode(exit_code)) { result.AppendError("The current driver doesn't allow custom exit codes" " for the quit command."); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -104,8 +101,5 @@ bool CommandObjectQuit::DoExecute(Args &command, CommandReturnObject &result) { m_interpreter.BroadcastEvent(event_type); result.SetStatus(eReturnStatusQuit); - if (m_interpreter.GetSaveSessionOnQuit()) - m_interpreter.SaveTranscript(result); - return true; } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.cpp index 1bf29d3c047b..46295421834a 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.cpp @@ -23,7 +23,7 @@ CommandObjectRegexCommand::CommandObjectRegexCommand( m_entries(), m_is_removable(is_removable) {} // Destructor -CommandObjectRegexCommand::~CommandObjectRegexCommand() {} +CommandObjectRegexCommand::~CommandObjectRegexCommand() = default; bool CommandObjectRegexCommand::DoExecute(llvm::StringRef command, CommandReturnObject &result) { @@ -43,7 +43,7 @@ bool CommandObjectRegexCommand::DoExecute(llvm::StringRef command, percent_var, idx)) != std::string::npos;) { new_command.erase(percent_var_idx, percent_var_len); new_command.insert(percent_var_idx, match_str); - idx += percent_var_idx + match_str.size(); + idx = percent_var_idx + match_str.size(); } } } @@ -53,8 +53,8 @@ bool CommandObjectRegexCommand::DoExecute(llvm::StringRef command, // Pass in true for "no context switching". The command that called us // should have set up the context appropriately, we shouldn't have to // redo that. - return m_interpreter.HandleCommand( - new_command.c_str(), eLazyBoolCalculate, result, nullptr, true, true); + return m_interpreter.HandleCommand(new_command.c_str(), + eLazyBoolCalculate, result); } } result.SetStatus(eReturnStatusFailed); diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectRegister.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectRegister.cpp index 56e8c3fb4b84..6fd71c90c327 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectRegister.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectRegister.cpp @@ -178,13 +178,11 @@ protected: llvm::sys::StrError()); else result.AppendError("unknown error while reading registers.\n"); - result.SetStatus(eReturnStatusFailed); break; } } else { result.AppendErrorWithFormat( "invalid register set index: %" PRIu64 "\n", (uint64_t)set_idx); - result.SetStatus(eReturnStatusFailed); break; } } @@ -203,11 +201,9 @@ protected: if (m_command_options.dump_all_sets) { result.AppendError("the --all option can't be used when registers " "names are supplied as arguments\n"); - result.SetStatus(eReturnStatusFailed); } else if (m_command_options.set_indexes.GetSize() > 0) { result.AppendError("the --set <set> option can't be used when " "registers names are supplied as arguments\n"); - result.SetStatus(eReturnStatusFailed); } else { for (auto &entry : command) { // in most LLDB commands we accept $rbx as the name for register RBX @@ -353,7 +349,6 @@ protected: if (command.GetArgumentCount() != 2) { result.AppendError( "register write takes exactly 2 arguments: <reg-name> <value>"); - result.SetStatus(eReturnStatusFailed); } else { auto reg_name = command[0].ref(); auto value_str = command[1].ref(); @@ -390,11 +385,9 @@ protected: "Failed to write register '%s' with value '%s'", reg_name.str().c_str(), value_str.str().c_str()); } - result.SetStatus(eReturnStatusFailed); } else { result.AppendErrorWithFormat("Register not found for '%s'.\n", reg_name.str().c_str()); - result.SetStatus(eReturnStatusFailed); } } return result.Succeeded(); diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectReproducer.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectReproducer.cpp index 55f34c05d11d..01f9dc64e6f0 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectReproducer.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectReproducer.cpp @@ -138,9 +138,7 @@ llvm::Expected<T> static ReadFromYAML(StringRef filename) { } static void SetError(CommandReturnObject &result, Error err) { - result.GetErrorStream().Printf("error: %s\n", - toString(std::move(err)).c_str()); - result.SetStatus(eReturnStatusFailed); + result.AppendError(toString(std::move(err))); } /// Create a loader from the given path if specified. Otherwise use the current @@ -164,7 +162,8 @@ GetLoaderFromPathOrCurrent(llvm::Optional<Loader> &loader_storage, return loader; // This is a soft error because this is expected to fail during capture. - result.SetError("Not specifying a reproducer is only support during replay."); + result.AppendError( + "Not specifying a reproducer is only support during replay."); result.SetStatus(eReturnStatusSuccessFinishNoResult); return nullptr; } @@ -202,7 +201,6 @@ protected: return result.Succeeded(); } else { result.AppendErrorWithFormat("Unable to get the reproducer generator"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -279,7 +277,7 @@ protected: auto &r = Reproducer::Instance(); if (!r.IsCapturing() && !r.IsReplaying()) { - result.SetError( + result.AppendError( "forcing a crash is only supported when capturing a reproducer."); result.SetStatus(eReturnStatusSuccessFinishNoResult); return false; @@ -586,7 +584,7 @@ protected: return true; } case eReproducerProviderNone: - result.SetError("No valid provider specified."); + result.AppendError("No valid provider specified."); return false; } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectScript.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectScript.cpp index 9dadf11ebfc8..f53d6540bc04 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectScript.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectScript.cpp @@ -84,7 +84,7 @@ CommandObjectScript::CommandObjectScript(CommandInterpreter &interpreter) "results. Start the interactive interpreter if no code is supplied.", "script [--language <scripting-language> --] [<script-code>]") {} -CommandObjectScript::~CommandObjectScript() {} +CommandObjectScript::~CommandObjectScript() = default; bool CommandObjectScript::DoExecute(llvm::StringRef command, CommandReturnObject &result) { @@ -105,7 +105,6 @@ bool CommandObjectScript::DoExecute(llvm::StringRef command, if (language == lldb::eScriptLanguageNone) { result.AppendError( "the script-lang setting is set to none - scripting not available"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -114,7 +113,6 @@ bool CommandObjectScript::DoExecute(llvm::StringRef command, if (script_interpreter == nullptr) { result.AppendError("no script interpreter"); - result.SetStatus(eReturnStatusFailed); return false; } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectSettings.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectSettings.cpp index 87e0352636e1..cd79680e31f7 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectSettings.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectSettings.cpp @@ -87,7 +87,7 @@ insert-before or insert-after."); class CommandOptions : public Options { public: - CommandOptions() : Options(), m_global(false) {} + CommandOptions() : Options() {} ~CommandOptions() override = default; @@ -120,7 +120,7 @@ insert-before or insert-after."); } // Instance variables to hold the values for command options. - bool m_global; + bool m_global = false; bool m_force; }; @@ -177,7 +177,6 @@ protected: if ((argc < min_argc) && (!m_options.m_global)) { result.AppendError("'settings set' takes more arguments"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -185,7 +184,6 @@ protected: if ((var_name == nullptr) || (var_name[0] == '\0')) { result.AppendError( "'settings set' command requires a valid variable name"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -196,7 +194,6 @@ protected: &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef())); if (error.Fail()) { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } return result.Succeeded(); @@ -225,7 +222,6 @@ protected: if (error.Fail()) { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } else { result.SetStatus(eReturnStatusSuccessFinishResult); @@ -285,7 +281,6 @@ protected: result.GetOutputStream().EOL(); } else { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); } } } else { @@ -385,7 +380,6 @@ protected: if (!out_file.GetFile().IsValid()) { result.AppendErrorWithFormat("%s: unable to write to file", path.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -403,7 +397,6 @@ protected: &clean_ctx, out_file, arg.ref(), OptionValue::eDumpGroupExport)); if (!error.Success()) { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); } } @@ -469,14 +462,13 @@ protected: bool DoExecute(Args &command, CommandReturnObject &result) override { FileSpec file(m_options.m_filename); FileSystem::Instance().Resolve(file); - ExecutionContext clean_ctx; CommandInterpreterRunOptions options; options.SetAddToHistory(false); options.SetEchoCommands(false); options.SetPrintResults(true); options.SetPrintErrors(true); options.SetStopOnError(false); - m_interpreter.HandleCommandsFromFile(file, &clean_ctx, options, result); + m_interpreter.HandleCommandsFromFile(file, options, result); return result.Succeeded(); } @@ -544,7 +536,6 @@ protected: } else { result.AppendErrorWithFormat("invalid property path '%s'", property_path); - result.SetStatus(eReturnStatusFailed); } } } else { @@ -625,7 +616,6 @@ protected: "or an array followed by one or more indexes, or a " "dictionary followed by one or more key names to " "remove"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -633,7 +623,6 @@ protected: if ((var_name == nullptr) || (var_name[0] == '\0')) { result.AppendError( "'settings remove' command requires a valid variable name"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -645,7 +634,6 @@ protected: &m_exe_ctx, eVarSetOperationRemove, var_name, var_value)); if (error.Fail()) { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -729,7 +717,6 @@ protected: if ((var_name == nullptr) || (var_name[0] == '\0')) { result.AppendError("'settings replace' command requires a valid variable " "name; No value supplied"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -741,7 +728,6 @@ protected: &m_exe_ctx, eVarSetOperationReplace, var_name, var_value)); if (error.Fail()) { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } else { result.SetStatus(eReturnStatusSuccessFinishNoResult); @@ -823,7 +809,6 @@ protected: if (argc < 3) { result.AppendError("'settings insert-before' takes more arguments"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -831,7 +816,6 @@ protected: if ((var_name == nullptr) || (var_name[0] == '\0')) { result.AppendError("'settings insert-before' command requires a valid " "variable name; No value supplied"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -843,7 +827,6 @@ protected: &m_exe_ctx, eVarSetOperationInsertBefore, var_name, var_value)); if (error.Fail()) { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -922,7 +905,6 @@ protected: if (argc < 3) { result.AppendError("'settings insert-after' takes more arguments"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -930,7 +912,6 @@ protected: if ((var_name == nullptr) || (var_name[0] == '\0')) { result.AppendError("'settings insert-after' command requires a valid " "variable name; No value supplied"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -942,7 +923,6 @@ protected: &m_exe_ctx, eVarSetOperationInsertAfter, var_name, var_value)); if (error.Fail()) { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1009,7 +989,6 @@ protected: if (argc < 2) { result.AppendError("'settings append' takes more arguments"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1017,7 +996,6 @@ protected: if ((var_name == nullptr) || (var_name[0] == '\0')) { result.AppendError("'settings append' command requires a valid variable " "name; No value supplied"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1032,7 +1010,6 @@ protected: &m_exe_ctx, eVarSetOperationAppend, var_name, var_value)); if (error.Fail()) { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1118,7 +1095,6 @@ protected: if (m_options.m_clear_all) { if (argc != 0) { result.AppendError("'settings clear --all' doesn't take any arguments"); - result.SetStatus(eReturnStatusFailed); return false; } GetDebugger().GetValueProperties()->Clear(); @@ -1127,7 +1103,6 @@ protected: if (argc != 1) { result.AppendError("'settings clear' takes exactly one argument"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1135,7 +1110,6 @@ protected: if ((var_name == nullptr) || (var_name[0] == '\0')) { result.AppendError("'settings clear' command requires a valid variable " "name; No value supplied"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1143,7 +1117,6 @@ protected: &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef())); if (error.Fail()) { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.cpp index 8fff22a06366..7a0338e35bc7 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.cpp @@ -541,7 +541,6 @@ protected: if (argc != 0) { result.AppendErrorWithFormat("'%s' takes no arguments, only flags.\n", GetCommandName().str().c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -551,7 +550,6 @@ protected: if (target == nullptr) { result.AppendError("invalid target, create a debug target using the " "'target create' command."); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -575,12 +573,10 @@ protected: } if (!m_module_list.GetSize()) { result.AppendError("No modules match the input."); - result.SetStatus(eReturnStatusFailed); return false; } } else if (target->GetImages().GetSize() == 0) { result.AppendError("The target has no associated executable images."); - result.SetStatus(eReturnStatusFailed); return false; } @@ -811,7 +807,6 @@ protected: result.AppendErrorWithFormat("Could not find line information for " "start of function: \"%s\".\n", source_info.function.GetCString()); - result.SetStatus(eReturnStatusFailed); return 0; } sc.function->GetEndLineSourceInfo(end_file, end_line); @@ -933,7 +928,6 @@ protected: if (argc != 0) { result.AppendErrorWithFormat("'%s' takes no arguments, only flags.\n", GetCommandName().str().c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -971,7 +965,6 @@ protected: if (num_matches == 0) { result.AppendErrorWithFormat("Could not find function named: \"%s\".\n", m_options.symbol_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1038,7 +1031,6 @@ protected: "no modules have source information for file address 0x%" PRIx64 ".\n", m_options.address); - result.SetStatus(eReturnStatusFailed); return false; } } else { @@ -1061,7 +1053,6 @@ protected: "is no line table information " "available for this address.\n", error_strm.GetData()); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -1071,7 +1062,6 @@ protected: result.AppendErrorWithFormat( "no modules contain load address 0x%" PRIx64 ".\n", m_options.address); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -1191,7 +1181,6 @@ protected: if (num_matches == 0) { result.AppendErrorWithFormat("Could not find source file \"%s\".\n", m_options.file_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1215,7 +1204,6 @@ protected: result.AppendErrorWithFormat( "Multiple source files found matching: \"%s.\"\n", m_options.file_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -1245,7 +1233,6 @@ protected: } else { result.AppendErrorWithFormat("No comp unit found for: \"%s.\"\n", m_options.file_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectStats.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectStats.cpp index 6b06581f5a8f..23c7dbbaf373 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectStats.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectStats.cpp @@ -28,7 +28,6 @@ protected: if (target.GetCollectingStats()) { result.AppendError("statistics already enabled"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -53,7 +52,6 @@ protected: if (!target.GetCollectingStats()) { result.AppendError("need to enable statistics before disabling them"); - result.SetStatus(eReturnStatusFailed); return false; } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp index 1cb21384fd2a..b25514b1ffbc 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp @@ -158,9 +158,9 @@ static constexpr OptionEnumValueElement g_dependents_enumaration[] = { class OptionGroupDependents : public OptionGroup { public: - OptionGroupDependents() {} + OptionGroupDependents() = default; - ~OptionGroupDependents() override {} + ~OptionGroupDependents() override = default; llvm::ArrayRef<OptionDefinition> GetDefinitions() override { return llvm::makeArrayRef(g_target_dependents_options); @@ -278,7 +278,6 @@ protected: result.AppendErrorWithFormatv("Cannot open '{0}': {1}.", core_file.GetPath(), llvm::toString(file.takeError())); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -293,7 +292,6 @@ protected: result.AppendErrorWithFormatv("Cannot open '{0}': {1}.", symfile.GetPath(), llvm::toString(file.takeError())); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -320,7 +318,6 @@ protected: if (!target_sp) { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -344,7 +341,6 @@ protected: Status err = platform_sp->PutFile(file_spec, remote_file); if (err.Fail()) { result.AppendError(err.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -359,20 +355,17 @@ protected: Status err = platform_sp->GetFile(remote_file, file_spec); if (err.Fail()) { result.AppendError(err.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } } else { // make up a local file result.AppendError("remote --> local transfer without local " "path is not implemented yet"); - result.SetStatus(eReturnStatusFailed); return false; } } } else { result.AppendError("no platform found for target"); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -414,7 +407,6 @@ protected: if (error.Fail()) { result.AppendError( error.AsCString("can't find plug-in for core file")); - result.SetStatus(eReturnStatusFailed); return false; } else { result.AppendMessageWithFormatv( @@ -427,7 +419,6 @@ protected: result.AppendErrorWithFormatv( "Unable to find process plug-in for core file '{0}'\n", core_file.GetPath()); - result.SetStatus(eReturnStatusFailed); } } else { result.AppendMessageWithFormat( @@ -441,7 +432,6 @@ protected: result.AppendErrorWithFormat("'%s' takes exactly one executable path " "argument, or use the --core option.\n", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); @@ -482,7 +472,6 @@ protected: result.SetStatus(eReturnStatusSuccessFinishResult); } else { result.AppendError("the 'target list' command takes no arguments\n"); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -524,17 +513,14 @@ protected: "index %u is out of range since there are no active targets\n", target_idx); } - result.SetStatus(eReturnStatusFailed); } } else { result.AppendErrorWithFormat("invalid index string value '%s'\n", target_idx_arg); - result.SetStatus(eReturnStatusFailed); } } else { result.AppendError( "'target select' takes a single argument: a target index\n"); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -584,7 +570,6 @@ protected: // Bail out if don't have any targets. if (num_targets == 0) { result.AppendError("no targets to delete"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -593,7 +578,6 @@ protected: if (entry.ref().getAsInteger(0, target_idx)) { result.AppendErrorWithFormat("invalid target index '%s'\n", entry.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } if (target_idx < num_targets) { @@ -612,14 +596,12 @@ protected: "target index %u is out of range, the only valid index is 0\n", target_idx); - result.SetStatus(eReturnStatusFailed); return false; } } else { target_sp = target_list.GetSelectedTarget(); if (!target_sp) { result.AppendErrorWithFormat("no target is currently selected\n"); - result.SetStatus(eReturnStatusFailed); return false; } delete_target_list.push_back(target_sp); @@ -848,12 +830,10 @@ protected: size_t matches = 0; bool use_var_name = false; if (m_option_variable.use_regex) { - RegularExpression regex( - llvm::StringRef::withNullAsEmpty(arg.c_str())); + RegularExpression regex(arg.ref()); if (!regex.IsValid()) { result.GetErrorStream().Printf( "error: invalid regular expression: '%s'\n", arg.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } use_var_name = true; @@ -868,9 +848,8 @@ protected: } if (matches == 0) { - result.GetErrorStream().Printf( - "error: can't find global variable '%s'\n", arg.c_str()); - result.SetStatus(eReturnStatusFailed); + result.AppendErrorWithFormat("can't find global variable '%s'", + arg.c_str()); return false; } else { for (uint32_t global_idx = 0; global_idx < matches; ++global_idx) { @@ -931,7 +910,6 @@ protected: } else result.AppendError("'target variable' takes one or more global " "variable names as arguments\n"); - result.SetStatus(eReturnStatusFailed); } } else { SymbolContextList sc_list; @@ -1054,7 +1032,6 @@ protected: const size_t argc = command.GetArgumentCount(); if (argc & 1) { result.AppendError("add requires an even number of arguments\n"); - result.SetStatus(eReturnStatusFailed); } else { for (size_t i = 0; i < argc; i += 2) { const char *from = command.GetArgumentAtIndex(i); @@ -1078,7 +1055,6 @@ protected: result.AppendError("<path-prefix> can't be empty\n"); else result.AppendError("<new-path-prefix> can't be empty\n"); - result.SetStatus(eReturnStatusFailed); } } } @@ -1186,7 +1162,6 @@ protected: result.AppendErrorWithFormat( "<index> parameter is not an integer: '%s'.\n", command.GetArgumentAtIndex(0)); - result.SetStatus(eReturnStatusFailed); return result.Succeeded(); } @@ -1208,13 +1183,11 @@ protected: result.AppendError("<path-prefix> can't be empty\n"); else result.AppendError("<new-path-prefix> can't be empty\n"); - result.SetStatus(eReturnStatusFailed); return false; } } } else { result.AppendError("insert requires at least three arguments\n"); - result.SetStatus(eReturnStatusFailed); return result.Succeeded(); } return result.Succeeded(); @@ -1239,7 +1212,6 @@ protected: Target *target = &GetSelectedTarget(); if (command.GetArgumentCount() != 0) { result.AppendError("list takes no arguments\n"); - result.SetStatus(eReturnStatusFailed); return result.Succeeded(); } @@ -1280,7 +1252,6 @@ protected: Target *target = &GetSelectedTarget(); if (command.GetArgumentCount() != 1) { result.AppendError("query requires one argument\n"); - result.SetStatus(eReturnStatusFailed); return result.Succeeded(); } @@ -1900,7 +1871,6 @@ protected: target->GetImages()); if (num_dumped == 0) { result.AppendError("the target has no associated executable images"); - result.SetStatus(eReturnStatusFailed); } } else { // Find the modules that match the basename or full path. @@ -1925,7 +1895,6 @@ protected: result.SetStatus(eReturnStatusSuccessFinishResult); } else { result.AppendError("no matching executable images found"); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -1970,7 +1939,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() : Options(), m_sort_order(eSortOrderNone) {} + CommandOptions() : Options() {} ~CommandOptions() override = default; @@ -2006,7 +1975,7 @@ public: return llvm::makeArrayRef(g_target_modules_dump_symtab_options); } - SortOrder m_sort_order; + SortOrder m_sort_order = eSortOrderNone; OptionValueBoolean m_prefer_mangled = {false, false}; }; @@ -2044,7 +2013,6 @@ protected: } } else { result.AppendError("the target has no associated executable images"); - result.SetStatus(eReturnStatusFailed); return false; } } else { @@ -2081,7 +2049,6 @@ protected: result.SetStatus(eReturnStatusSuccessFinishResult); else { result.AppendError("no matching executable images found"); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -2119,7 +2086,6 @@ protected: const size_t num_modules = target->GetImages().GetSize(); if (num_modules == 0) { result.AppendError("the target has no associated executable images"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -2168,7 +2134,6 @@ protected: result.SetStatus(eReturnStatusSuccessFinishResult); else { result.AppendError("no matching executable images found"); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -2198,7 +2163,6 @@ protected: const size_t num_modules = module_list.GetSize(); if (num_modules == 0) { result.AppendError("the target has no associated executable images"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -2276,7 +2240,6 @@ protected: const size_t num_modules = target_modules.GetSize(); if (num_modules == 0) { result.AppendError("the target has no associated executable images"); - result.SetStatus(eReturnStatusFailed); return false; } result.GetOutputStream().Format( @@ -2316,7 +2279,6 @@ protected: result.SetStatus(eReturnStatusSuccessFinishResult); else { result.AppendError("no matching executable images found"); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -2352,7 +2314,6 @@ protected: if (command.GetArgumentCount() == 0) { result.AppendError("file option must be specified."); - result.SetStatus(eReturnStatusFailed); return result.Succeeded(); } else { // Dump specified images (by basename or fullpath) @@ -2389,7 +2350,6 @@ protected: result.SetStatus(eReturnStatusSuccessFinishResult); else { result.AppendError("no source filenames matched any command arguments"); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -2535,7 +2495,6 @@ protected: "or symbol file with UUID %s", strm.GetData()); } - result.SetStatus(eReturnStatusFailed); return false; } } else { @@ -2544,13 +2503,11 @@ protected: result.AppendErrorWithFormat( "Unable to locate the executable or symbol file with UUID %s", strm.GetData()); - result.SetStatus(eReturnStatusFailed); return false; } } else { result.AppendError( "one or more executable image paths must be specified"); - result.SetStatus(eReturnStatusFailed); return false; } } else { @@ -2579,7 +2536,6 @@ protected: else result.AppendErrorWithFormat("unsupported module: %s", entry.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } else { flush = true; @@ -2587,7 +2543,6 @@ protected: result.SetStatus(eReturnStatusSuccessFinishResult); } else { std::string resolved_path = file_spec.GetPath(); - result.SetStatus(eReturnStatusFailed); if (resolved_path != entry.ref()) { result.AppendErrorWithFormat( "invalid module path '%s' with resolved path '%s'\n", @@ -2685,12 +2640,10 @@ protected: search_using_module_spec = false; result.AppendErrorWithFormat( "more than 1 module matched by name '%s'\n", arg_cstr); - result.SetStatus(eReturnStatusFailed); } else { search_using_module_spec = false; result.AppendErrorWithFormat("no object file for module '%s'\n", arg_cstr); - result.SetStatus(eReturnStatusFailed); } } @@ -2724,7 +2677,6 @@ protected: } else { result.AppendError("one or more section name + load " "address pair must be specified"); - result.SetStatus(eReturnStatusFailed); return false; } } else { @@ -2732,7 +2684,6 @@ protected: result.AppendError("The \"--slide <offset>\" option can't " "be used in conjunction with setting " "section load addresses.\n"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -2751,7 +2702,6 @@ protected: "thread specific sections are not yet " "supported (section '%s')\n", sect_name); - result.SetStatus(eReturnStatusFailed); break; } else { if (target->GetSectionLoadList() @@ -2766,13 +2716,11 @@ protected: "matches the section " "name '%s'\n", sect_name); - result.SetStatus(eReturnStatusFailed); break; } } else { result.AppendErrorWithFormat( "invalid load address string '%s'\n", load_addr_cstr); - result.SetStatus(eReturnStatusFailed); break; } } else { @@ -2782,7 +2730,6 @@ protected: else result.AppendError("one or more section name + load " "address pair must be specified.\n"); - result.SetStatus(eReturnStatusFailed); break; } } @@ -2825,7 +2772,6 @@ protected: result.AppendErrorWithFormat("failed to set PC value to " "0x%" PRIx64 "\n", file_entry_addr); - result.SetStatus(eReturnStatusFailed); } } } @@ -2833,13 +2779,11 @@ protected: module->GetFileSpec().GetPath(path, sizeof(path)); result.AppendErrorWithFormat("no sections in object file '%s'\n", path); - result.SetStatus(eReturnStatusFailed); } } else { module->GetFileSpec().GetPath(path, sizeof(path)); result.AppendErrorWithFormat("no object file for module '%s'\n", path); - result.SetStatus(eReturnStatusFailed); } } else { FileSpec *module_spec_file = module_spec.GetFileSpecPtr(); @@ -2848,7 +2792,6 @@ protected: result.AppendErrorWithFormat("invalid module '%s'.\n", path); } else result.AppendError("no module spec"); - result.SetStatus(eReturnStatusFailed); } } else { std::string uuid_str; @@ -2876,12 +2819,10 @@ protected: path[0] ? " file=" : "", path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str()); } - result.SetStatus(eReturnStatusFailed); } } else { result.AppendError("either the \"--file <module>\" or the \"--uuid " "<uuid>\" option must be specified.\n"); - result.SetStatus(eReturnStatusFailed); return false; } return result.Succeeded(); @@ -2903,9 +2844,7 @@ class CommandObjectTargetModulesList : public CommandObjectParsed { public: class CommandOptions : public Options { public: - CommandOptions() - : Options(), m_format_array(), m_use_global_module_list(false), - m_module_addr(LLDB_INVALID_ADDRESS) {} + CommandOptions() : Options(), m_format_array() {} ~CommandOptions() override = default; @@ -2940,8 +2879,8 @@ public: // Instance variables to hold the values for command options. typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection; FormatWidthCollection m_format_array; - bool m_use_global_module_list; - lldb::addr_t m_module_addr; + bool m_use_global_module_list = false; + lldb::addr_t m_module_addr = LLDB_INVALID_ADDRESS; }; CommandObjectTargetModulesList(CommandInterpreter &interpreter) @@ -2966,7 +2905,6 @@ protected: if (target == nullptr && !use_global_module_list) { result.AppendError("invalid target, create a debug target using the " "'target create' command"); - result.SetStatus(eReturnStatusFailed); return false; } else { if (target) { @@ -2990,18 +2928,15 @@ protected: result.AppendErrorWithFormat( "Couldn't find module matching address: 0x%" PRIx64 ".", m_options.m_module_addr); - result.SetStatus(eReturnStatusFailed); } } else { result.AppendErrorWithFormat( "Couldn't find module containing address: 0x%" PRIx64 ".", m_options.m_module_addr); - result.SetStatus(eReturnStatusFailed); } } else { result.AppendError( "Can only look up modules by address with a valid target."); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -3033,7 +2968,6 @@ protected: if (argc == 1) { result.AppendErrorWithFormat("no modules found that match '%s'", arg.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -3080,7 +3014,6 @@ protected: result.AppendError( "the target has no associated executable images"); } - result.SetStatus(eReturnStatusFailed); return false; } } @@ -3254,9 +3187,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() - : Options(), m_type(eLookupTypeInvalid), m_str(), - m_addr(LLDB_INVALID_ADDRESS) {} + CommandOptions() : Options(), m_str() {} ~CommandOptions() override = default; @@ -3302,9 +3233,10 @@ public: // Instance variables to hold the values for command options. - int m_type; // Should be a eLookupTypeXXX enum after parsing options + int m_type = eLookupTypeInvalid; // Should be a eLookupTypeXXX enum after + // parsing options std::string m_str; // Holds name lookup - lldb::addr_t m_addr; // Holds the address to lookup + lldb::addr_t m_addr = LLDB_INVALID_ADDRESS; // Holds the address to lookup }; CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter) @@ -3330,21 +3262,18 @@ protected: if (process == nullptr) { result.AppendError( "You must have a process running to use this command."); - result.SetStatus(eReturnStatusFailed); return false; } ThreadList threads(process->GetThreadList()); if (threads.GetSize() == 0) { result.AppendError("The process must be paused to use this command."); - result.SetStatus(eReturnStatusFailed); return false; } ThreadSP thread(threads.GetThreadAtIndex(0)); if (!thread) { result.AppendError("The process must be paused to use this command."); - result.SetStatus(eReturnStatusFailed); return false; } @@ -3369,7 +3298,6 @@ protected: } else { result.AppendError( "address-expression or function name option must be specified."); - result.SetStatus(eReturnStatusFailed); return false; } @@ -3377,7 +3305,6 @@ protected: if (num_matches == 0) { result.AppendErrorWithFormat("no unwind data found that matches '%s'.", m_options.m_str.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -3894,7 +3821,6 @@ protected: std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex()); if (target_modules.GetSize() == 0) { result.AppendError("the target has no associated executable images"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -4064,7 +3990,6 @@ protected: if (!symbol_fspec) { result.AppendError( "one or more executable image paths must be specified"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -4146,7 +4071,6 @@ protected: "use the --uuid option to resolve the " "ambiguity.\n", symfile_path); - result.SetStatus(eReturnStatusFailed); return false; } @@ -4213,7 +4137,6 @@ protected: !llvm::sys::fs::is_regular_file(symbol_fspec.GetPath()) ? "\n please specify the full path to the symbol file" : ""); - result.SetStatus(eReturnStatusFailed); return false; } @@ -4425,11 +4348,7 @@ class CommandObjectTargetStopHookAdd : public CommandObjectParsed, public: class CommandOptions : public OptionGroup { public: - CommandOptions() - : OptionGroup(), m_line_start(0), m_line_end(UINT_MAX), - m_func_name_type_mask(eFunctionNameTypeAuto), - m_sym_ctx_specified(false), m_thread_specified(false), - m_use_one_liner(false), m_one_liner() {} + CommandOptions() : OptionGroup(), m_line_end(UINT_MAX), m_one_liner() {} ~CommandOptions() override = default; @@ -4556,20 +4475,21 @@ public: std::string m_class_name; std::string m_function_name; - uint32_t m_line_start; + uint32_t m_line_start = 0; uint32_t m_line_end; std::string m_file_name; std::string m_module_name; - uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType. + uint32_t m_func_name_type_mask = + eFunctionNameTypeAuto; // A pick from lldb::FunctionNameType. lldb::tid_t m_thread_id; uint32_t m_thread_index; std::string m_thread_name; std::string m_queue_name; - bool m_sym_ctx_specified; + bool m_sym_ctx_specified = false; bool m_no_inlines; - bool m_thread_specified; + bool m_thread_specified = false; // Instance variables to hold the values for one_liner options. - bool m_use_one_liner; + bool m_use_one_liner = false; std::vector<std::string> m_one_liner; bool m_auto_continue; @@ -4602,7 +4522,7 @@ Python Based Stop Hooks: When the stop hook is added, the class is initialized by calling: - def __init__(self, target, extra_args, dict): + def __init__(self, target, extra_args, internal_dict): target: The target that the stop hook is being added to. extra_args: An SBStructuredData Dictionary filled with the -key -value @@ -4780,7 +4700,6 @@ protected: // FIXME: Set the stop hook ID counter back. result.AppendErrorWithFormat("Couldn't add stop hook: %s", error.AsCString()); - result.SetStatus(eReturnStatusFailed); target.UndoCreateStopHook(new_hook_sp->GetID()); return false; } @@ -4841,13 +4760,11 @@ protected: if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) { result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); - result.SetStatus(eReturnStatusFailed); return false; } if (!target.RemoveStopHookByID(user_id)) { result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -4896,14 +4813,12 @@ protected: if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) { result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); - result.SetStatus(eReturnStatusFailed); return false; } success = target.SetStopHookActiveStateByID(user_id, m_enable); if (!success) { result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); - result.SetStatus(eReturnStatusFailed); return false; } } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.cpp index f4ce5cc599cb..7247601b292b 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.cpp @@ -8,9 +8,11 @@ #include "CommandObjectThread.h" +#include <memory> #include <sstream> #include "CommandObjectThreadUtil.h" +#include "CommandObjectTrace.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/ValueObject.h" #include "lldb/Host/OptionParser.h" @@ -31,6 +33,7 @@ #include "lldb/Target/ThreadPlan.h" #include "lldb/Target/ThreadPlanStepInRange.h" #include "lldb/Target/Trace.h" +#include "lldb/Target/TraceInstructionDumper.h" #include "lldb/Utility/State.h" using namespace lldb; @@ -153,7 +156,6 @@ protected: result.AppendErrorWithFormat( "thread disappeared while computing backtraces: 0x%" PRIx64 "\n", tid); - result.SetStatus(eReturnStatusFailed); return false; } @@ -172,7 +174,6 @@ protected: result.AppendErrorWithFormat( "error displaying backtrace for thread: \"0x%4.4x\"\n", thread->GetIndexID()); - result.SetStatus(eReturnStatusFailed); return false; } if (m_options.m_extended_backtrace) { @@ -384,7 +385,6 @@ protected: if (thread == nullptr) { result.AppendError("no selected thread in process"); - result.SetStatus(eReturnStatusFailed); return false; } } else { @@ -394,7 +394,6 @@ protected: if (!llvm::to_integer(thread_idx_cstr, step_thread_idx)) { result.AppendErrorWithFormat("invalid thread index '%s'.\n", thread_idx_cstr); - result.SetStatus(eReturnStatusFailed); return false; } thread = @@ -403,7 +402,6 @@ protected: result.AppendErrorWithFormat( "Thread index %u is out of range (valid values are 0 - %u).\n", step_thread_idx, num_threads); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -411,14 +409,12 @@ protected: if (m_step_type == eStepTypeScripted) { if (m_class_options.GetName().empty()) { result.AppendErrorWithFormat("empty class name for scripted step."); - result.SetStatus(eReturnStatusFailed); return false; } else if (!GetDebugger().GetScriptInterpreter()->CheckObjectExists( m_class_options.GetName().c_str())) { result.AppendErrorWithFormat( "class for scripted step: \"%s\" does not exist.", m_class_options.GetName().c_str()); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -427,7 +423,6 @@ protected: m_step_type != eStepTypeInto) { result.AppendErrorWithFormat( "end line option is only valid for step into"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -460,7 +455,6 @@ protected: error)) { result.AppendErrorWithFormat("invalid end-line option: %s.", error.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } } else if (m_options.m_end_line_is_block_end) { @@ -468,7 +462,6 @@ protected: Block *block = frame->GetSymbolContext(eSymbolContextBlock).block; if (!block) { result.AppendErrorWithFormat("Could not find the current block."); - result.SetStatus(eReturnStatusFailed); return false; } @@ -478,7 +471,6 @@ protected: if (!block_range.GetBaseAddress().IsValid()) { result.AppendErrorWithFormat( "Could not find the current block address."); - result.SetStatus(eReturnStatusFailed); return false; } lldb::addr_t pc_offset_in_block = @@ -537,7 +529,6 @@ protected: new_plan_status); } else { result.AppendError("step type is not supported"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -569,7 +560,6 @@ protected: if (!error.Success()) { result.AppendMessage(error.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -593,7 +583,6 @@ protected: } } else { result.SetError(new_plan_status); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -649,7 +638,6 @@ public: Process *process = m_exe_ctx.GetProcessPtr(); if (process == nullptr) { result.AppendError("no process exists. Cannot continue"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -670,7 +658,6 @@ public: if (entry.ref().getAsInteger(0, thread_idx)) { result.AppendErrorWithFormat( "invalid thread index argument: \"%s\".\n", entry.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } Thread *thread = @@ -681,14 +668,12 @@ public: } else { result.AppendErrorWithFormat("invalid thread index %u.\n", thread_idx); - result.SetStatus(eReturnStatusFailed); return false; } } if (resume_threads.empty()) { result.AppendError("no valid thread indexes were specified"); - result.SetStatus(eReturnStatusFailed); return false; } else { if (resume_threads.size() == 1) @@ -728,7 +713,6 @@ public: Thread *current_thread = GetDefaultThread(); if (current_thread == nullptr) { result.AppendError("the process doesn't have a current thread"); - result.SetStatus(eReturnStatusFailed); return false; } // Set the actions that the threads should each take when resuming @@ -771,13 +755,11 @@ public: } else { result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString()); - result.SetStatus(eReturnStatusFailed); } } else { result.AppendErrorWithFormat( "Process cannot be continued from its current state (%s).\n", StateAsCString(state)); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); @@ -801,12 +783,10 @@ class CommandObjectThreadUntil : public CommandObjectParsed { public: class CommandOptions : public Options { public: - uint32_t m_thread_idx; - uint32_t m_frame_idx; + uint32_t m_thread_idx = LLDB_INVALID_THREAD_ID; + uint32_t m_frame_idx = LLDB_INVALID_FRAME_ID; - CommandOptions() - : Options(), m_thread_idx(LLDB_INVALID_THREAD_ID), - m_frame_idx(LLDB_INVALID_FRAME_ID) { + CommandOptions() : Options() { // Keep default values of all options in one place: OptionParsingStarting // () OptionParsingStarting(nullptr); @@ -917,7 +897,6 @@ protected: Process *process = m_exe_ctx.GetProcessPtr(); if (process == nullptr) { result.AppendError("need a valid process to step"); - result.SetStatus(eReturnStatusFailed); } else { Thread *thread = nullptr; std::vector<uint32_t> line_numbers; @@ -929,7 +908,6 @@ protected: if (!llvm::to_integer(command.GetArgumentAtIndex(i), line_number)) { result.AppendErrorWithFormat("invalid line number: '%s'.\n", command.GetArgumentAtIndex(i)); - result.SetStatus(eReturnStatusFailed); return false; } else line_numbers.push_back(line_number); @@ -937,7 +915,6 @@ protected: } else if (m_options.m_until_addrs.empty()) { result.AppendErrorWithFormat("No line number or address provided:\n%s", GetSyntax().str().c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -954,7 +931,6 @@ protected: result.AppendErrorWithFormat( "Thread index %u is out of range (valid values are 0 - %u).\n", m_options.m_thread_idx, num_threads); - result.SetStatus(eReturnStatusFailed); return false; } @@ -966,7 +942,6 @@ protected: result.AppendErrorWithFormat( "Frame index %u is out of range for thread %u.\n", m_options.m_frame_idx, m_options.m_thread_idx); - result.SetStatus(eReturnStatusFailed); return false; } @@ -986,7 +961,6 @@ protected: "frame %u of thread index %u.\n", m_options.m_frame_idx, m_options.m_thread_idx); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1046,7 +1020,6 @@ protected: result.AppendErrorWithFormat( "Until target outside of the current function.\n"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1062,14 +1035,12 @@ protected: new_plan_sp->SetOkayToDiscard(false); } else { result.SetError(new_plan_status); - result.SetStatus(eReturnStatusFailed); return false; } } else { result.AppendErrorWithFormat( "Frame index %u of thread %u has no debug information.\n", m_options.m_frame_idx, m_options.m_thread_idx); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1099,7 +1070,6 @@ protected: } else { result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString()); - result.SetStatus(eReturnStatusFailed); } } return result.Succeeded(); @@ -1151,13 +1121,11 @@ protected: Process *process = m_exe_ctx.GetProcessPtr(); if (process == nullptr) { result.AppendError("no process"); - result.SetStatus(eReturnStatusFailed); return false; } else if (command.GetArgumentCount() != 1) { result.AppendErrorWithFormat( "'%s' takes exactly one thread index argument:\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1165,7 +1133,6 @@ protected: if (!llvm::to_integer(command.GetArgumentAtIndex(0), index_id)) { result.AppendErrorWithFormat("Invalid thread index '%s'", command.GetArgumentAtIndex(0)); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1174,7 +1141,6 @@ protected: if (new_thread == nullptr) { result.AppendErrorWithFormat("invalid thread #%s.\n", command.GetArgumentAtIndex(0)); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1293,7 +1259,6 @@ public: if (!thread_sp) { result.AppendErrorWithFormat("thread no longer exists: 0x%" PRIx64 "\n", tid); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1305,7 +1270,6 @@ public: m_options.m_json_stopinfo)) { result.AppendErrorWithFormat("error displaying info for thread: \"%d\"\n", thread->GetIndexID()); - result.SetStatus(eReturnStatusFailed); return false; } return true; @@ -1343,7 +1307,6 @@ public: if (!thread_sp) { result.AppendErrorWithFormat("thread no longer exists: 0x%" PRIx64 "\n", tid); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1373,7 +1336,7 @@ class CommandObjectThreadReturn : public CommandObjectRaw { public: class CommandOptions : public Options { public: - CommandOptions() : Options(), m_from_expression(false) { + CommandOptions() : Options() { // Keep default values of all options in one place: OptionParsingStarting // () OptionParsingStarting(nullptr); @@ -1413,7 +1376,7 @@ public: return llvm::makeArrayRef(g_thread_return_options); } - bool m_from_expression; + bool m_from_expression = false; // Instance variables to hold the values for command options. }; @@ -1466,7 +1429,6 @@ protected: if (!error.Success()) { result.AppendErrorWithFormat("Unwinding expression failed - %s.", error.AsCString()); - result.SetStatus(eReturnStatusFailed); } else { bool success = thread->SetSelectedFrameByIndexNoisily(0, result.GetOutputStream()); @@ -1476,7 +1438,6 @@ protected: } else { result.AppendErrorWithFormat( "Could not select 0th frame after unwinding expression."); - result.SetStatus(eReturnStatusFailed); } } return result.Succeeded(); @@ -1489,7 +1450,6 @@ protected: if (frame_sp->IsInlined()) { result.AppendError("Don't know how to return from inlined frames."); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1511,7 +1471,6 @@ protected: else result.AppendErrorWithFormat( "Unknown error evaluating result expression."); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -1524,7 +1483,6 @@ protected: result.AppendErrorWithFormat( "Error returning from frame %d of thread %d: %s.", frame_idx, thread_sp->GetIndexID(), error.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1626,14 +1584,12 @@ protected: lldb::addr_t callAddr = dest.GetCallableLoadAddress(target); if (callAddr == LLDB_INVALID_ADDRESS) { result.AppendErrorWithFormat("Invalid destination address."); - result.SetStatus(eReturnStatusFailed); return false; } if (!reg_ctx->SetPC(callAddr)) { result.AppendErrorWithFormat("Error changing PC value for thread %d.", thread->GetIndexID()); - result.SetStatus(eReturnStatusFailed); return false; } } else { @@ -1650,7 +1606,6 @@ protected: if (!file) { result.AppendErrorWithFormat( "No source file available for the current location."); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1775,9 +1730,8 @@ public: true /* condense_trivial */, m_options.m_unreported); // If we didn't find a TID, stop here and return an error. if (!success) { - result.SetError("Error dumping plans:"); + result.AppendError("Error dumping plans:"); result.AppendError(tmp_strm.GetString()); - result.SetStatus(eReturnStatusFailed); return false; } // Otherwise, add our data to the output: @@ -1854,7 +1808,6 @@ public: result.AppendErrorWithFormat("Too many arguments, expected one - the " "thread plan index - but got %zu.", args.GetArgumentCount()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1863,14 +1816,12 @@ public: result.AppendErrorWithFormat( "Invalid thread index: \"%s\" - should be unsigned int.", args.GetArgumentAtIndex(0)); - result.SetStatus(eReturnStatusFailed); return false; } if (thread_plan_idx == 0) { result.AppendErrorWithFormat( "You wouldn't really want me to discard the base thread plan."); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1881,7 +1832,6 @@ public: result.AppendErrorWithFormat( "Could not find User thread plan with index %s.", args.GetArgumentAtIndex(0)); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -1920,11 +1870,11 @@ public: bool DoExecute(Args &args, CommandReturnObject &result) override { Process *process = m_exe_ctx.GetProcessPtr(); - + if (args.GetArgumentCount() == 0) { process->PruneThreadPlans(); result.SetStatus(eReturnStatusSuccessFinishNoResult); - return true; + return true; } const size_t num_args = args.GetArgumentCount(); @@ -1937,13 +1887,11 @@ public: if (!llvm::to_integer(args.GetArgumentAtIndex(i), tid)) { result.AppendErrorWithFormat("invalid thread specification: \"%s\"\n", args.GetArgumentAtIndex(i)); - result.SetStatus(eReturnStatusFailed); return false; } if (!process->PruneThreadPlansForTID(tid)) { result.AppendErrorWithFormat("Could not find unreported tid: \"%s\"\n", args.GetArgumentAtIndex(i)); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -1976,77 +1924,61 @@ public: // Next are the subcommands of CommandObjectMultiwordTrace +// CommandObjectTraceExport + +class CommandObjectTraceExport : public CommandObjectMultiword { +public: + CommandObjectTraceExport(CommandInterpreter &interpreter) + : CommandObjectMultiword( + interpreter, "trace thread export", + "Commands for exporting traces of the threads in the current " + "process to different formats.", + "thread trace export <export-plugin> [<subcommand objects>]") { + + for (uint32_t i = 0; true; i++) { + if (const char *plugin_name = + PluginManager::GetTraceExporterPluginNameAtIndex(i)) { + if (ThreadTraceExportCommandCreator command_creator = + PluginManager::GetThreadTraceExportCommandCreatorAtIndex(i)) { + LoadSubCommand(plugin_name, command_creator(interpreter)); + } + } else { + break; + } + } + } +}; + // CommandObjectTraceStart -/// This class works by delegating the logic to the actual trace plug-in that -/// can support the current process. -class CommandObjectTraceStart : public CommandObjectProxy { +class CommandObjectTraceStart : public CommandObjectTraceProxy { public: CommandObjectTraceStart(CommandInterpreter &interpreter) - : CommandObjectProxy(interpreter, "thread trace start", - "Start tracing threads with the corresponding trace " - "plug-in for the current process.", - "thread trace start [<trace-options>]") {} + : CommandObjectTraceProxy( + /*live_debug_session_only=*/true, interpreter, "thread trace start", + "Start tracing threads with the corresponding trace " + "plug-in for the current process.", + "thread trace start [<trace-options>]") {} protected: - llvm::Expected<CommandObjectSP> DoGetProxyCommandObject() { - ProcessSP process_sp = m_interpreter.GetExecutionContext().GetProcessSP(); - - if (!process_sp) - return llvm::createStringError(llvm::inconvertibleErrorCode(), - "Process not available."); - if (!process_sp->IsAlive()) - return llvm::createStringError(llvm::inconvertibleErrorCode(), - "Process must be launched."); - - llvm::Expected<TraceTypeInfo> trace_type = - process_sp->GetSupportedTraceType(); - - if (!trace_type) - return llvm::createStringError( - llvm::inconvertibleErrorCode(), "Tracing is not supported. %s", - llvm::toString(trace_type.takeError()).c_str()); - - CommandObjectSP delegate_sp = - PluginManager::GetTraceStartCommand(trace_type->name, m_interpreter); - if (!delegate_sp) - return llvm::createStringError( - llvm::inconvertibleErrorCode(), - "No trace plug-in matches the specified type: \"%s\"", - trace_type->name.c_str()); - return delegate_sp; - } - - CommandObject *GetProxyCommandObject() override { - if (llvm::Expected<CommandObjectSP> delegate = DoGetProxyCommandObject()) { - m_delegate_sp = *delegate; - m_delegate_error.clear(); - return m_delegate_sp.get(); - } else { - m_delegate_sp.reset(); - m_delegate_error = llvm::toString(delegate.takeError()); - return nullptr; - } + lldb::CommandObjectSP GetDelegateCommand(Trace &trace) override { + return trace.GetThreadTraceStartCommand(m_interpreter); } - -private: - llvm::StringRef GetUnsupportedError() override { return m_delegate_error; } - - CommandObjectSP m_delegate_sp; - std::string m_delegate_error; }; // CommandObjectTraceStop -class CommandObjectTraceStop : public CommandObjectIterateOverThreads { +class CommandObjectTraceStop : public CommandObjectMultipleThreads { public: CommandObjectTraceStop(CommandInterpreter &interpreter) - : CommandObjectIterateOverThreads( + : CommandObjectMultipleThreads( interpreter, "thread trace stop", - "Stop tracing threads. " + "Stop tracing threads, including the ones traced with the " + "\"process trace start\" command." "Defaults to the current thread. Thread indices can be " - "specified as arguments.\n Use the thread-index \"all\" to trace " - "all threads.", + "specified as arguments.\n Use the thread-index \"all\" to stop " + "tracing " + "for all existing threads.", "thread trace stop [<thread-index> <thread-index> ...]", eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused | @@ -2054,20 +1986,18 @@ public: ~CommandObjectTraceStop() override = default; - bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override { - const Thread &thread = - *m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid); - Trace &trace = *m_exe_ctx.GetTargetSP()->GetTrace(); + bool DoExecuteOnThreads(Args &command, CommandReturnObject &result, + llvm::ArrayRef<lldb::tid_t> tids) override { + ProcessSP process_sp = m_exe_ctx.GetProcessSP(); - if (llvm::Error err = trace.StopTracingThread(thread)) { - result.AppendErrorWithFormat("Failed stopping thread %" PRIu64 ": %s\n", - tid, toString(std::move(err)).c_str()); - result.SetStatus(eReturnStatusFailed); - } + TraceSP trace_sp = process_sp->GetTarget().GetTrace(); - // We don't return false on errors to try to stop as many threads as - // possible. - return true; + if (llvm::Error err = trace_sp->Stop(tids)) + result.AppendError(toString(std::move(err))); + else + result.SetStatus(eReturnStatusSuccessFinishResult); + + return result.Succeeded(); } }; @@ -2101,21 +2031,28 @@ public: m_count = count; break; } - case 'p': { - int32_t position; - if (option_arg.empty() || option_arg.getAsInteger(0, position) || - position < 0) + case 's': { + int32_t skip; + if (option_arg.empty() || option_arg.getAsInteger(0, skip) || skip < 0) error.SetErrorStringWithFormat( "invalid integer value for option '%s'", option_arg.str().c_str()); else - m_position = position; + m_skip = skip; break; } case 'r': { m_raw = true; break; } + case 'f': { + m_forwards = true; + break; + } + case 't': { + m_show_tsc = true; + break; + } default: llvm_unreachable("Unimplemented option"); } @@ -2124,8 +2061,10 @@ public: void OptionParsingStarting(ExecutionContext *execution_context) override { m_count = kDefaultCount; - m_position = llvm::None; + m_skip = 0; m_raw = false; + m_forwards = false; + m_show_tsc = false; } llvm::ArrayRef<OptionDefinition> GetDefinitions() override { @@ -2136,14 +2075,16 @@ public: // Instance variables to hold the values for command options. size_t m_count; - llvm::Optional<ssize_t> m_position; + size_t m_skip; bool m_raw; + bool m_forwards; + bool m_show_tsc; }; CommandObjectTraceDumpInstructions(CommandInterpreter &interpreter) : CommandObjectIterateOverThreads( interpreter, "thread trace dump instructions", - "Dump the traced instructions for one or more threads. If no " + "Dump the traced instructions for one or more threads. If no " "threads are specified, show the current thread. Use the " "thread-index \"all\" to see all threads.", nullptr, @@ -2160,14 +2101,14 @@ public: uint32_t index) override { current_command_args.GetCommandString(m_repeat_command); m_create_repeat_command_just_invoked = true; - m_consecutive_repetitions = 0; return m_repeat_command.c_str(); } protected: bool DoExecute(Args &args, CommandReturnObject &result) override { - if (IsRepeatCommand()) - m_consecutive_repetitions++; + if (!IsRepeatCommand()) + m_dumpers.clear(); + bool status = CommandObjectIterateOverThreads::DoExecute(args, result); m_create_repeat_command_just_invoked = false; @@ -2179,19 +2120,38 @@ protected: } bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override { + Stream &s = result.GetOutputStream(); + const TraceSP &trace_sp = m_exe_ctx.GetTargetSP()->GetTrace(); ThreadSP thread_sp = m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid); - size_t count = m_options.m_count; - ssize_t position = m_options.m_position.getValueOr( - trace_sp->GetCursorPosition(*thread_sp)) - - m_consecutive_repetitions * count; - if (position < 0) - result.SetError("error: no more data"); - else - trace_sp->DumpTraceInstructions(*thread_sp, result.GetOutputStream(), - count, position, m_options.m_raw); + if (!m_dumpers.count(thread_sp->GetID())) { + lldb::TraceCursorUP cursor_up = trace_sp->GetCursor(*thread_sp); + // Set up the cursor and return the presentation index of the first + // instruction to dump after skipping instructions. + auto setUpCursor = [&]() { + cursor_up->SetForwards(m_options.m_forwards); + if (m_options.m_forwards) + return cursor_up->Seek(m_options.m_skip, TraceCursor::SeekType::Set); + return -cursor_up->Seek(-m_options.m_skip, TraceCursor::SeekType::End); + }; + + int initial_index = setUpCursor(); + + auto dumper = std::make_unique<TraceInstructionDumper>( + std::move(cursor_up), initial_index, m_options.m_raw, + m_options.m_show_tsc); + + // This happens when the seek value was more than the number of available + // instructions. + if (std::abs(initial_index) < (int)m_options.m_skip) + dumper->SetNoMoreData(); + + m_dumpers[thread_sp->GetID()] = std::move(dumper); + } + + m_dumpers[thread_sp->GetID()]->DumpInstructions(s, m_options.m_count); return true; } @@ -2200,7 +2160,84 @@ protected: // Repeat command helpers std::string m_repeat_command; bool m_create_repeat_command_just_invoked; - size_t m_consecutive_repetitions = 0; + std::map<lldb::tid_t, std::unique_ptr<TraceInstructionDumper>> m_dumpers; +}; + +// CommandObjectTraceDumpInfo +#define LLDB_OPTIONS_thread_trace_dump_info +#include "CommandOptions.inc" + +class CommandObjectTraceDumpInfo : public CommandObjectIterateOverThreads { +public: + class CommandOptions : public Options { + public: + CommandOptions() : Options() { OptionParsingStarting(nullptr); } + + ~CommandOptions() override = default; + + Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, + ExecutionContext *execution_context) override { + Status error; + const int short_option = m_getopt_table[option_idx].val; + + switch (short_option) { + case 'v': { + m_verbose = true; + break; + } + default: + llvm_unreachable("Unimplemented option"); + } + return error; + } + + void OptionParsingStarting(ExecutionContext *execution_context) override { + m_verbose = false; + } + + llvm::ArrayRef<OptionDefinition> GetDefinitions() override { + return llvm::makeArrayRef(g_thread_trace_dump_info_options); + } + + // Instance variables to hold the values for command options. + bool m_verbose; + }; + + bool DoExecute(Args &command, CommandReturnObject &result) override { + Target &target = m_exe_ctx.GetTargetRef(); + result.GetOutputStream().Printf( + "Trace technology: %s\n", + target.GetTrace()->GetPluginName().AsCString()); + return CommandObjectIterateOverThreads::DoExecute(command, result); + } + + CommandObjectTraceDumpInfo(CommandInterpreter &interpreter) + : CommandObjectIterateOverThreads( + interpreter, "thread trace dump info", + "Dump the traced information for one or more threads. If no " + "threads are specified, show the current thread. Use the " + "thread-index \"all\" to see all threads.", + nullptr, + eCommandRequiresProcess | eCommandTryTargetAPILock | + eCommandProcessMustBeLaunched | eCommandProcessMustBePaused | + eCommandProcessMustBeTraced), + m_options() {} + + ~CommandObjectTraceDumpInfo() override = default; + + Options *GetOptions() override { return &m_options; } + +protected: + bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override { + const TraceSP &trace_sp = m_exe_ctx.GetTargetSP()->GetTrace(); + ThreadSP thread_sp = + m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid); + trace_sp->DumpTraceInfo(*thread_sp, result.GetOutputStream(), + m_options.m_verbose); + return true; + } + + CommandOptions m_options; }; // CommandObjectMultiwordTraceDump @@ -2215,6 +2252,8 @@ public: LoadSubCommand( "instructions", CommandObjectSP(new CommandObjectTraceDumpInstructions(interpreter))); + LoadSubCommand( + "info", CommandObjectSP(new CommandObjectTraceDumpInfo(interpreter))); } ~CommandObjectMultiwordTraceDump() override = default; }; @@ -2234,6 +2273,8 @@ public: CommandObjectSP(new CommandObjectTraceStart(interpreter))); LoadSubCommand("stop", CommandObjectSP(new CommandObjectTraceStop(interpreter))); + LoadSubCommand("export", + CommandObjectSP(new CommandObjectTraceExport(interpreter))); } ~CommandObjectMultiwordTrace() override = default; diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.cpp index b93698c7be60..d330da7e684e 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.cpp @@ -58,7 +58,6 @@ bool CommandObjectIterateOverThreads::DoExecute(Args &command, if (!llvm::to_integer(command.GetArgumentAtIndex(i), thread_idx)) { result.AppendErrorWithFormat("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i)); - result.SetStatus(eReturnStatusFailed); return false; } @@ -68,7 +67,6 @@ bool CommandObjectIterateOverThreads::DoExecute(Args &command, if (!thread) { result.AppendErrorWithFormat("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i)); - result.SetStatus(eReturnStatusFailed); return false; } @@ -129,7 +127,6 @@ bool CommandObjectIterateOverThreads::BucketThread( Thread *thread = process->GetThreadList().FindThreadByID(tid).get(); if (thread == nullptr) { result.AppendErrorWithFormatv("Failed to process thread #{0}.\n", tid); - result.SetStatus(eReturnStatusFailed); return false; } @@ -156,3 +153,45 @@ bool CommandObjectIterateOverThreads::BucketThread( } return true; } + +bool CommandObjectMultipleThreads::DoExecute(Args &command, + CommandReturnObject &result) { + Process &process = m_exe_ctx.GetProcessRef(); + + std::vector<lldb::tid_t> tids; + const size_t num_args = command.GetArgumentCount(); + + std::lock_guard<std::recursive_mutex> guard( + process.GetThreadList().GetMutex()); + + if (num_args > 0 && ::strcmp(command.GetArgumentAtIndex(0), "all") == 0) { + for (ThreadSP thread_sp : process.Threads()) + tids.push_back(thread_sp->GetID()); + } else { + if (num_args == 0) { + Thread &thread = m_exe_ctx.GetThreadRef(); + tids.push_back(thread.GetID()); + } + + for (size_t i = 0; i < num_args; i++) { + uint32_t thread_idx; + if (!llvm::to_integer(command.GetArgumentAtIndex(i), thread_idx)) { + result.AppendErrorWithFormat("invalid thread specification: \"%s\"\n", + command.GetArgumentAtIndex(i)); + return false; + } + + ThreadSP thread = process.GetThreadList().FindThreadByIndexID(thread_idx); + + if (!thread) { + result.AppendErrorWithFormat("no thread with index: \"%s\"\n", + command.GetArgumentAtIndex(i)); + return false; + } + + tids.push_back(thread->GetID()); + } + } + + return DoExecuteOnThreads(command, result, tids); +} diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.h index 7122982d8943..289ffdfc1894 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.h @@ -76,6 +76,26 @@ protected: bool m_add_return = true; }; +/// Class similar to \a CommandObjectIterateOverThreads, but which performs +/// an action on multiple threads at once instead of iterating over each thread. +class CommandObjectMultipleThreads : public CommandObjectParsed { +public: + using CommandObjectParsed::CommandObjectParsed; + + bool DoExecute(Args &command, CommandReturnObject &result) override; + +protected: + /// Method that handles the command after the main arguments have been parsed. + /// + /// \param[in] tids + /// The thread ids passed as arguments. + /// + /// \return + /// A boolean result similar to the one expected from \a DoExecute. + virtual bool DoExecuteOnThreads(Args &command, CommandReturnObject &result, + llvm::ArrayRef<lldb::tid_t> tids) = 0; +}; + } // namespace lldb_private #endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTTHREADUTIL_H diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.cpp index 170630b85b2e..c55fed45d4f4 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.cpp @@ -23,6 +23,7 @@ #include "lldb/Interpreter/OptionValueLanguage.h" #include "lldb/Interpreter/OptionValueString.h" #include "lldb/Interpreter/Options.h" +#include "lldb/Target/Process.h" #include "lldb/Target/Trace.h" using namespace lldb; @@ -86,14 +87,12 @@ protected: result.AppendError( "a single path to a JSON file containing a trace session" "is required"); - result.SetStatus(eReturnStatusFailed); return false; } auto end_with_failure = [&result](llvm::Error err) -> bool { result.AppendErrorWithFormat("%s\n", llvm::toString(std::move(err)).c_str()); - result.SetStatus(eReturnStatusFailed); return false; }; @@ -113,10 +112,11 @@ protected: return end_with_failure(session_file.takeError()); if (Expected<lldb::TraceSP> traceOrErr = - Trace::FindPlugin(GetDebugger(), *session_file, - json_file.GetDirectory().AsCString())) { + Trace::FindPluginForPostMortemProcess( + GetDebugger(), *session_file, + json_file.GetDirectory().AsCString())) { lldb::TraceSP trace_sp = traceOrErr.get(); - if (m_options.m_verbose) + if (m_options.m_verbose && trace_sp) result.AppendMessageWithFormat("loading trace with plugin %s\n", trace_sp->GetPluginName().AsCString()); } else @@ -188,7 +188,6 @@ protected: result.SetStatus(eReturnStatusSuccessFinishResult); } else { result.AppendErrorWithFormat("%s\n", error.AsCString()); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -252,7 +251,7 @@ protected: bool DoExecute(Args &command, CommandReturnObject &result) override { Status error; if (command.empty()) { - result.SetError( + result.AppendError( "trace schema cannot be invoked without a plug-in as argument"); return false; } @@ -279,7 +278,6 @@ protected: result.SetStatus(eReturnStatusSuccessFinishResult); } else { result.AppendErrorWithFormat("%s\n", error.AsCString()); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -303,3 +301,33 @@ CommandObjectTrace::CommandObjectTrace(CommandInterpreter &interpreter) } CommandObjectTrace::~CommandObjectTrace() = default; + +Expected<CommandObjectSP> CommandObjectTraceProxy::DoGetProxyCommandObject() { + ProcessSP process_sp = m_interpreter.GetExecutionContext().GetProcessSP(); + + if (!process_sp) + return createStringError(inconvertibleErrorCode(), + "Process not available."); + if (m_live_debug_session_only && !process_sp->IsLiveDebugSession()) + return createStringError(inconvertibleErrorCode(), + "Process must be alive."); + + if (Expected<TraceSP> trace_sp = process_sp->GetTarget().GetTraceOrCreate()) + return GetDelegateCommand(**trace_sp); + else + return createStringError(inconvertibleErrorCode(), + "Tracing is not supported. %s", + toString(trace_sp.takeError()).c_str()); +} + +CommandObject *CommandObjectTraceProxy::GetProxyCommandObject() { + if (Expected<CommandObjectSP> delegate = DoGetProxyCommandObject()) { + m_delegate_sp = *delegate; + m_delegate_error.clear(); + return m_delegate_sp.get(); + } else { + m_delegate_sp.reset(); + m_delegate_error = toString(delegate.takeError()); + return nullptr; + } +} diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.h index 2dca0e26b243..b96a3094cefc 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.h @@ -9,7 +9,7 @@ #ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTTRACE_H #define LLDB_SOURCE_COMMANDS_COMMANDOBJECTTRACE_H -#include "lldb/Interpreter/CommandObjectMultiword.h" +#include "CommandObjectThreadUtil.h" namespace lldb_private { @@ -20,6 +20,32 @@ public: ~CommandObjectTrace() override; }; +/// This class works by delegating the logic to the actual trace plug-in that +/// can support the current process. +class CommandObjectTraceProxy : public CommandObjectProxy { +public: + CommandObjectTraceProxy(bool live_debug_session_only, + CommandInterpreter &interpreter, const char *name, + const char *help = nullptr, + const char *syntax = nullptr, uint32_t flags = 0) + : CommandObjectProxy(interpreter, name, help, syntax, flags), + m_live_debug_session_only(live_debug_session_only) {} + +protected: + virtual lldb::CommandObjectSP GetDelegateCommand(Trace &trace) = 0; + + llvm::Expected<lldb::CommandObjectSP> DoGetProxyCommandObject(); + + CommandObject *GetProxyCommandObject() override; + +private: + llvm::StringRef GetUnsupportedError() override { return m_delegate_error; } + + bool m_live_debug_session_only; + lldb::CommandObjectSP m_delegate_sp; + std::string m_delegate_error; +}; + } // namespace lldb_private #endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTTRACE_H diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectType.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectType.cpp index 004c066b57aa..90e224867e2a 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectType.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectType.cpp @@ -270,7 +270,7 @@ protected: static const char *g_synth_addreader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n" "You must define a Python class with these methods:\n" - " def __init__(self, valobj, dict):\n" + " def __init__(self, valobj, internal_dict):\n" " def num_children(self):\n" " def get_child_at_index(self, index):\n" " def get_child_index(self, name):\n" @@ -377,7 +377,6 @@ protected: result.AppendError("must either provide a children list, a Python class " "name, or use -P and type a Python class " "line-by-line"); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -639,7 +638,6 @@ protected: if (argc < 1) { result.AppendErrorWithFormat("%s takes one or more args.\n", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -648,7 +646,6 @@ protected: m_command_options.m_custom_type_name.empty()) { result.AppendErrorWithFormat("%s needs a valid format.\n", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -681,7 +678,6 @@ protected: for (auto &arg_entry : command.entries()) { if (arg_entry.ref().empty()) { result.AppendError("empty typenames not allowed"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -691,7 +687,6 @@ protected: if (!typeRX.IsValid()) { result.AppendError( "regex format error (maybe this is not really a regex?)"); - result.SetStatus(eReturnStatusFailed); return false; } category_sp->GetRegexTypeSummariesContainer()->Delete(typeCS); @@ -821,7 +816,6 @@ protected: if (argc != 1) { result.AppendErrorWithFormat("%s takes 1 arg.\n", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -830,7 +824,6 @@ protected: if (!typeCS) { result.AppendError("empty typenames not allowed"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -868,7 +861,6 @@ protected: return result.Succeeded(); } else { result.AppendErrorWithFormat("no custom formatter for %s.\n", typeA); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -1073,19 +1065,16 @@ protected: result.AppendErrorWithFormat( "syntax error in category regular expression '%s'", m_options.m_category_regex.GetCurrentValueAsRef().str().c_str()); - result.SetStatus(eReturnStatusFailed); return false; } } if (argc == 1) { const char *arg = command.GetArgumentAtIndex(0); - formatter_regex = std::make_unique<RegularExpression>( - llvm::StringRef::withNullAsEmpty(arg)); + formatter_regex = std::make_unique<RegularExpression>(arg); if (!formatter_regex->IsValid()) { result.AppendErrorWithFormat("syntax error in regular expression '%s'", arg); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -1167,9 +1156,7 @@ protected: bool escape = true; if (category->GetName() == category_regex->GetText()) { escape = false; - } else if (category_regex->Execute( - llvm::StringRef::withNullAsEmpty( - category->GetName()))) { + } else if (category_regex->Execute(category->GetName())) { escape = false; } @@ -1296,7 +1283,6 @@ bool CommandObjectTypeSummaryAdd::Execute_ScriptSummary( if (argc < 1 && !m_options.m_name) { result.AppendErrorWithFormat("%s takes one or more args.\n", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1308,7 +1294,6 @@ bool CommandObjectTypeSummaryAdd::Execute_ScriptSummary( const char *funct_name = m_options.m_python_function.c_str(); if (!funct_name || !funct_name[0]) { result.AppendError("function name empty.\n"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1332,7 +1317,6 @@ bool CommandObjectTypeSummaryAdd::Execute_ScriptSummary( if (!interpreter) { result.AppendError("script interpreter missing - unable to generate " "function wrapper.\n"); - result.SetStatus(eReturnStatusFailed); return false; } StringList funct_sl; @@ -1340,13 +1324,11 @@ bool CommandObjectTypeSummaryAdd::Execute_ScriptSummary( std::string funct_name_str; if (!interpreter->GenerateTypeScriptFunction(funct_sl, funct_name_str)) { result.AppendError("unable to generate function wrapper.\n"); - result.SetStatus(eReturnStatusFailed); return false; } if (funct_name_str.empty()) { result.AppendError( "script interpreter failed to generate a valid function name.\n"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1363,7 +1345,6 @@ bool CommandObjectTypeSummaryAdd::Execute_ScriptSummary( for (auto &entry : command.entries()) { if (entry.ref().empty()) { result.AppendError("empty typenames not allowed"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1392,7 +1373,6 @@ bool CommandObjectTypeSummaryAdd::Execute_ScriptSummary( m_options.m_category, &error); if (error.Fail()) { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -1403,7 +1383,6 @@ bool CommandObjectTypeSummaryAdd::Execute_ScriptSummary( if (error.Fail()) { result.AppendError(error.AsCString()); result.AppendError("added to types, but not given a name"); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -1420,14 +1399,12 @@ bool CommandObjectTypeSummaryAdd::Execute_StringSummary( if (argc < 1 && !m_options.m_name) { result.AppendErrorWithFormat("%s takes one or more args.\n", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } if (!m_options.m_flags.GetShowMembersOneLiner() && m_options.m_format_string.empty()) { result.AppendError("empty summary strings not allowed"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1438,7 +1415,6 @@ bool CommandObjectTypeSummaryAdd::Execute_StringSummary( // ${var%S} is an endless recursion, prevent it if (strcmp(format_cstr, "${var%S}") == 0) { result.AppendError("recursive summary not allowed"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1446,13 +1422,11 @@ bool CommandObjectTypeSummaryAdd::Execute_StringSummary( new StringSummaryFormat(m_options.m_flags, format_cstr)); if (!string_format) { result.AppendError("summary creation failed"); - result.SetStatus(eReturnStatusFailed); return false; } if (string_format->m_error.Fail()) { result.AppendErrorWithFormat("syntax error: %s", string_format->m_error.AsCString("<unknown>")); - result.SetStatus(eReturnStatusFailed); return false; } lldb::TypeSummaryImplSP entry(string_format.release()); @@ -1462,7 +1436,6 @@ bool CommandObjectTypeSummaryAdd::Execute_StringSummary( for (auto &arg_entry : command.entries()) { if (arg_entry.ref().empty()) { result.AppendError("empty typenames not allowed"); - result.SetStatus(eReturnStatusFailed); return false; } ConstString typeCS(arg_entry.ref()); @@ -1473,7 +1446,6 @@ bool CommandObjectTypeSummaryAdd::Execute_StringSummary( if (error.Fail()) { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -1484,7 +1456,6 @@ bool CommandObjectTypeSummaryAdd::Execute_StringSummary( if (error.Fail()) { result.AppendError(error.AsCString()); result.AppendError("added to types, but not given a name"); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -1613,7 +1584,6 @@ bool CommandObjectTypeSummaryAdd::DoExecute(Args &command, return Execute_ScriptSummary(command, result); #else result.AppendError("python is disabled"); - result.SetStatus(eReturnStatusFailed); return false; #endif } @@ -1820,7 +1790,6 @@ protected: if (argc < 1) { result.AppendErrorWithFormat("%s takes 1 or more args.\n", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1924,7 +1893,6 @@ protected: if (argc < 1 && m_options.m_language == lldb::eLanguageTypeUnknown) { result.AppendErrorWithFormat("%s takes arguments and/or a language", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1937,7 +1905,6 @@ protected: if (!typeCS) { result.AppendError("empty category name not allowed"); - result.SetStatus(eReturnStatusFailed); return false; } DataVisualization::Categories::Enable(typeCS); @@ -1994,7 +1961,6 @@ protected: if (argc < 1) { result.AppendErrorWithFormat("%s takes 1 or more arg.\n", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -2007,7 +1973,6 @@ protected: if (!typeCS) { result.AppendError("empty category name not allowed"); - result.SetStatus(eReturnStatusFailed); return false; } if (!DataVisualization::Categories::Delete(typeCS)) @@ -2018,7 +1983,6 @@ protected: return result.Succeeded(); } else { result.AppendError("cannot delete one or more categories\n"); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -2107,7 +2071,6 @@ protected: if (argc < 1 && m_options.m_language == lldb::eLanguageTypeUnknown) { result.AppendErrorWithFormat("%s takes arguments and/or a language", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -2121,7 +2084,6 @@ protected: if (!typeCS) { result.AppendError("empty category name not allowed"); - result.SetStatus(eReturnStatusFailed); return false; } DataVisualization::Categories::Disable(typeCS); @@ -2175,18 +2137,15 @@ protected: if (argc == 1) { const char *arg = command.GetArgumentAtIndex(0); - regex = std::make_unique<RegularExpression>( - llvm::StringRef::withNullAsEmpty(arg)); + regex = std::make_unique<RegularExpression>(arg); if (!regex->IsValid()) { result.AppendErrorWithFormat( "syntax error in category regular expression '%s'", arg); - result.SetStatus(eReturnStatusFailed); return false; } } else if (argc != 0) { result.AppendErrorWithFormat("%s takes 0 or one arg.\n", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -2196,8 +2155,7 @@ protected: bool escape = true; if (regex->GetText() == category_sp->GetName()) { escape = false; - } else if (regex->Execute(llvm::StringRef::withNullAsEmpty( - category_sp->GetName()))) { + } else if (regex->Execute(category_sp->GetName())) { escape = false; } @@ -2305,7 +2263,6 @@ bool CommandObjectTypeSynthAdd::Execute_HandwritePython( for (auto &entry : command.entries()) { if (entry.ref().empty()) { result.AppendError("empty typenames not allowed"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -2328,7 +2285,6 @@ bool CommandObjectTypeSynthAdd::Execute_PythonClass( if (argc < 1) { result.AppendErrorWithFormat("%s takes one or more args.\n", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -2336,7 +2292,6 @@ bool CommandObjectTypeSynthAdd::Execute_PythonClass( result.AppendErrorWithFormat("%s needs either a Python class name or -P to " "directly input Python code.\n", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -2369,7 +2324,6 @@ bool CommandObjectTypeSynthAdd::Execute_PythonClass( for (auto &arg_entry : command.entries()) { if (arg_entry.ref().empty()) { result.AppendError("empty typenames not allowed"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -2378,7 +2332,6 @@ bool CommandObjectTypeSynthAdd::Execute_PythonClass( m_options.m_regex ? eRegexSynth : eRegularSynth, m_options.m_category, &error)) { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -2633,14 +2586,12 @@ protected: if (argc < 1) { result.AppendErrorWithFormat("%s takes one or more args.\n", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } if (m_options.m_expr_paths.empty()) { result.AppendErrorWithFormat("%s needs one or more children.\n", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -2670,7 +2621,6 @@ protected: for (auto &arg_entry : command.entries()) { if (arg_entry.ref().empty()) { result.AppendError("empty typenames not allowed"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -2679,7 +2629,6 @@ protected: m_options.m_regex ? eRegexFilter : eRegularFilter, m_options.m_category, &error)) { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -2717,8 +2666,7 @@ protected: class CommandOptions : public OptionGroup { public: - CommandOptions() - : OptionGroup(), m_show_help(false), m_language(eLanguageTypeUnknown) {} + CommandOptions() : OptionGroup() {} ~CommandOptions() override = default; @@ -2755,8 +2703,8 @@ protected: // Options table: Required for subclasses of Options. - bool m_show_help; - lldb::LanguageType m_language; + bool m_show_help = false; + lldb::LanguageType m_language = eLanguageTypeUnknown; }; OptionGroupOptions m_option_group; @@ -2796,7 +2744,7 @@ public: bool DoExecute(llvm::StringRef raw_command_line, CommandReturnObject &result) override { if (raw_command_line.empty()) { - result.SetError( + result.AppendError( "type lookup cannot be invoked without a type name as argument"); return false; } @@ -2927,7 +2875,6 @@ protected: Thread *thread = GetDefaultThread(); if (!thread) { result.AppendError("no default thread"); - result.SetStatus(lldb::eReturnStatusFailed); return false; } @@ -2960,7 +2907,6 @@ protected: return true; } else { result.AppendError("failed to evaluate expression"); - result.SetStatus(lldb::eReturnStatusFailed); return false; } } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectVersion.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectVersion.cpp index 065cbe4660d3..20c2d25b745c 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectVersion.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectVersion.cpp @@ -20,7 +20,7 @@ CommandObjectVersion::CommandObjectVersion(CommandInterpreter &interpreter) : CommandObjectParsed(interpreter, "version", "Show the LLDB debugger version.", "version") {} -CommandObjectVersion::~CommandObjectVersion() {} +CommandObjectVersion::~CommandObjectVersion() = default; bool CommandObjectVersion::DoExecute(Args &args, CommandReturnObject &result) { if (args.GetArgumentCount() == 0) { @@ -28,7 +28,6 @@ bool CommandObjectVersion::DoExecute(Args &args, CommandReturnObject &result) { result.SetStatus(eReturnStatusSuccessFinishResult); } else { result.AppendError("the version command takes no arguments."); - result.SetStatus(eReturnStatusFailed); } return true; } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.cpp index e7b1f31f3960..d7a446fc366c 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.cpp @@ -42,7 +42,6 @@ static bool CheckTargetForWatchpointOperations(Target *target, target->GetProcessSP() && target->GetProcessSP()->IsAlive(); if (!process_is_valid) { result.AppendError("There's no process or it is not alive."); - result.SetStatus(eReturnStatusFailed); return false; } // Target passes our checks, return true. @@ -166,11 +165,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() - : Options(), - m_level(lldb::eDescriptionLevelBrief) // Watchpoint List defaults to - // brief descriptions - {} + CommandOptions() : Options() {} ~CommandOptions() override = default; @@ -206,7 +201,7 @@ public: // Instance variables to hold the values for command options. - lldb::DescriptionLevel m_level; + lldb::DescriptionLevel m_level = lldb::eDescriptionLevelBrief; }; protected: @@ -252,7 +247,6 @@ protected: if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs( target, command, wp_ids)) { result.AppendError("Invalid watchpoints specification."); - result.SetStatus(eReturnStatusFailed); return false; } @@ -315,7 +309,6 @@ protected: if (num_watchpoints == 0) { result.AppendError("No watchpoints exist to be enabled."); - result.SetStatus(eReturnStatusFailed); return false; } @@ -332,7 +325,6 @@ protected: if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs( target, command, wp_ids)) { result.AppendError("Invalid watchpoints specification."); - result.SetStatus(eReturnStatusFailed); return false; } @@ -392,7 +384,6 @@ protected: if (num_watchpoints == 0) { result.AppendError("No watchpoints exist to be disabled."); - result.SetStatus(eReturnStatusFailed); return false; } @@ -405,7 +396,6 @@ protected: result.SetStatus(eReturnStatusSuccessFinishNoResult); } else { result.AppendError("Disable all watchpoints failed\n"); - result.SetStatus(eReturnStatusFailed); } } else { // Particular watchpoints selected; disable them. @@ -413,7 +403,6 @@ protected: if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs( target, command, wp_ids)) { result.AppendError("Invalid watchpoints specification."); - result.SetStatus(eReturnStatusFailed); return false; } @@ -467,7 +456,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() : Options(), m_force(false) {} + CommandOptions() : Options() {} ~CommandOptions() override = default; @@ -495,7 +484,7 @@ public: } // Instance variables to hold the values for command options. - bool m_force; + bool m_force = false; }; protected: @@ -513,7 +502,6 @@ protected: if (num_watchpoints == 0) { result.AppendError("No watchpoints exist to be deleted."); - result.SetStatus(eReturnStatusFailed); return false; } @@ -538,7 +526,6 @@ protected: if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command, wp_ids)) { result.AppendError("Invalid watchpoints specification."); - result.SetStatus(eReturnStatusFailed); return false; } @@ -593,7 +580,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() : Options(), m_ignore_count(0) {} + CommandOptions() : Options() {} ~CommandOptions() override = default; @@ -625,7 +612,7 @@ public: // Instance variables to hold the values for command options. - uint32_t m_ignore_count; + uint32_t m_ignore_count = 0; }; protected: @@ -643,7 +630,6 @@ protected: if (num_watchpoints == 0) { result.AppendError("No watchpoints exist to be ignored."); - result.SetStatus(eReturnStatusFailed); return false; } @@ -659,7 +645,6 @@ protected: if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs( target, command, wp_ids)) { result.AppendError("Invalid watchpoints specification."); - result.SetStatus(eReturnStatusFailed); return false; } @@ -721,7 +706,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() : Options(), m_condition(), m_condition_passed(false) {} + CommandOptions() : Options(), m_condition() {} ~CommandOptions() override = default; @@ -754,7 +739,7 @@ public: // Instance variables to hold the values for command options. std::string m_condition; - bool m_condition_passed; + bool m_condition_passed = false; }; protected: @@ -772,7 +757,6 @@ protected: if (num_watchpoints == 0) { result.AppendError("No watchpoints exist to be modified."); - result.SetStatus(eReturnStatusFailed); return false; } @@ -786,7 +770,6 @@ protected: if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs( target, command, wp_ids)) { result.AppendError("Invalid watchpoints specification."); - result.SetStatus(eReturnStatusFailed); return false; } @@ -893,10 +876,8 @@ protected: // If no argument is present, issue an error message. There's no way to // set a watchpoint. if (command.GetArgumentCount() <= 0) { - result.GetErrorStream().Printf("error: required argument missing; " - "specify your program variable to watch " - "for\n"); - result.SetStatus(eReturnStatusFailed); + result.AppendError("required argument missing; " + "specify your program variable to watch for"); return false; } @@ -916,9 +897,7 @@ protected: // A simple watch variable gesture allows only one argument. if (command.GetArgumentCount() != 1) { - result.GetErrorStream().Printf( - "error: specify exactly one variable to watch for\n"); - result.SetStatus(eReturnStatusFailed); + result.AppendError("specify exactly one variable to watch for"); return false; } @@ -962,11 +941,11 @@ protected: } else { const char *error_cstr = error.AsCString(nullptr); if (error_cstr) - result.GetErrorStream().Printf("error: %s\n", error_cstr); + result.AppendError(error_cstr); else - result.GetErrorStream().Printf("error: unable to find any variable " - "expression path that matches '%s'\n", - command.GetArgumentAtIndex(0)); + result.AppendErrorWithFormat("unable to find any variable " + "expression path that matches '%s'", + command.GetArgumentAtIndex(0)); return false; } @@ -997,7 +976,6 @@ protected: addr, (uint64_t)size, command.GetArgumentAtIndex(0)); if (error.AsCString(nullptr)) result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); @@ -1087,10 +1065,8 @@ protected: // If no argument is present, issue an error message. There's no way to // set a watchpoint. if (raw_command.trim().empty()) { - result.GetErrorStream().Printf("error: required argument missing; " - "specify an expression to evaluate into " - "the address to watch for\n"); - result.SetStatus(eReturnStatusFailed); + result.AppendError("required argument missing; specify an expression " + "to evaluate into the address to watch for"); return false; } @@ -1117,12 +1093,10 @@ protected: ExpressionResults expr_result = target->EvaluateExpression(expr, frame, valobj_sp, options); if (expr_result != eExpressionCompleted) { - result.GetErrorStream().Printf( - "error: expression evaluation of address to watch failed\n"); - result.GetErrorStream() << "expression evaluated: \n" << expr << "\n"; + result.AppendError("expression evaluation of address to watch failed"); + result.AppendErrorWithFormat("expression evaluated: \n%s", expr.data()); if (valobj_sp && !valobj_sp->GetError().Success()) - result.GetErrorStream() << valobj_sp->GetError().AsCString() << "\n"; - result.SetStatus(eReturnStatusFailed); + result.AppendError(valobj_sp->GetError().AsCString()); return false; } @@ -1130,9 +1104,7 @@ protected: bool success = false; addr = valobj_sp->GetValueAsUnsigned(0, &success); if (!success) { - result.GetErrorStream().Printf( - "error: expression did not evaluate to an address\n"); - result.SetStatus(eReturnStatusFailed); + result.AppendError("expression did not evaluate to an address"); return false; } @@ -1165,7 +1137,6 @@ protected: addr, (uint64_t)size); if (error.AsCString(nullptr)) result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpointCommand.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpointCommand.cpp index fe3052a775a2..1f4e95366385 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpointCommand.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpointCommand.cpp @@ -61,7 +61,9 @@ public: CommandObjectWatchpointCommandAdd(CommandInterpreter &interpreter) : CommandObjectParsed(interpreter, "add", "Add a set of LLDB commands to a watchpoint, to be " - "executed whenever the watchpoint is hit.", + "executed whenever the watchpoint is hit. " + "The commands added to the watchpoint replace any " + "commands previously added to it.", nullptr, eCommandRequiresTarget), IOHandlerDelegateMultiline("DONE", IOHandlerDelegate::Completion::LLDBCommand), @@ -301,7 +303,7 @@ are no syntax errors may indicate that a function was declared but never called. options.SetPrintErrors(true); options.SetAddToHistory(false); - debugger.GetCommandInterpreter().HandleCommands(commands, &exe_ctx, + debugger.GetCommandInterpreter().HandleCommands(commands, exe_ctx, options, result); result.GetImmediateOutputStream()->Flush(); result.GetImmediateErrorStream()->Flush(); @@ -312,10 +314,7 @@ are no syntax errors may indicate that a function was declared but never called. class CommandOptions : public Options { public: - CommandOptions() - : Options(), m_use_commands(false), m_use_script_language(false), - m_script_language(eScriptLanguageNone), m_use_one_liner(false), - m_one_liner(), m_function_name() {} + CommandOptions() : Options(), m_one_liner(), m_function_name() {} ~CommandOptions() override = default; @@ -385,12 +384,12 @@ are no syntax errors may indicate that a function was declared but never called. // Instance variables to hold the values for command options. - bool m_use_commands; - bool m_use_script_language; - lldb::ScriptLanguage m_script_language; + bool m_use_commands = false; + bool m_use_script_language = false; + lldb::ScriptLanguage m_script_language = eScriptLanguageNone; // Instance variables to hold the values for one_liner options. - bool m_use_one_liner; + bool m_use_one_liner = false; std::string m_one_liner; bool m_stop_on_error; std::string m_function_name; @@ -405,7 +404,6 @@ protected: if (num_watchpoints == 0) { result.AppendError("No watchpoints exist to have commands added"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -420,7 +418,6 @@ protected: if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command, valid_wp_ids)) { result.AppendError("Invalid watchpoints specification."); - result.SetStatus(eReturnStatusFailed); return false; } @@ -515,14 +512,12 @@ protected: if (num_watchpoints == 0) { result.AppendError("No watchpoints exist to have commands deleted"); - result.SetStatus(eReturnStatusFailed); return false; } if (command.GetArgumentCount() == 0) { result.AppendError( "No watchpoint specified from which to delete the commands"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -530,7 +525,6 @@ protected: if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command, valid_wp_ids)) { result.AppendError("Invalid watchpoints specification."); - result.SetStatus(eReturnStatusFailed); return false; } @@ -544,7 +538,6 @@ protected: wp->ClearCallback(); } else { result.AppendErrorWithFormat("Invalid watchpoint ID: %u.\n", cur_wp_id); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -587,14 +580,12 @@ protected: if (num_watchpoints == 0) { result.AppendError("No watchpoints exist for which to list commands"); - result.SetStatus(eReturnStatusFailed); return false; } if (command.GetArgumentCount() == 0) { result.AppendError( "No watchpoint specified for which to list the commands"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -602,7 +593,6 @@ protected: if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command, valid_wp_ids)) { result.AppendError("Invalid watchpoints specification."); - result.SetStatus(eReturnStatusFailed); return false; } @@ -634,7 +624,6 @@ protected: } else { result.AppendErrorWithFormat("Invalid watchpoint ID: %u.\n", cur_wp_id); - result.SetStatus(eReturnStatusFailed); } } } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandOptionsProcessLaunch.cpp b/contrib/llvm-project/lldb/source/Commands/CommandOptionsProcessLaunch.cpp index 4445457ca852..a618796156a6 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandOptionsProcessLaunch.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandOptionsProcessLaunch.cpp @@ -30,7 +30,7 @@ Status CommandOptionsProcessLaunch::SetOptionValue( uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) { Status error; - const int short_option = m_getopt_table[option_idx].val; + const int short_option = g_process_launch_options[option_idx].short_option; switch (short_option) { case 's': // Stop at program entry point @@ -130,7 +130,7 @@ Status CommandOptionsProcessLaunch::SetOptionValue( launch_info.SetShell(HostInfo::GetDefaultShell()); break; - case 'v': + case 'E': launch_info.GetEnvironment().insert(option_arg); break; diff --git a/contrib/llvm-project/lldb/source/Commands/CommandOptionsProcessLaunch.h b/contrib/llvm-project/lldb/source/Commands/CommandOptionsProcessLaunch.h index 4028d8e02cb2..d18a23245080 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandOptionsProcessLaunch.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandOptionsProcessLaunch.h @@ -1,4 +1,4 @@ -//===-- CommandOptionsProcessLaunch.h -------------------------------------===// +//===-- CommandOptionsProcessLaunch.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. @@ -16,9 +16,9 @@ namespace lldb_private { // CommandOptionsProcessLaunch -class CommandOptionsProcessLaunch : public lldb_private::Options { +class CommandOptionsProcessLaunch : public lldb_private::OptionGroup { public: - CommandOptionsProcessLaunch() : lldb_private::Options() { + CommandOptionsProcessLaunch() : lldb_private::OptionGroup() { // Keep default values of all options in one place: OptionParsingStarting // () OptionParsingStarting(nullptr); @@ -44,6 +44,6 @@ public: lldb_private::LazyBool disable_aslr; }; // CommandOptionsProcessLaunch -}; // namespace lldb_private +} // namespace lldb_private #endif // LLDB_SOURCE_COMMANDS_COMMANDOPTIONSPROCESSLAUNCH_H diff --git a/contrib/llvm-project/lldb/source/Commands/Options.td b/contrib/llvm-project/lldb/source/Commands/Options.td index d3329078893a..9c9b7c6e9b82 100644 --- a/contrib/llvm-project/lldb/source/Commands/Options.td +++ b/contrib/llvm-project/lldb/source/Commands/Options.td @@ -125,7 +125,7 @@ let Command = "breakpoint set" in { def breakpoint_set_address : Option<"address", "a">, Group<2>, Arg<"AddressOrExpression">, Required, Desc<"Set the breakpoint at the specified address. If the address maps " - "uniquely toa particular binary, then the address will be converted to " + "uniquely to a particular binary, then the address will be converted to " "a \"file\"address, so that the breakpoint will track that binary+offset " "no matter where the binary eventually loads. Alternately, if you also " "specify the module - with the -s option - then the address will be " @@ -200,7 +200,7 @@ let Command = "breakpoint set" in { def breakpoint_set_move_to_nearest_code : Option<"move-to-nearest-code", "m">, Groups<[1,9,12]>, Arg<"Boolean">, Desc<"Move breakpoints to nearest code. If not set the " - "target.move-to-nearest-codesetting is used.">; + "target.move-to-nearest-code setting is used.">; def breakpoint_set_file_colon_line : Option<"joint-specifier", "y">, Group<12>, Arg<"FileLineColumn">, Required, Completion<"SourceFile">, Desc<"A specifier in the form filename:line[:column] for setting file & line breakpoints.">; @@ -655,7 +655,7 @@ let Command = "process launch" in { Desc<"Set the current working directory to <path> when running the inferior.">; def process_launch_arch : Option<"arch", "a">, Arg<"Architecture">, Desc<"Set the architecture for the process to launch when ambiguous.">; - def process_launch_environment : Option<"environment", "v">, + def process_launch_environment : Option<"environment", "E">, Arg<"None">, Desc<"Specify an environment variable name/value string " "(--environment NAME=VALUE). Can be specified multiple times for subsequent " "environment entries.">; @@ -730,6 +730,12 @@ let Command = "process status" in { Desc<"Show verbose process status including extended crash information.">; } +let Command = "process save_core" in { + def process_save_core_style : Option<"style", "s">, Group<1>, + EnumArg<"SaveCoreStyle", "SaveCoreStyles()">, Desc<"Request a specific style " + "of corefile to be saved.">; +} + let Command = "script import" in { def script_import_allow_reload : Option<"allow-reload", "r">, Group<1>, Desc<"Allow the script to be loaded even if it was already loaded before. " @@ -739,6 +745,8 @@ let Command = "script import" in { Group<1>, Desc<"Resolve non-absolute paths relative to the location of the " "current command file. This argument can only be used when the command is " "being sourced from a file.">; + def silent : Option<"silent", "s">, Group<1>, + Desc<"If true don't print any script output while importing.">; } let Command = "script add" in { @@ -1041,16 +1049,30 @@ let Command = "thread plan list" in { } let Command = "thread trace dump instructions" in { + def thread_trace_dump_instructions_forwards: Option<"forwards", "f">, Group<1>, + Desc<"If specified, the trace is traversed forwards chronologically " + "starting at the oldest instruction. Otherwise, it starts at the most " + "recent one and the traversal is backwards.">; def thread_trace_dump_instructions_count : Option<"count", "c">, Group<1>, Arg<"Count">, - Desc<"The number of instructions to display ending at the current position.">; - def thread_trace_dump_instructions_position : Option<"position", "p">, + Desc<"The number of instructions to display starting at the most recent " + "instruction, or the oldest if --forwards is provided.">; + def thread_trace_dump_instructions_skip: Option<"skip", "s">, Group<1>, Arg<"Index">, - Desc<"The position to use instead of the current position of the trace.">; + Desc<"How many instruction to skip from the end of the trace to start " + "dumping instructions, or from the beginning if --forwards is provided">; def thread_trace_dump_instructions_raw : Option<"raw", "r">, Group<1>, Desc<"Dump only instruction address without disassembly nor symbol information.">; + def thread_trace_dump_instructions_show_tsc : Option<"tsc", "t">, + Group<1>, + Desc<"For each instruction, print the corresponding timestamp counter if available.">; +} + +let Command = "thread trace dump info" in { + def thread_trace_dump_info_verbose : Option<"verbose", "v">, Group<1>, + Desc<"show verbose thread trace dump info">; } let Command = "type summary add" in { diff --git a/contrib/llvm-project/lldb/source/Core/Address.cpp b/contrib/llvm-project/lldb/source/Core/Address.cpp index 9d52f1db8918..f0c7e2b34f99 100644 --- a/contrib/llvm-project/lldb/source/Core/Address.cpp +++ b/contrib/llvm-project/lldb/source/Core/Address.cpp @@ -7,12 +7,12 @@ //===----------------------------------------------------------------------===// #include "lldb/Core/Address.h" +#include "lldb/Core/Declaration.h" #include "lldb/Core/DumpDataExtractor.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleList.h" #include "lldb/Core/Section.h" #include "lldb/Symbol/Block.h" -#include "lldb/Symbol/Declaration.h" #include "lldb/Symbol/LineEntry.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/Symbol.h" @@ -43,9 +43,9 @@ #include <memory> #include <vector> -#include <assert.h> -#include <inttypes.h> -#include <string.h> +#include <cassert> +#include <cinttypes> +#include <cstring> namespace lldb_private { class CompileUnit; @@ -65,9 +65,9 @@ static size_t ReadBytes(ExecutionContextScope *exe_scope, TargetSP target_sp(exe_scope->CalculateTarget()); if (target_sp) { Status error; - bool prefer_file_cache = false; - return target_sp->ReadMemory(address, prefer_file_cache, dst, dst_len, - error); + bool force_live_memory = true; + return target_sp->ReadMemory(address, dst, dst_len, error, + force_live_memory); } return 0; } diff --git a/contrib/llvm-project/lldb/source/Core/AddressRange.cpp b/contrib/llvm-project/lldb/source/Core/AddressRange.cpp index 0868ac5e0888..af6e31a67da3 100644 --- a/contrib/llvm-project/lldb/source/Core/AddressRange.cpp +++ b/contrib/llvm-project/lldb/source/Core/AddressRange.cpp @@ -8,6 +8,7 @@ #include "lldb/Core/AddressRange.h" #include "lldb/Core/Module.h" +#include "lldb/Core/Section.h" #include "lldb/Target/Target.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/FileSpec.h" @@ -18,7 +19,7 @@ #include <memory> -#include <inttypes.h> +#include <cinttypes> namespace lldb_private { class SectionList; @@ -27,7 +28,7 @@ class SectionList; using namespace lldb; using namespace lldb_private; -AddressRange::AddressRange() : m_base_addr(), m_byte_size(0) {} +AddressRange::AddressRange() : m_base_addr() {} AddressRange::AddressRange(addr_t file_addr, addr_t byte_size, const SectionList *section_list) @@ -40,16 +41,24 @@ AddressRange::AddressRange(const lldb::SectionSP §ion, addr_t offset, AddressRange::AddressRange(const Address &so_addr, addr_t byte_size) : m_base_addr(so_addr), m_byte_size(byte_size) {} -AddressRange::~AddressRange() {} +AddressRange::~AddressRange() = default; + +bool AddressRange::Contains(const Address &addr) const { + SectionSP range_sect_sp = GetBaseAddress().GetSection(); + SectionSP addr_sect_sp = addr.GetSection(); + if (range_sect_sp) { + if (!addr_sect_sp || + range_sect_sp->GetModule() != addr_sect_sp->GetModule()) + return false; // Modules do not match. + } else if (addr_sect_sp) { + return false; // Range has no module but "addr" does because addr has a + // section + } + // Either the modules match, or both have no module, so it is ok to compare + // the file addresses in this case only. + return ContainsFileAddress(addr); +} -// bool -// AddressRange::Contains (const Address &addr) const -//{ -// const addr_t byte_size = GetByteSize(); -// if (byte_size) -// return addr.GetSection() == m_base_addr.GetSection() && -// (addr.GetOffset() - m_base_addr.GetOffset()) < byte_size; -//} // // bool // AddressRange::Contains (const Address *addr) const diff --git a/contrib/llvm-project/lldb/source/Core/AddressResolver.cpp b/contrib/llvm-project/lldb/source/Core/AddressResolver.cpp index 16b849b721de..87b0abd34e52 100644 --- a/contrib/llvm-project/lldb/source/Core/AddressResolver.cpp +++ b/contrib/llvm-project/lldb/source/Core/AddressResolver.cpp @@ -17,9 +17,9 @@ class ModuleList; using namespace lldb_private; // AddressResolver: -AddressResolver::AddressResolver() {} +AddressResolver::AddressResolver() = default; -AddressResolver::~AddressResolver() {} +AddressResolver::~AddressResolver() = default; void AddressResolver::ResolveAddressInModules(SearchFilter &filter, ModuleList &modules) { diff --git a/contrib/llvm-project/lldb/source/Core/AddressResolverFileLine.cpp b/contrib/llvm-project/lldb/source/Core/AddressResolverFileLine.cpp index b0d8dcdde2de..fb61a6100b0e 100644 --- a/contrib/llvm-project/lldb/source/Core/AddressResolverFileLine.cpp +++ b/contrib/llvm-project/lldb/source/Core/AddressResolverFileLine.cpp @@ -21,20 +21,18 @@ #include "lldb/lldb-enumerations.h" #include "lldb/lldb-types.h" -#include <inttypes.h> +#include <cinttypes> #include <vector> using namespace lldb; using namespace lldb_private; // AddressResolverFileLine: -AddressResolverFileLine::AddressResolverFileLine(const FileSpec &file_spec, - uint32_t line_no, - bool check_inlines) - : AddressResolver(), m_file_spec(file_spec), m_line_number(line_no), - m_inlines(check_inlines) {} +AddressResolverFileLine::AddressResolverFileLine( + SourceLocationSpec location_spec) + : AddressResolver(), m_src_location_spec(location_spec) {} -AddressResolverFileLine::~AddressResolverFileLine() {} +AddressResolverFileLine::~AddressResolverFileLine() = default; Searcher::CallbackReturn AddressResolverFileLine::SearchCallback(SearchFilter &filter, @@ -44,8 +42,9 @@ AddressResolverFileLine::SearchCallback(SearchFilter &filter, Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); - cu->ResolveSymbolContext(m_file_spec, m_line_number, m_inlines, false, - eSymbolContextEverything, sc_list); + // TODO: Handle SourceLocationSpec column information + cu->ResolveSymbolContext(m_src_location_spec, eSymbolContextEverything, + sc_list); uint32_t sc_list_size = sc_list.GetSize(); for (uint32_t i = 0; i < sc_list_size; i++) { SymbolContext sc; @@ -55,18 +54,14 @@ AddressResolverFileLine::SearchCallback(SearchFilter &filter, if (line_start.IsValid()) { AddressRange new_range(line_start, byte_size); m_address_ranges.push_back(new_range); - if (log) { - StreamString s; - // new_bp_loc->GetDescription (&s, lldb::eDescriptionLevelVerbose); - // LLDB_LOGF(log, "Added address: %s\n", s.GetData()); - } } else { LLDB_LOGF(log, "error: Unable to resolve address at file address 0x%" PRIx64 " for %s:%d\n", line_start.GetFileAddress(), - m_file_spec.GetFilename().AsCString("<Unknown>"), - m_line_number); + m_src_location_spec.GetFileSpec().GetFilename().AsCString( + "<Unknown>"), + m_src_location_spec.GetLine().getValueOr(0)); } } } @@ -78,6 +73,8 @@ lldb::SearchDepth AddressResolverFileLine::GetDepth() { } void AddressResolverFileLine::GetDescription(Stream *s) { - s->Printf("File and line address - file: \"%s\" line: %u", - m_file_spec.GetFilename().AsCString("<Unknown>"), m_line_number); + s->Printf( + "File and line address - file: \"%s\" line: %u", + m_src_location_spec.GetFileSpec().GetFilename().AsCString("<Unknown>"), + m_src_location_spec.GetLine().getValueOr(0)); } diff --git a/contrib/llvm-project/lldb/source/Core/AddressResolverName.cpp b/contrib/llvm-project/lldb/source/Core/AddressResolverName.cpp deleted file mode 100644 index 51ab6435e8fb..000000000000 --- a/contrib/llvm-project/lldb/source/Core/AddressResolverName.cpp +++ /dev/null @@ -1,198 +0,0 @@ -//===-- AddressResolverName.cpp -------------------------------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#include "lldb/Core/AddressResolverName.h" - -#include "lldb/Core/Address.h" -#include "lldb/Core/AddressRange.h" -#include "lldb/Core/Module.h" -#include "lldb/Symbol/Function.h" -#include "lldb/Symbol/Symbol.h" -#include "lldb/Symbol/SymbolContext.h" -#include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" -#include "lldb/Utility/Stream.h" -#include "lldb/lldb-enumerations.h" -#include "lldb/lldb-forward.h" -#include "lldb/lldb-types.h" -#include "llvm/ADT/StringRef.h" - -#include <memory> -#include <string> -#include <vector> - -#include <stdint.h> - -using namespace lldb; -using namespace lldb_private; - -AddressResolverName::AddressResolverName(const char *func_name, - AddressResolver::MatchType type) - : AddressResolver(), m_func_name(func_name), m_class_name(nullptr), - m_regex(), m_match_type(type) { - if (m_match_type == AddressResolver::Regexp) { - m_regex = RegularExpression(m_func_name.GetStringRef()); - if (!m_regex.IsValid()) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); - - if (log) - log->Warning("function name regexp: \"%s\" did not compile.", - m_func_name.AsCString()); - } - } -} - -AddressResolverName::AddressResolverName(RegularExpression func_regex) - : AddressResolver(), m_func_name(nullptr), m_class_name(nullptr), - m_regex(std::move(func_regex)), m_match_type(AddressResolver::Regexp) {} - -AddressResolverName::AddressResolverName(const char *class_name, - const char *method, - AddressResolver::MatchType type) - : AddressResolver(), m_func_name(method), m_class_name(class_name), - m_regex(), m_match_type(type) {} - -AddressResolverName::~AddressResolverName() = default; - -// FIXME: Right now we look at the module level, and call the module's -// "FindFunctions". -// Greg says he will add function tables, maybe at the CompileUnit level to -// accelerate function lookup. At that point, we should switch the depth to -// CompileUnit, and look in these tables. - -Searcher::CallbackReturn -AddressResolverName::SearchCallback(SearchFilter &filter, - SymbolContext &context, Address *addr) { - SymbolContextList func_list; - SymbolContextList sym_list; - - bool skip_prologue = true; - uint32_t i; - SymbolContext sc; - Address func_addr; - - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); - - if (m_class_name) { - if (log) - log->Warning("Class/method function specification not supported yet.\n"); - return Searcher::eCallbackReturnStop; - } - - const bool include_symbols = false; - const bool include_inlines = true; - switch (m_match_type) { - case AddressResolver::Exact: - if (context.module_sp) { - context.module_sp->FindSymbolsWithNameAndType(m_func_name, - eSymbolTypeCode, sym_list); - context.module_sp->FindFunctions(m_func_name, CompilerDeclContext(), - eFunctionNameTypeAuto, include_symbols, - include_inlines, func_list); - } - break; - - case AddressResolver::Regexp: - if (context.module_sp) { - context.module_sp->FindSymbolsMatchingRegExAndType( - m_regex, eSymbolTypeCode, sym_list); - context.module_sp->FindFunctions(m_regex, include_symbols, - include_inlines, func_list); - } - break; - - case AddressResolver::Glob: - if (log) - log->Warning("glob is not supported yet."); - break; - } - - // Remove any duplicates between the function list and the symbol list - if (func_list.GetSize()) { - for (i = 0; i < func_list.GetSize(); i++) { - if (!func_list.GetContextAtIndex(i, sc)) - continue; - - if (sc.function == nullptr) - continue; - uint32_t j = 0; - while (j < sym_list.GetSize()) { - SymbolContext symbol_sc; - if (sym_list.GetContextAtIndex(j, symbol_sc)) { - if (symbol_sc.symbol && symbol_sc.symbol->ValueIsAddress()) { - if (sc.function->GetAddressRange().GetBaseAddress() == - symbol_sc.symbol->GetAddressRef()) { - sym_list.RemoveContextAtIndex(j); - continue; // Don't increment j - } - } - } - - j++; - } - } - - for (i = 0; i < func_list.GetSize(); i++) { - if (func_list.GetContextAtIndex(i, sc)) { - if (sc.function) { - func_addr = sc.function->GetAddressRange().GetBaseAddress(); - addr_t byte_size = sc.function->GetAddressRange().GetByteSize(); - if (skip_prologue) { - const uint32_t prologue_byte_size = - sc.function->GetPrologueByteSize(); - if (prologue_byte_size) { - func_addr.SetOffset(func_addr.GetOffset() + prologue_byte_size); - byte_size -= prologue_byte_size; - } - } - - if (filter.AddressPasses(func_addr)) { - AddressRange new_range(func_addr, byte_size); - m_address_ranges.push_back(new_range); - } - } - } - } - } - - for (i = 0; i < sym_list.GetSize(); i++) { - if (sym_list.GetContextAtIndex(i, sc)) { - if (sc.symbol && sc.symbol->ValueIsAddress()) { - func_addr = sc.symbol->GetAddressRef(); - addr_t byte_size = sc.symbol->GetByteSize(); - - if (skip_prologue) { - const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize(); - if (prologue_byte_size) { - func_addr.SetOffset(func_addr.GetOffset() + prologue_byte_size); - byte_size -= prologue_byte_size; - } - } - - if (filter.AddressPasses(func_addr)) { - AddressRange new_range(func_addr, byte_size); - m_address_ranges.push_back(new_range); - } - } - } - } - return Searcher::eCallbackReturnContinue; -} - -lldb::SearchDepth AddressResolverName::GetDepth() { - return lldb::eSearchDepthModule; -} - -void AddressResolverName::GetDescription(Stream *s) { - s->PutCString("Address by function name: "); - - if (m_match_type == AddressResolver::Regexp) - s->Printf("'%s' (regular expression)", m_regex.GetText().str().c_str()); - else - s->Printf("'%s'", m_func_name.AsCString()); -} diff --git a/contrib/llvm-project/lldb/source/Core/Communication.cpp b/contrib/llvm-project/lldb/source/Core/Communication.cpp index b50cd0ecab5c..5640e0510cf1 100644 --- a/contrib/llvm-project/lldb/source/Core/Communication.cpp +++ b/contrib/llvm-project/lldb/source/Core/Communication.cpp @@ -27,9 +27,9 @@ #include <cstring> #include <memory> -#include <errno.h> -#include <inttypes.h> -#include <stdio.h> +#include <cerrno> +#include <cinttypes> +#include <cstdio> using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm-project/lldb/source/Core/CoreProperties.td b/contrib/llvm-project/lldb/source/Core/CoreProperties.td index f0653334c448..f1147ec066cd 100644 --- a/contrib/llvm-project/lldb/source/Core/CoreProperties.td +++ b/contrib/llvm-project/lldb/source/Core/CoreProperties.td @@ -51,6 +51,10 @@ let Definition = "debugger" in { DefaultEnumValue<"Debugger::eStopDisassemblyTypeNoDebugInfo">, EnumValues<"OptionEnumValues(g_show_disassembly_enum_values)">, Desc<"Control when to display disassembly when displaying a stopped context.">; + def StopDisassemblyMaxSize: Property<"stop-disassembly-max-size", "UInt64">, + Global, + DefaultUnsignedValue<32000>, + Desc<"The size limit to use when disassembling large functions (default: 32KB).">; def StopLineCountAfter: Property<"stop-line-count-after", "SInt64">, Global, DefaultUnsignedValue<3>, @@ -134,5 +138,5 @@ let Definition = "debugger" in { def ShowAutosuggestion: Property<"show-autosuggestion", "Boolean">, Global, DefaultFalse, - Desc<"If true, LLDB will show suggestions to complete the command the user typed.">; + Desc<"If true, LLDB will show suggestions to complete the command the user typed. Suggestions may be accepted using Ctrl-F.">; } diff --git a/contrib/llvm-project/lldb/source/Core/Debugger.cpp b/contrib/llvm-project/lldb/source/Core/Debugger.cpp index b16ce68c2fd2..17c3ba426f71 100644 --- a/contrib/llvm-project/lldb/source/Core/Debugger.cpp +++ b/contrib/llvm-project/lldb/source/Core/Debugger.cpp @@ -23,6 +23,7 @@ #include "lldb/Host/Terminal.h" #include "lldb/Host/ThreadLauncher.h" #include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionValue.h" #include "lldb/Interpreter/OptionValueProperties.h" #include "lldb/Interpreter/OptionValueSInt64.h" @@ -64,13 +65,13 @@ #include "llvm/Support/Threading.h" #include "llvm/Support/raw_ostream.h" +#include <cstdio> +#include <cstdlib> +#include <cstring> #include <list> #include <memory> #include <mutex> #include <set> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> #include <string> #include <system_error> @@ -258,6 +259,12 @@ const FormatEntity::Entry *Debugger::GetFrameFormatUnique() const { return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); } +uint32_t Debugger::GetStopDisassemblyMaxSize() const { + const uint32_t idx = ePropertyStopDisassemblyMaxSize; + return m_collection_sp->GetPropertyAtIndexAsUInt64( + nullptr, idx, g_debugger_properties[idx].default_uint_value); +} + bool Debugger::GetNotifyVoid() const { const uint32_t idx = ePropertyNotiftVoid; return m_collection_sp->GetPropertyAtIndexAsBoolean( @@ -598,6 +605,17 @@ void Debugger::Destroy(DebuggerSP &debugger_sp) { if (!debugger_sp) return; + CommandInterpreter &cmd_interpreter = debugger_sp->GetCommandInterpreter(); + + if (cmd_interpreter.GetSaveSessionOnQuit()) { + CommandReturnObject result(debugger_sp->GetUseColor()); + cmd_interpreter.SaveTranscript(result); + if (result.Succeeded()) + debugger_sp->GetOutputStream() << result.GetOutputData() << '\n'; + else + debugger_sp->GetErrorStream() << result.GetErrorData() << '\n'; + } + debugger_sp->Clear(); if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { @@ -655,6 +673,11 @@ TargetSP Debugger::FindTargetWithProcess(Process *process) { return target_sp; } +ConstString Debugger::GetStaticBroadcasterClass() { + static ConstString class_name("lldb.debugger"); + return class_name; +} + Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) : UserID(g_unique_id++), Properties(std::make_shared<OptionValueProperties>()), @@ -671,6 +694,8 @@ Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) m_io_handler_stack(), m_instance_name(), m_loaded_plugins(), m_event_handler_thread(), m_io_handler_thread(), m_sync_broadcaster(nullptr, "lldb.debugger.sync"), + m_broadcaster(m_broadcaster_manager_sp, + GetStaticBroadcasterClass().AsCString()), m_forward_listener_sp(), m_clear_once() { m_instance_name.SetString(llvm::formatv("debugger_{0}", GetID()).str()); if (log_callback) @@ -748,12 +773,9 @@ void Debugger::Clear() { StopIOHandlerThread(); StopEventHandlerThread(); m_listener_sp->Clear(); - int num_targets = m_target_list.GetNumTargets(); - for (int i = 0; i < num_targets; i++) { - TargetSP target_sp(m_target_list.GetTargetAtIndex(i)); + for (TargetSP target_sp : m_target_list.Targets()) { if (target_sp) { - ProcessSP process_sp(target_sp->GetProcessSP()); - if (process_sp) + if (ProcessSP process_sp = target_sp->GetProcessSP()) process_sp->Finalize(); target_sp->Destroy(); } @@ -816,24 +838,9 @@ void Debugger::SaveInputTerminalState() { void Debugger::RestoreInputTerminalState() { m_terminal_state.Restore(); } ExecutionContext Debugger::GetSelectedExecutionContext() { - ExecutionContext exe_ctx; - TargetSP target_sp(GetSelectedTarget()); - exe_ctx.SetTargetSP(target_sp); - - if (target_sp) { - ProcessSP process_sp(target_sp->GetProcessSP()); - exe_ctx.SetProcessSP(process_sp); - if (process_sp && !process_sp->IsRunning()) { - ThreadSP thread_sp(process_sp->GetThreadList().GetSelectedThread()); - if (thread_sp) { - exe_ctx.SetThreadSP(thread_sp); - exe_ctx.SetFrameSP(thread_sp->GetSelectedFrame()); - if (exe_ctx.GetFramePtr() == nullptr) - exe_ctx.SetFrameSP(thread_sp->GetStackFrameAtIndex(0)); - } - } - } - return exe_ctx; + bool adopt_selected = true; + ExecutionContextRef exe_ctx_ref(GetSelectedTarget().get(), adopt_selected); + return ExecutionContext(exe_ctx_ref); } void Debugger::DispatchInputInterrupt() { @@ -1146,6 +1153,74 @@ void Debugger::SetLoggingCallback(lldb::LogOutputCallback log_callback, std::make_shared<StreamCallback>(log_callback, baton); } +ConstString Debugger::ProgressEventData::GetFlavorString() { + static ConstString g_flavor("Debugger::ProgressEventData"); + return g_flavor; +} + +ConstString Debugger::ProgressEventData::GetFlavor() const { + return Debugger::ProgressEventData::GetFlavorString(); +} + +void Debugger::ProgressEventData::Dump(Stream *s) const { + s->Printf(" id = %" PRIu64 ", message = \"%s\"", m_id, m_message.c_str()); + if (m_completed == 0 || m_completed == m_total) + s->Printf(", type = %s", m_completed == 0 ? "start" : "end"); + else + s->PutCString(", type = update"); + // If m_total is UINT64_MAX, there is no progress to report, just "start" + // and "end". If it isn't we will show the completed and total amounts. + if (m_total != UINT64_MAX) + s->Printf(", progress = %" PRIu64 " of %" PRIu64, m_completed, m_total); +} + +const Debugger::ProgressEventData * +Debugger::ProgressEventData::GetEventDataFromEvent(const Event *event_ptr) { + if (event_ptr) + if (const EventData *event_data = event_ptr->GetData()) + if (event_data->GetFlavor() == ProgressEventData::GetFlavorString()) + return static_cast<const ProgressEventData *>(event_ptr->GetData()); + return nullptr; +} + +static void PrivateReportProgress(Debugger &debugger, uint64_t progress_id, + const std::string &message, + uint64_t completed, uint64_t total, + bool is_debugger_specific) { + // Only deliver progress events if we have any progress listeners. + const uint32_t event_type = Debugger::eBroadcastBitProgress; + if (!debugger.GetBroadcaster().EventTypeHasListeners(event_type)) + return; + EventSP event_sp(new Event(event_type, new Debugger::ProgressEventData( + progress_id, message, completed, + total, is_debugger_specific))); + debugger.GetBroadcaster().BroadcastEvent(event_sp); +} + +void Debugger::ReportProgress(uint64_t progress_id, const std::string &message, + uint64_t completed, uint64_t total, + llvm::Optional<lldb::user_id_t> debugger_id) { + // Check if this progress is for a specific debugger. + if (debugger_id.hasValue()) { + // It is debugger specific, grab it and deliver the event if the debugger + // still exists. + DebuggerSP debugger_sp = FindDebuggerWithID(*debugger_id); + if (debugger_sp) + PrivateReportProgress(*debugger_sp, progress_id, message, completed, + total, /*is_debugger_specific*/ true); + return; + } + // The progress event is not debugger specific, iterate over all debuggers + // and deliver a progress event to each one. + if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { + std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); + DebuggerList::iterator pos, end = g_debugger_list_ptr->end(); + for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) + PrivateReportProgress(*(*pos), progress_id, message, completed, total, + /*is_debugger_specific*/ false); + } +} + bool Debugger::EnableLog(llvm::StringRef channel, llvm::ArrayRef<const char *> categories, llvm::StringRef log_file, uint32_t log_options, diff --git a/contrib/llvm-project/lldb/source/Symbol/Declaration.cpp b/contrib/llvm-project/lldb/source/Core/Declaration.cpp index 48d8013811d9..579a3999d14e 100644 --- a/contrib/llvm-project/lldb/source/Symbol/Declaration.cpp +++ b/contrib/llvm-project/lldb/source/Core/Declaration.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Symbol/Declaration.h" +#include "lldb/Core/Declaration.h" #include "lldb/Utility/Stream.h" using namespace lldb_private; @@ -20,22 +20,15 @@ void Declaration::Dump(Stream *s, bool show_fullpaths) const { *s << m_file.GetFilename(); if (m_line > 0) s->Printf(":%u", m_line); -#ifdef LLDB_ENABLE_DECLARATION_COLUMNS - if (m_column > 0) + if (m_column != LLDB_INVALID_COLUMN_NUMBER) s->Printf(":%u", m_column); -#endif } else { if (m_line > 0) { s->Printf(", line = %u", m_line); -#ifdef LLDB_ENABLE_DECLARATION_COLUMNS - if (m_column > 0) + if (m_column != LLDB_INVALID_COLUMN_NUMBER) s->Printf(":%u", m_column); -#endif - } -#ifdef LLDB_ENABLE_DECLARATION_COLUMNS - else if (m_column > 0) + } else if (m_column != LLDB_INVALID_COLUMN_NUMBER) s->Printf(", column = %u", m_column); -#endif } } @@ -48,17 +41,13 @@ bool Declaration::DumpStopContext(Stream *s, bool show_fullpaths) const { if (m_line > 0) s->Printf(":%u", m_line); -#ifdef LLDB_ENABLE_DECLARATION_COLUMNS - if (m_column > 0) + if (m_column != LLDB_INVALID_COLUMN_NUMBER) s->Printf(":%u", m_column); -#endif return true; } else if (m_line > 0) { s->Printf(" line %u", m_line); -#ifdef LLDB_ENABLE_DECLARATION_COLUMNS - if (m_column > 0) + if (m_column != LLDB_INVALID_COLUMN_NUMBER) s->Printf(":%u", m_column); -#endif return true; } return false; @@ -74,12 +63,10 @@ int Declaration::Compare(const Declaration &a, const Declaration &b) { return -1; else if (a.m_line > b.m_line) return 1; -#ifdef LLDB_ENABLE_DECLARATION_COLUMNS if (a.m_column < b.m_column) return -1; else if (a.m_column > b.m_column) return 1; -#endif return 0; } @@ -89,10 +76,8 @@ bool Declaration::FileAndLineEqual(const Declaration &declaration) const { } bool lldb_private::operator==(const Declaration &lhs, const Declaration &rhs) { -#ifdef LLDB_ENABLE_DECLARATION_COLUMNS if (lhs.GetColumn() != rhs.GetColumn()) return false; -#else + return lhs.GetLine() == rhs.GetLine() && lhs.GetFile() == rhs.GetFile(); -#endif } diff --git a/contrib/llvm-project/lldb/source/Core/Disassembler.cpp b/contrib/llvm-project/lldb/source/Core/Disassembler.cpp index 3a975d9296f4..704b3df4b2ac 100644 --- a/contrib/llvm-project/lldb/source/Core/Disassembler.cpp +++ b/contrib/llvm-project/lldb/source/Core/Disassembler.cpp @@ -48,7 +48,7 @@ #include <cstring> #include <utility> -#include <assert.h> +#include <cassert> #define DEFAULT_DISASM_BYTE_SIZE 32 @@ -122,7 +122,7 @@ static Address ResolveAddress(Target &target, const Address &addr) { lldb::DisassemblerSP Disassembler::DisassembleRange( const ArchSpec &arch, const char *plugin_name, const char *flavor, - Target &target, const AddressRange &range, bool prefer_file_cache) { + Target &target, const AddressRange &range, bool force_live_memory) { if (range.GetByteSize() <= 0) return {}; @@ -137,7 +137,7 @@ lldb::DisassemblerSP Disassembler::DisassembleRange( const size_t bytes_disassembled = disasm_sp->ParseInstructions( target, range.GetBaseAddress(), {Limit::Bytes, range.GetByteSize()}, - nullptr, prefer_file_cache); + nullptr, force_live_memory); if (bytes_disassembled == 0) return {}; @@ -181,9 +181,9 @@ bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch, if (!disasm_sp) return false; - const bool prefer_file_cache = false; + const bool force_live_memory = true; size_t bytes_disassembled = disasm_sp->ParseInstructions( - exe_ctx.GetTargetRef(), address, limit, &strm, prefer_file_cache); + exe_ctx.GetTargetRef(), address, limit, &strm, force_live_memory); if (bytes_disassembled == 0) return false; @@ -1036,7 +1036,7 @@ InstructionList::GetIndexOfInstructionAtLoadAddress(lldb::addr_t load_addr, size_t Disassembler::ParseInstructions(Target &target, Address start, Limit limit, Stream *error_strm_ptr, - bool prefer_file_cache) { + bool force_live_memory) { m_instruction_list.Clear(); if (!start.IsValid()) @@ -1052,8 +1052,8 @@ size_t Disassembler::ParseInstructions(Target &target, Address start, Status error; lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; const size_t bytes_read = - target.ReadMemory(start, prefer_file_cache, data_sp->GetBytes(), - data_sp->GetByteSize(), error, &load_addr); + target.ReadMemory(start, data_sp->GetBytes(), data_sp->GetByteSize(), + error, force_live_memory, &load_addr); const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS; if (bytes_read == 0) { diff --git a/contrib/llvm-project/lldb/source/Core/DumpDataExtractor.cpp b/contrib/llvm-project/lldb/source/Core/DumpDataExtractor.cpp index dbfedfae27a8..175ffef04a81 100644 --- a/contrib/llvm-project/lldb/source/Core/DumpDataExtractor.cpp +++ b/contrib/llvm-project/lldb/source/Core/DumpDataExtractor.cpp @@ -14,8 +14,10 @@ #include "lldb/Core/Address.h" #include "lldb/Core/Disassembler.h" #include "lldb/Core/ModuleList.h" +#include "lldb/Target/ABI.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/ExecutionContextScope.h" +#include "lldb/Target/Process.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataExtractor.h" @@ -32,10 +34,10 @@ #include <memory> #include <string> -#include <assert.h> -#include <ctype.h> -#include <inttypes.h> -#include <math.h> +#include <cassert> +#include <cctype> +#include <cinttypes> +#include <cmath> #include <bitset> #include <sstream> @@ -50,7 +52,9 @@ static float half2float(uint16_t half) { float f; uint32_t u; } u; - int32_t v = (int16_t)half; + // Sign extend to 4 byte. + int32_t sign_extended = static_cast<int16_t>(half); + uint32_t v = static_cast<uint32_t>(sign_extended); if (0 == (v & 0x7c00)) { u.u = v & 0x80007FFFU; @@ -112,7 +116,7 @@ static lldb::offset_t DumpAPInt(Stream *s, const DataExtractor &data, bool is_signed, unsigned radix) { llvm::Optional<llvm::APInt> apint = GetAPInt(data, &offset, byte_size); if (apint.hasValue()) { - std::string apint_str(apint.getValue().toString(radix, is_signed)); + std::string apint_str = toString(apint.getValue(), radix, is_signed); switch (radix) { case 2: s->Write("0b", 2); @@ -226,6 +230,29 @@ static void DumpCharacter(Stream &s, const char c) { s.Printf("\\x%2.2x", c); } +/// Dump a floating point type. +template <typename FloatT> +void DumpFloatingPoint(std::ostringstream &ss, FloatT f) { + static_assert(std::is_floating_point<FloatT>::value, + "Only floating point types can be dumped."); + // NaN and Inf are potentially implementation defined and on Darwin it + // seems NaNs are printed without their sign. Manually implement dumping them + // here to avoid having to deal with platform differences. + if (std::isnan(f)) { + if (std::signbit(f)) + ss << '-'; + ss << "nan"; + return; + } + if (std::isinf(f)) { + if (std::signbit(f)) + ss << '-'; + ss << "inf"; + return; + } + ss << f; +} + lldb::offset_t lldb_private::DumpDataExtractor( const DataExtractor &DE, Stream *s, offset_t start_offset, lldb::Format item_format, size_t item_byte_size, size_t item_count, @@ -566,14 +593,14 @@ lldb::offset_t lldb_private::DumpDataExtractor( f = DE.GetFloat(&offset); } ss.precision(std::numeric_limits<float>::digits10); - ss << f; + DumpFloatingPoint(ss, f); } else if (item_byte_size == sizeof(double)) { ss.precision(std::numeric_limits<double>::digits10); - ss << DE.GetDouble(&offset); + DumpFloatingPoint(ss, DE.GetDouble(&offset)); } else if (item_byte_size == sizeof(long double) || item_byte_size == 10) { ss.precision(std::numeric_limits<long double>::digits10); - ss << DE.GetLongDouble(&offset); + DumpFloatingPoint(ss, DE.GetLongDouble(&offset)); } else { s->Printf("error: unsupported byte size (%" PRIu64 ") for float format", @@ -611,6 +638,21 @@ lldb::offset_t lldb_private::DumpDataExtractor( so_addr.SetOffset(addr); so_addr.Dump(s, exe_scope, Address::DumpStyleResolvedPointerDescription); + if (ProcessSP process_sp = exe_scope->CalculateProcess()) { + if (ABISP abi_sp = process_sp->GetABI()) { + addr_t addr_fixed = abi_sp->FixCodeAddress(addr); + if (target_sp->GetSectionLoadList().ResolveLoadAddress( + addr_fixed, so_addr)) { + s->PutChar(' '); + s->Printf("(0x%*.*" PRIx64 ")", (int)(2 * item_byte_size), + (int)(2 * item_byte_size), addr_fixed); + s->PutChar(' '); + so_addr.Dump(s, exe_scope, + Address::DumpStyleResolvedDescription, + Address::DumpStyleModuleWithFileAddress); + } + } + } } } } diff --git a/contrib/llvm-project/lldb/source/Core/DynamicLoader.cpp b/contrib/llvm-project/lldb/source/Core/DynamicLoader.cpp index 22cb9f18147a..10d2b7207018 100644 --- a/contrib/llvm-project/lldb/source/Core/DynamicLoader.cpp +++ b/contrib/llvm-project/lldb/source/Core/DynamicLoader.cpp @@ -24,7 +24,7 @@ #include <memory> -#include <assert.h> +#include <cassert> using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm-project/lldb/source/Core/EmulateInstruction.cpp b/contrib/llvm-project/lldb/source/Core/EmulateInstruction.cpp index f7f56e9fc54f..9b9111408209 100644 --- a/contrib/llvm-project/lldb/source/Core/EmulateInstruction.cpp +++ b/contrib/llvm-project/lldb/source/Core/EmulateInstruction.cpp @@ -30,8 +30,8 @@ #include <cstring> #include <memory> -#include <inttypes.h> -#include <stdio.h> +#include <cinttypes> +#include <cstdio> namespace lldb_private { class Target; diff --git a/contrib/llvm-project/lldb/source/Core/FileLineResolver.cpp b/contrib/llvm-project/lldb/source/Core/FileLineResolver.cpp index 37435f9e9047..2cf7007165bc 100644 --- a/contrib/llvm-project/lldb/source/Core/FileLineResolver.cpp +++ b/contrib/llvm-project/lldb/source/Core/FileLineResolver.cpp @@ -29,7 +29,7 @@ FileLineResolver::FileLineResolver(const FileSpec &file_spec, uint32_t line_no, : Searcher(), m_file_spec(file_spec), m_line_number(line_no), m_inlines(check_inlines) {} -FileLineResolver::~FileLineResolver() {} +FileLineResolver::~FileLineResolver() = default; Searcher::CallbackReturn FileLineResolver::SearchCallback(SearchFilter &filter, SymbolContext &context, diff --git a/contrib/llvm-project/lldb/source/Core/FileSpecList.cpp b/contrib/llvm-project/lldb/source/Core/FileSpecList.cpp index 3ada7b495fdb..1a1cf284ea07 100644 --- a/contrib/llvm-project/lldb/source/Core/FileSpecList.cpp +++ b/contrib/llvm-project/lldb/source/Core/FileSpecList.cpp @@ -13,7 +13,7 @@ #include <utility> -#include <stdint.h> +#include <cstdint> using namespace lldb_private; using namespace std; diff --git a/contrib/llvm-project/lldb/source/Core/FormatEntity.cpp b/contrib/llvm-project/lldb/source/Core/FormatEntity.cpp index d491ac14bec8..6e6255b903bb 100644 --- a/contrib/llvm-project/lldb/source/Core/FormatEntity.cpp +++ b/contrib/llvm-project/lldb/source/Core/FormatEntity.cpp @@ -41,11 +41,13 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/AnsiTerminal.h" #include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/CompletionRequest.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Logging.h" #include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/StringList.h" @@ -57,12 +59,12 @@ #include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" -#include <ctype.h> -#include <inttypes.h> +#include <cctype> +#include <cinttypes> +#include <cstdio> +#include <cstdlib> +#include <cstring> #include <memory> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> #include <type_traits> #include <utility> @@ -76,203 +78,196 @@ struct RegisterInfo; using namespace lldb; using namespace lldb_private; -enum FileKind { FileError = 0, Basename, Dirname, Fullpath }; - -#define ENTRY(n, t) \ - { n, nullptr, FormatEntity::Entry::Type::t, 0, 0, nullptr, false } -#define ENTRY_VALUE(n, t, v) \ - { n, nullptr, FormatEntity::Entry::Type::t, v, 0, nullptr, false } -#define ENTRY_CHILDREN(n, t, c) \ - { \ - n, nullptr, FormatEntity::Entry::Type::t, 0, \ - static_cast<uint32_t>(llvm::array_lengthof(c)), c, false \ - } -#define ENTRY_CHILDREN_KEEP_SEP(n, t, c) \ - { \ - n, nullptr, FormatEntity::Entry::Type::t, 0, \ - static_cast<uint32_t>(llvm::array_lengthof(c)), c, true \ - } -#define ENTRY_STRING(n, s) \ - { n, s, FormatEntity::Entry::Type::EscapeCode, 0, 0, nullptr, false } -static FormatEntity::Entry::Definition g_string_entry[] = { - ENTRY("*", ParentString)}; - -static FormatEntity::Entry::Definition g_addr_entries[] = { - ENTRY("load", AddressLoad), - ENTRY("file", AddressFile), - ENTRY("load", AddressLoadOrFile), -}; +using Definition = lldb_private::FormatEntity::Entry::Definition; +using Entry = FormatEntity::Entry; +using EntryType = FormatEntity::Entry::Type; -static FormatEntity::Entry::Definition g_file_child_entries[] = { - ENTRY_VALUE("basename", ParentNumber, FileKind::Basename), - ENTRY_VALUE("dirname", ParentNumber, FileKind::Dirname), - ENTRY_VALUE("fullpath", ParentNumber, FileKind::Fullpath)}; - -static FormatEntity::Entry::Definition g_frame_child_entries[] = { - ENTRY("index", FrameIndex), - ENTRY("pc", FrameRegisterPC), - ENTRY("fp", FrameRegisterFP), - ENTRY("sp", FrameRegisterSP), - ENTRY("flags", FrameRegisterFlags), - ENTRY("no-debug", FrameNoDebug), - ENTRY_CHILDREN("reg", FrameRegisterByName, g_string_entry), - ENTRY("is-artificial", FrameIsArtificial), -}; - -static FormatEntity::Entry::Definition g_function_child_entries[] = { - ENTRY("id", FunctionID), - ENTRY("name", FunctionName), - ENTRY("name-without-args", FunctionNameNoArgs), - ENTRY("name-with-args", FunctionNameWithArgs), - ENTRY("mangled-name", FunctionMangledName), - ENTRY("addr-offset", FunctionAddrOffset), - ENTRY("concrete-only-addr-offset-no-padding", FunctionAddrOffsetConcrete), - ENTRY("line-offset", FunctionLineOffset), - ENTRY("pc-offset", FunctionPCOffset), - ENTRY("initial-function", FunctionInitial), - ENTRY("changed", FunctionChanged), - ENTRY("is-optimized", FunctionIsOptimized)}; - -static FormatEntity::Entry::Definition g_line_child_entries[] = { - ENTRY_CHILDREN("file", LineEntryFile, g_file_child_entries), - ENTRY("number", LineEntryLineNumber), - ENTRY("column", LineEntryColumn), - ENTRY("start-addr", LineEntryStartAddress), - ENTRY("end-addr", LineEntryEndAddress), -}; - -static FormatEntity::Entry::Definition g_module_child_entries[] = { - ENTRY_CHILDREN("file", ModuleFile, g_file_child_entries), -}; +enum FileKind { FileError = 0, Basename, Dirname, Fullpath }; -static FormatEntity::Entry::Definition g_process_child_entries[] = { - ENTRY("id", ProcessID), - ENTRY_VALUE("name", ProcessFile, FileKind::Basename), - ENTRY_CHILDREN("file", ProcessFile, g_file_child_entries), +constexpr Definition g_string_entry[] = { + Definition("*", EntryType::ParentString)}; + +constexpr Definition g_addr_entries[] = { + Definition("load", EntryType::AddressLoad), + Definition("file", EntryType::AddressFile)}; + +constexpr Definition g_file_child_entries[] = { + Definition("basename", EntryType::ParentNumber, FileKind::Basename), + Definition("dirname", EntryType::ParentNumber, FileKind::Dirname), + Definition("fullpath", EntryType::ParentNumber, FileKind::Fullpath)}; + +constexpr Definition g_frame_child_entries[] = { + Definition("index", EntryType::FrameIndex), + Definition("pc", EntryType::FrameRegisterPC), + Definition("fp", EntryType::FrameRegisterFP), + Definition("sp", EntryType::FrameRegisterSP), + Definition("flags", EntryType::FrameRegisterFlags), + Definition("no-debug", EntryType::FrameNoDebug), + Entry::DefinitionWithChildren("reg", EntryType::FrameRegisterByName, + g_string_entry), + Definition("is-artificial", EntryType::FrameIsArtificial), }; -static FormatEntity::Entry::Definition g_svar_child_entries[] = { - ENTRY("*", ParentString)}; - -static FormatEntity::Entry::Definition g_var_child_entries[] = { - ENTRY("*", ParentString)}; - -static FormatEntity::Entry::Definition g_thread_child_entries[] = { - ENTRY("id", ThreadID), - ENTRY("protocol_id", ThreadProtocolID), - ENTRY("index", ThreadIndexID), - ENTRY_CHILDREN("info", ThreadInfo, g_string_entry), - ENTRY("queue", ThreadQueue), - ENTRY("name", ThreadName), - ENTRY("stop-reason", ThreadStopReason), - ENTRY("stop-reason-raw", ThreadStopReasonRaw), - ENTRY("return-value", ThreadReturnValue), - ENTRY("completed-expression", ThreadCompletedExpression), +constexpr Definition g_function_child_entries[] = { + Definition("id", EntryType::FunctionID), + Definition("name", EntryType::FunctionName), + Definition("name-without-args", EntryType::FunctionNameNoArgs), + Definition("name-with-args", EntryType::FunctionNameWithArgs), + Definition("mangled-name", EntryType::FunctionMangledName), + Definition("addr-offset", EntryType::FunctionAddrOffset), + Definition("concrete-only-addr-offset-no-padding", + EntryType::FunctionAddrOffsetConcrete), + Definition("line-offset", EntryType::FunctionLineOffset), + Definition("pc-offset", EntryType::FunctionPCOffset), + Definition("initial-function", EntryType::FunctionInitial), + Definition("changed", EntryType::FunctionChanged), + Definition("is-optimized", EntryType::FunctionIsOptimized)}; + +constexpr Definition g_line_child_entries[] = { + Entry::DefinitionWithChildren("file", EntryType::LineEntryFile, + g_file_child_entries), + Definition("number", EntryType::LineEntryLineNumber), + Definition("column", EntryType::LineEntryColumn), + Definition("start-addr", EntryType::LineEntryStartAddress), + Definition("end-addr", EntryType::LineEntryEndAddress), }; -static FormatEntity::Entry::Definition g_target_child_entries[] = { - ENTRY("arch", TargetArch), -}; +constexpr Definition g_module_child_entries[] = {Entry::DefinitionWithChildren( + "file", EntryType::ModuleFile, g_file_child_entries)}; + +constexpr Definition g_process_child_entries[] = { + Definition("id", EntryType::ProcessID), + Definition("name", EntryType::ProcessFile, FileKind::Basename), + Entry::DefinitionWithChildren("file", EntryType::ProcessFile, + g_file_child_entries)}; + +constexpr Definition g_svar_child_entries[] = { + Definition("*", EntryType::ParentString)}; + +constexpr Definition g_var_child_entries[] = { + Definition("*", EntryType::ParentString)}; + +constexpr Definition g_thread_child_entries[] = { + Definition("id", EntryType::ThreadID), + Definition("protocol_id", EntryType::ThreadProtocolID), + Definition("index", EntryType::ThreadIndexID), + Entry::DefinitionWithChildren("info", EntryType::ThreadInfo, + g_string_entry), + Definition("queue", EntryType::ThreadQueue), + Definition("name", EntryType::ThreadName), + Definition("stop-reason", EntryType::ThreadStopReason), + Definition("stop-reason-raw", EntryType::ThreadStopReasonRaw), + Definition("return-value", EntryType::ThreadReturnValue), + Definition("completed-expression", EntryType::ThreadCompletedExpression)}; + +constexpr Definition g_target_child_entries[] = { + Definition("arch", EntryType::TargetArch)}; #define _TO_STR2(_val) #_val #define _TO_STR(_val) _TO_STR2(_val) -static FormatEntity::Entry::Definition g_ansi_fg_entries[] = { - ENTRY_STRING("black", - ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLACK) ANSI_ESC_END), - ENTRY_STRING("red", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_RED) ANSI_ESC_END), - ENTRY_STRING("green", - ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_GREEN) ANSI_ESC_END), - ENTRY_STRING("yellow", - ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_YELLOW) ANSI_ESC_END), - ENTRY_STRING("blue", - ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLUE) ANSI_ESC_END), - ENTRY_STRING("purple", - ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_PURPLE) ANSI_ESC_END), - ENTRY_STRING("cyan", - ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_CYAN) ANSI_ESC_END), - ENTRY_STRING("white", - ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_WHITE) ANSI_ESC_END), -}; - -static FormatEntity::Entry::Definition g_ansi_bg_entries[] = { - ENTRY_STRING("black", - ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLACK) ANSI_ESC_END), - ENTRY_STRING("red", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_RED) ANSI_ESC_END), - ENTRY_STRING("green", - ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_GREEN) ANSI_ESC_END), - ENTRY_STRING("yellow", - ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_YELLOW) ANSI_ESC_END), - ENTRY_STRING("blue", - ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLUE) ANSI_ESC_END), - ENTRY_STRING("purple", - ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_PURPLE) ANSI_ESC_END), - ENTRY_STRING("cyan", - ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_CYAN) ANSI_ESC_END), - ENTRY_STRING("white", - ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_WHITE) ANSI_ESC_END), -}; - -static FormatEntity::Entry::Definition g_ansi_entries[] = { - ENTRY_CHILDREN("fg", Invalid, g_ansi_fg_entries), - ENTRY_CHILDREN("bg", Invalid, g_ansi_bg_entries), - ENTRY_STRING("normal", - ANSI_ESC_START _TO_STR(ANSI_CTRL_NORMAL) ANSI_ESC_END), - ENTRY_STRING("bold", ANSI_ESC_START _TO_STR(ANSI_CTRL_BOLD) ANSI_ESC_END), - ENTRY_STRING("faint", ANSI_ESC_START _TO_STR(ANSI_CTRL_FAINT) ANSI_ESC_END), - ENTRY_STRING("italic", - ANSI_ESC_START _TO_STR(ANSI_CTRL_ITALIC) ANSI_ESC_END), - ENTRY_STRING("underline", - ANSI_ESC_START _TO_STR(ANSI_CTRL_UNDERLINE) ANSI_ESC_END), - ENTRY_STRING("slow-blink", - ANSI_ESC_START _TO_STR(ANSI_CTRL_SLOW_BLINK) ANSI_ESC_END), - ENTRY_STRING("fast-blink", - ANSI_ESC_START _TO_STR(ANSI_CTRL_FAST_BLINK) ANSI_ESC_END), - ENTRY_STRING("negative", - ANSI_ESC_START _TO_STR(ANSI_CTRL_IMAGE_NEGATIVE) ANSI_ESC_END), - ENTRY_STRING("conceal", - ANSI_ESC_START _TO_STR(ANSI_CTRL_CONCEAL) ANSI_ESC_END), - ENTRY_STRING("crossed-out", - ANSI_ESC_START _TO_STR(ANSI_CTRL_CROSSED_OUT) ANSI_ESC_END), +constexpr Definition g_ansi_fg_entries[] = { + Definition("black", + ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLACK) ANSI_ESC_END), + Definition("red", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_RED) ANSI_ESC_END), + Definition("green", + ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_GREEN) ANSI_ESC_END), + Definition("yellow", + ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_YELLOW) ANSI_ESC_END), + Definition("blue", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLUE) ANSI_ESC_END), + Definition("purple", + ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_PURPLE) ANSI_ESC_END), + Definition("cyan", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_CYAN) ANSI_ESC_END), + Definition("white", + ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_WHITE) ANSI_ESC_END), }; -static FormatEntity::Entry::Definition g_script_child_entries[] = { - ENTRY("frame", ScriptFrame), ENTRY("process", ScriptProcess), - ENTRY("target", ScriptTarget), ENTRY("thread", ScriptThread), - ENTRY("var", ScriptVariable), ENTRY("svar", ScriptVariableSynthetic), - ENTRY("thread", ScriptThread), +constexpr Definition g_ansi_bg_entries[] = { + Definition("black", + ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLACK) ANSI_ESC_END), + Definition("red", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_RED) ANSI_ESC_END), + Definition("green", + ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_GREEN) ANSI_ESC_END), + Definition("yellow", + ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_YELLOW) ANSI_ESC_END), + Definition("blue", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLUE) ANSI_ESC_END), + Definition("purple", + ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_PURPLE) ANSI_ESC_END), + Definition("cyan", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_CYAN) ANSI_ESC_END), + Definition("white", + ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_WHITE) ANSI_ESC_END), }; -static FormatEntity::Entry::Definition g_top_level_entries[] = { - ENTRY_CHILDREN("addr", AddressLoadOrFile, g_addr_entries), - ENTRY("addr-file-or-load", AddressLoadOrFile), - ENTRY_CHILDREN("ansi", Invalid, g_ansi_entries), - ENTRY("current-pc-arrow", CurrentPCArrow), - ENTRY_CHILDREN("file", File, g_file_child_entries), - ENTRY("language", Lang), - ENTRY_CHILDREN("frame", Invalid, g_frame_child_entries), - ENTRY_CHILDREN("function", Invalid, g_function_child_entries), - ENTRY_CHILDREN("line", Invalid, g_line_child_entries), - ENTRY_CHILDREN("module", Invalid, g_module_child_entries), - ENTRY_CHILDREN("process", Invalid, g_process_child_entries), - ENTRY_CHILDREN("script", Invalid, g_script_child_entries), - ENTRY_CHILDREN_KEEP_SEP("svar", VariableSynthetic, g_svar_child_entries), - ENTRY_CHILDREN("thread", Invalid, g_thread_child_entries), - ENTRY_CHILDREN("target", Invalid, g_target_child_entries), - ENTRY_CHILDREN_KEEP_SEP("var", Variable, g_var_child_entries), +constexpr Definition g_ansi_entries[] = { + Entry::DefinitionWithChildren("fg", EntryType::Invalid, g_ansi_fg_entries), + Entry::DefinitionWithChildren("bg", EntryType::Invalid, g_ansi_bg_entries), + Definition("normal", ANSI_ESC_START _TO_STR(ANSI_CTRL_NORMAL) ANSI_ESC_END), + Definition("bold", ANSI_ESC_START _TO_STR(ANSI_CTRL_BOLD) ANSI_ESC_END), + Definition("faint", ANSI_ESC_START _TO_STR(ANSI_CTRL_FAINT) ANSI_ESC_END), + Definition("italic", ANSI_ESC_START _TO_STR(ANSI_CTRL_ITALIC) ANSI_ESC_END), + Definition("underline", + ANSI_ESC_START _TO_STR(ANSI_CTRL_UNDERLINE) ANSI_ESC_END), + Definition("slow-blink", + ANSI_ESC_START _TO_STR(ANSI_CTRL_SLOW_BLINK) ANSI_ESC_END), + Definition("fast-blink", + ANSI_ESC_START _TO_STR(ANSI_CTRL_FAST_BLINK) ANSI_ESC_END), + Definition("negative", + ANSI_ESC_START _TO_STR(ANSI_CTRL_IMAGE_NEGATIVE) ANSI_ESC_END), + Definition("conceal", + ANSI_ESC_START _TO_STR(ANSI_CTRL_CONCEAL) ANSI_ESC_END), + Definition("crossed-out", + ANSI_ESC_START _TO_STR(ANSI_CTRL_CROSSED_OUT) ANSI_ESC_END), }; -static FormatEntity::Entry::Definition g_root = - ENTRY_CHILDREN("<root>", Root, g_top_level_entries); +constexpr Definition g_script_child_entries[] = { + Definition("frame", EntryType::ScriptFrame), + Definition("process", EntryType::ScriptProcess), + Definition("target", EntryType::ScriptTarget), + Definition("thread", EntryType::ScriptThread), + Definition("var", EntryType::ScriptVariable), + Definition("svar", EntryType::ScriptVariableSynthetic), + Definition("thread", EntryType::ScriptThread)}; + +constexpr Definition g_top_level_entries[] = { + Entry::DefinitionWithChildren("addr", EntryType::AddressLoadOrFile, + g_addr_entries), + Definition("addr-file-or-load", EntryType::AddressLoadOrFile), + Entry::DefinitionWithChildren("ansi", EntryType::Invalid, g_ansi_entries), + Definition("current-pc-arrow", EntryType::CurrentPCArrow), + Entry::DefinitionWithChildren("file", EntryType::File, + g_file_child_entries), + Definition("language", EntryType::Lang), + Entry::DefinitionWithChildren("frame", EntryType::Invalid, + g_frame_child_entries), + Entry::DefinitionWithChildren("function", EntryType::Invalid, + g_function_child_entries), + Entry::DefinitionWithChildren("line", EntryType::Invalid, + g_line_child_entries), + Entry::DefinitionWithChildren("module", EntryType::Invalid, + g_module_child_entries), + Entry::DefinitionWithChildren("process", EntryType::Invalid, + g_process_child_entries), + Entry::DefinitionWithChildren("script", EntryType::Invalid, + g_script_child_entries), + Entry::DefinitionWithChildren("svar", EntryType::VariableSynthetic, + g_svar_child_entries, true), + Entry::DefinitionWithChildren("thread", EntryType::Invalid, + g_thread_child_entries), + Entry::DefinitionWithChildren("target", EntryType::Invalid, + g_target_child_entries), + Entry::DefinitionWithChildren("var", EntryType::Variable, + g_var_child_entries, true)}; + +constexpr Definition g_root = Entry::DefinitionWithChildren( + "<root>", EntryType::Root, g_top_level_entries); FormatEntity::Entry::Entry(llvm::StringRef s) : string(s.data(), s.size()), printf_format(), children(), - definition(nullptr), type(Type::String), fmt(lldb::eFormatDefault), - number(0), deref(false) {} + type(Type::String), fmt(lldb::eFormatDefault), number(0), deref(false) {} FormatEntity::Entry::Entry(char ch) - : string(1, ch), printf_format(), children(), definition(nullptr), - type(Type::String), fmt(lldb::eFormatDefault), number(0), deref(false) {} + : string(1, ch), printf_format(), children(), type(Type::String), + fmt(lldb::eFormatDefault), number(0), deref(false) {} void FormatEntity::Entry::AppendChar(char ch) { if (children.empty() || children.back().type != Entry::Type::String) @@ -598,9 +593,7 @@ static bool DumpFile(Stream &s, const FileSpec &file, FileKind file_kind) { } static bool DumpRegister(Stream &s, StackFrame *frame, RegisterKind reg_kind, - uint32_t reg_num, Format format) - -{ + uint32_t reg_num, Format format) { if (frame) { RegisterContext *reg_ctx = frame->GetRegisterContext().get(); @@ -624,7 +617,6 @@ static bool DumpRegister(Stream &s, StackFrame *frame, RegisterKind reg_kind, } static ValueObjectSP ExpandIndexedExpression(ValueObject *valobj, size_t index, - StackFrame *frame, bool deref_pointer) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS)); const char *ptr_deref_format = "[%d]"; @@ -956,9 +948,7 @@ static bool DumpValue(Stream &s, const SymbolContext *sc, bool success = true; for (int64_t index = index_lower; index <= index_higher; ++index) { - ValueObject *item = - ExpandIndexedExpression(target, index, exe_ctx->GetFramePtr(), false) - .get(); + ValueObject *item = ExpandIndexedExpression(target, index, false).get(); if (!item) { LLDB_LOGF(log, @@ -1523,17 +1513,22 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, return initial_function; case Entry::Type::FunctionName: { + if (!sc) + return false; + Language *language_plugin = nullptr; bool language_plugin_handled = false; StreamString ss; + if (sc->function) language_plugin = Language::FindPlugin(sc->function->GetLanguage()); else if (sc->symbol) language_plugin = Language::FindPlugin(sc->symbol->GetLanguage()); - if (language_plugin) { + + if (language_plugin) language_plugin_handled = language_plugin->GetFunctionDisplayName( sc, exe_ctx, Language::FunctionNameRepresentation::eName, ss); - } + if (language_plugin_handled) { s << ss.GetString(); return true; @@ -1543,6 +1538,7 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, name = sc->function->GetName().AsCString(nullptr); else if (sc->symbol) name = sc->symbol->GetName().AsCString(nullptr); + if (name) { s.PutCString(name); @@ -1564,6 +1560,9 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, return false; case Entry::Type::FunctionNameNoArgs: { + if (!sc) + return false; + Language *language_plugin = nullptr; bool language_plugin_handled = false; StreamString ss; @@ -1571,11 +1570,12 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, language_plugin = Language::FindPlugin(sc->function->GetLanguage()); else if (sc->symbol) language_plugin = Language::FindPlugin(sc->symbol->GetLanguage()); - if (language_plugin) { + + if (language_plugin) language_plugin_handled = language_plugin->GetFunctionDisplayName( sc, exe_ctx, Language::FunctionNameRepresentation::eNameWithNoArgs, ss); - } + if (language_plugin_handled) { s << ss.GetString(); return true; @@ -1594,6 +1594,9 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, return false; case Entry::Type::FunctionNameWithArgs: { + if (!sc) + return false; + Language *language_plugin = nullptr; bool language_plugin_handled = false; StreamString ss; @@ -1601,10 +1604,11 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, language_plugin = Language::FindPlugin(sc->function->GetLanguage()); else if (sc->symbol) language_plugin = Language::FindPlugin(sc->symbol->GetLanguage()); - if (language_plugin) { + + if (language_plugin) language_plugin_handled = language_plugin->GetFunctionDisplayName( sc, exe_ctx, Language::FunctionNameRepresentation::eNameWithArgs, ss); - } + if (language_plugin_handled) { s << ss.GetString(); return true; @@ -1756,6 +1760,9 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, return false; case Entry::Type::FunctionMangledName: { + if (!sc) + return false; + const char *name = nullptr; if (sc->symbol) name = @@ -1769,7 +1776,7 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, return false; s.PutCString(name); - if (sc->block->GetContainingInlinedBlock()) { + if (sc->block && sc->block->GetContainingInlinedBlock()) { if (const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo()) { s.PutCString(" [inlined] "); @@ -1778,7 +1785,6 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, } return true; } - case Entry::Type::FunctionAddrOffset: if (addr) { if (DumpAddressOffsetFromFunction(s, sc, exe_ctx, *addr, false, false, @@ -1796,9 +1802,11 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, return false; case Entry::Type::FunctionLineOffset: - return (DumpAddressOffsetFromFunction(s, sc, exe_ctx, - sc->line_entry.range.GetBaseAddress(), - false, false, false)); + if (sc) + return (DumpAddressOffsetFromFunction( + s, sc, exe_ctx, sc->line_entry.range.GetBaseAddress(), false, false, + false)); + return false; case Entry::Type::FunctionPCOffset: if (exe_ctx) { @@ -1817,7 +1825,7 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, case Entry::Type::FunctionIsOptimized: { bool is_optimized = false; - if (sc->function && sc->function->GetIsOptimized()) { + if (sc && sc->function && sc->function->GetIsOptimized()) { is_optimized = true; } return is_optimized; @@ -1891,8 +1899,8 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, return false; } -static bool DumpCommaSeparatedChildEntryNames( - Stream &s, const FormatEntity::Entry::Definition *parent) { +static bool DumpCommaSeparatedChildEntryNames(Stream &s, + const Definition *parent) { if (parent->children) { const size_t n = parent->num_children; for (size_t i = 0; i < n; ++i) { @@ -1906,8 +1914,7 @@ static bool DumpCommaSeparatedChildEntryNames( } static Status ParseEntry(const llvm::StringRef &format_str, - const FormatEntity::Entry::Definition *parent, - FormatEntity::Entry &entry) { + const Definition *parent, FormatEntity::Entry &entry) { Status error; const size_t sep_pos = format_str.find_first_of(".[:"); @@ -1917,7 +1924,7 @@ static Status ParseEntry(const llvm::StringRef &format_str, const size_t n = parent->num_children; for (size_t i = 0; i < n; ++i) { - const FormatEntity::Entry::Definition *entry_def = parent->children + i; + const Definition *entry_def = parent->children + i; if (key.equals(entry_def->name) || entry_def->name[0] == '*') { llvm::StringRef value; if (sep_char) @@ -1990,16 +1997,15 @@ static Status ParseEntry(const llvm::StringRef &format_str, return error; } -static const FormatEntity::Entry::Definition * -FindEntry(const llvm::StringRef &format_str, - const FormatEntity::Entry::Definition *parent, - llvm::StringRef &remainder) { +static const Definition *FindEntry(const llvm::StringRef &format_str, + const Definition *parent, + llvm::StringRef &remainder) { Status error; std::pair<llvm::StringRef, llvm::StringRef> p = format_str.split('.'); const size_t n = parent->num_children; for (size_t i = 0; i < n; ++i) { - const FormatEntity::Entry::Definition *entry_def = parent->children + i; + const Definition *entry_def = parent->children + i; if (p.first.equals(entry_def->name) || entry_def->name[0] == '*') { if (p.second.empty()) { if (format_str.back() == '.') @@ -2363,8 +2369,7 @@ static std::string MakeMatch(const llvm::StringRef &prefix, return match; } -static void AddMatches(const FormatEntity::Entry::Definition *def, - const llvm::StringRef &prefix, +static void AddMatches(const Definition *def, const llvm::StringRef &prefix, const llvm::StringRef &match_prefix, StringList &matches) { const size_t n = def->num_children; @@ -2418,8 +2423,7 @@ void FormatEntity::AutoComplete(CompletionRequest &request) { // We have a partially specified variable, find it llvm::StringRef remainder; - const FormatEntity::Entry::Definition *entry_def = - FindEntry(partial_variable, &g_root, remainder); + const Definition *entry_def = FindEntry(partial_variable, &g_root, remainder); if (!entry_def) return; diff --git a/contrib/llvm-project/lldb/source/Core/IOHandler.cpp b/contrib/llvm-project/lldb/source/Core/IOHandler.cpp index 8c654d9d8a98..c6f05d43a2a7 100644 --- a/contrib/llvm-project/lldb/source/Core/IOHandler.cpp +++ b/contrib/llvm-project/lldb/source/Core/IOHandler.cpp @@ -38,13 +38,13 @@ #include <memory> #include <mutex> -#include <assert.h> -#include <ctype.h> -#include <errno.h> -#include <locale.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> +#include <cassert> +#include <cctype> +#include <cerrno> +#include <clocale> +#include <cstdint> +#include <cstdio> +#include <cstring> #include <type_traits> using namespace lldb; @@ -265,17 +265,31 @@ IOHandlerEditline::IOHandlerEditline( m_editline_up = std::make_unique<Editline>(editline_name, GetInputFILE(), GetOutputFILE(), GetErrorFILE(), m_color_prompts); - m_editline_up->SetIsInputCompleteCallback(IsInputCompleteCallback, this); - m_editline_up->SetAutoCompleteCallback(AutoCompleteCallback, this); - if (debugger.GetUseAutosuggestion() && debugger.GetUseColor()) - m_editline_up->SetSuggestionCallback(SuggestionCallback, this); + m_editline_up->SetIsInputCompleteCallback( + [this](Editline *editline, StringList &lines) { + return this->IsInputCompleteCallback(editline, lines); + }); + + m_editline_up->SetAutoCompleteCallback([this](CompletionRequest &request) { + this->AutoCompleteCallback(request); + }); + + if (debugger.GetUseAutosuggestion() && debugger.GetUseColor()) { + m_editline_up->SetSuggestionCallback([this](llvm::StringRef line) { + return this->SuggestionCallback(line); + }); + } // See if the delegate supports fixing indentation const char *indent_chars = delegate.IOHandlerGetFixIndentationCharacters(); if (indent_chars) { // The delegate does support indentation, hook it up so when any // indentation character is typed, the delegate gets a chance to fix it - m_editline_up->SetFixIndentationCallback(FixIndentationCallback, this, - indent_chars); + FixIndentationCallbackType f = [this](Editline *editline, + const StringList &lines, + int cursor_position) { + return this->FixIndentationCallback(editline, lines, cursor_position); + }; + m_editline_up->SetFixIndentationCallback(std::move(f), indent_chars); } } #endif @@ -425,37 +439,23 @@ bool IOHandlerEditline::GetLine(std::string &line, bool &interrupted) { #if LLDB_ENABLE_LIBEDIT bool IOHandlerEditline::IsInputCompleteCallback(Editline *editline, - StringList &lines, - void *baton) { - IOHandlerEditline *editline_reader = (IOHandlerEditline *)baton; - return editline_reader->m_delegate.IOHandlerIsInputComplete(*editline_reader, - lines); + StringList &lines) { + return m_delegate.IOHandlerIsInputComplete(*this, lines); } int IOHandlerEditline::FixIndentationCallback(Editline *editline, const StringList &lines, - int cursor_position, - void *baton) { - IOHandlerEditline *editline_reader = (IOHandlerEditline *)baton; - return editline_reader->m_delegate.IOHandlerFixIndentation( - *editline_reader, lines, cursor_position); + int cursor_position) { + return m_delegate.IOHandlerFixIndentation(*this, lines, cursor_position); } llvm::Optional<std::string> -IOHandlerEditline::SuggestionCallback(llvm::StringRef line, void *baton) { - IOHandlerEditline *editline_reader = static_cast<IOHandlerEditline *>(baton); - if (editline_reader) - return editline_reader->m_delegate.IOHandlerSuggestion(*editline_reader, - line); - - return llvm::None; +IOHandlerEditline::SuggestionCallback(llvm::StringRef line) { + return m_delegate.IOHandlerSuggestion(*this, line); } -void IOHandlerEditline::AutoCompleteCallback(CompletionRequest &request, - void *baton) { - IOHandlerEditline *editline_reader = (IOHandlerEditline *)baton; - if (editline_reader) - editline_reader->m_delegate.IOHandlerComplete(*editline_reader, request); +void IOHandlerEditline::AutoCompleteCallback(CompletionRequest &request) { + m_delegate.IOHandlerComplete(*this, request); } #endif diff --git a/contrib/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp b/contrib/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp index 19066e6be623..4bed788d4863 100644 --- a/contrib/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp +++ b/contrib/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp @@ -26,6 +26,7 @@ #include "lldb/Core/Debugger.h" #include "lldb/Core/StreamFile.h" +#include "lldb/Core/ValueObjectUpdater.h" #include "lldb/Host/File.h" #include "lldb/Utility/Predicate.h" #include "lldb/Utility/Status.h" @@ -39,6 +40,7 @@ #if LLDB_ENABLE_CURSES #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectRegister.h" #include "lldb/Symbol/Block.h" @@ -63,13 +65,13 @@ #include <memory> #include <mutex> -#include <assert.h> -#include <ctype.h> -#include <errno.h> -#include <locale.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> +#include <cassert> +#include <cctype> +#include <cerrno> +#include <cstdint> +#include <cstdio> +#include <cstring> +#include <functional> #include <type_traits> using namespace lldb; @@ -84,6 +86,8 @@ using llvm::StringRef; #define KEY_RETURN 10 #define KEY_ESCAPE 27 +#define KEY_SHIFT_TAB (KEY_MAX + 1) + namespace curses { class Menu; class MenuDelegate; @@ -335,93 +339,52 @@ protected: int m_first_visible_line; }; -class Window { +// A surface is an abstraction for something than can be drawn on. The surface +// have a width, a height, a cursor position, and a multitude of drawing +// operations. This type should be sub-classed to get an actually useful ncurses +// object, such as a Window, SubWindow, Pad, or a SubPad. +class Surface { public: - Window(const char *name) - : m_name(name), m_window(nullptr), m_panel(nullptr), m_parent(nullptr), - m_subwindows(), m_delegate_sp(), m_curr_active_window_idx(UINT32_MAX), - m_prev_active_window_idx(UINT32_MAX), m_delete(false), - m_needs_update(true), m_can_activate(true), m_is_subwin(false) {} + Surface() : m_window(nullptr) {} - Window(const char *name, WINDOW *w, bool del = true) - : m_name(name), m_window(nullptr), m_panel(nullptr), m_parent(nullptr), - m_subwindows(), m_delegate_sp(), m_curr_active_window_idx(UINT32_MAX), - m_prev_active_window_idx(UINT32_MAX), m_delete(del), - m_needs_update(true), m_can_activate(true), m_is_subwin(false) { - if (w) - Reset(w); - } + WINDOW *get() { return m_window; } - Window(const char *name, const Rect &bounds) - : m_name(name), m_window(nullptr), m_parent(nullptr), m_subwindows(), - m_delegate_sp(), m_curr_active_window_idx(UINT32_MAX), - m_prev_active_window_idx(UINT32_MAX), m_delete(true), - m_needs_update(true), m_can_activate(true), m_is_subwin(false) { - Reset(::newwin(bounds.size.height, bounds.size.width, bounds.origin.y, - bounds.origin.y)); - } + operator WINDOW *() { return m_window; } - virtual ~Window() { - RemoveSubWindows(); - Reset(); + // Copy a region of the surface to another surface. + void CopyToSurface(Surface &target, Point source_origin, Point target_origin, + Size size) { + ::copywin(m_window, target.get(), source_origin.y, source_origin.x, + target_origin.y, target_origin.x, + target_origin.y + size.height - 1, + target_origin.x + size.width - 1, false); } - void Reset(WINDOW *w = nullptr, bool del = true) { - if (m_window == w) - return; - - if (m_panel) { - ::del_panel(m_panel); - m_panel = nullptr; - } - if (m_window && m_delete) { - ::delwin(m_window); - m_window = nullptr; - m_delete = false; - } - if (w) { - m_window = w; - m_panel = ::new_panel(m_window); - m_delete = del; - } - } + int GetCursorX() const { return getcurx(m_window); } + int GetCursorY() const { return getcury(m_window); } + void MoveCursor(int x, int y) { ::wmove(m_window, y, x); } void AttributeOn(attr_t attr) { ::wattron(m_window, attr); } void AttributeOff(attr_t attr) { ::wattroff(m_window, attr); } - void Box(chtype v_char = ACS_VLINE, chtype h_char = ACS_HLINE) { - ::box(m_window, v_char, h_char); - } - void Clear() { ::wclear(m_window); } - void Erase() { ::werase(m_window); } - Rect GetBounds() const { - return Rect(GetParentOrigin(), GetSize()); - } // Get the rectangle in our parent window - int GetChar() { return ::wgetch(m_window); } - int GetCursorX() const { return getcurx(m_window); } - int GetCursorY() const { return getcury(m_window); } - Rect GetFrame() const { - return Rect(Point(), GetSize()); - } // Get our rectangle in our own coordinate system - Point GetParentOrigin() const { return Point(GetParentX(), GetParentY()); } - Size GetSize() const { return Size(GetWidth(), GetHeight()); } - int GetParentX() const { return getparx(m_window); } - int GetParentY() const { return getpary(m_window); } + int GetMaxX() const { return getmaxx(m_window); } int GetMaxY() const { return getmaxy(m_window); } int GetWidth() const { return GetMaxX(); } int GetHeight() const { return GetMaxY(); } - void MoveCursor(int x, int y) { ::wmove(m_window, y, x); } - void MoveWindow(int x, int y) { MoveWindow(Point(x, y)); } - void Resize(int w, int h) { ::wresize(m_window, h, w); } - void Resize(const Size &size) { - ::wresize(m_window, size.height, size.width); - } - void PutChar(int ch) { ::waddch(m_window, ch); } - void PutCString(const char *s, int len = -1) { ::waddnstr(m_window, s, len); } + Size GetSize() const { return Size(GetWidth(), GetHeight()); } + // Get a zero origin rectangle width the surface size. + Rect GetFrame() const { return Rect(Point(), GetSize()); } + + void Clear() { ::wclear(m_window); } + void Erase() { ::werase(m_window); } + void SetBackground(int color_pair_idx) { ::wbkgd(m_window, COLOR_PAIR(color_pair_idx)); } + void PutChar(int ch) { ::waddch(m_window, ch); } + void PutCString(const char *s, int len = -1) { ::waddnstr(m_window, s, len); } + void PutCStringTruncated(int right_pad, const char *s, int len = -1) { int bytes_left = GetWidth() - GetCursorX(); if (bytes_left > right_pad) { @@ -430,37 +393,10 @@ public: } } - void MoveWindow(const Point &origin) { - const bool moving_window = origin != GetParentOrigin(); - if (m_is_subwin && moving_window) { - // Can't move subwindows, must delete and re-create - Size size = GetSize(); - Reset(::subwin(m_parent->m_window, size.height, size.width, origin.y, - origin.x), - true); - } else { - ::mvwin(m_window, origin.y, origin.x); - } - } - - void SetBounds(const Rect &bounds) { - const bool moving_window = bounds.origin != GetParentOrigin(); - if (m_is_subwin && moving_window) { - // Can't move subwindows, must delete and re-create - Reset(::subwin(m_parent->m_window, bounds.size.height, bounds.size.width, - bounds.origin.y, bounds.origin.x), - true); - } else { - if (moving_window) - MoveWindow(bounds.origin); - Resize(bounds.size); - } - } - void Printf(const char *format, ...) __attribute__((format(printf, 2, 3))) { va_list args; va_start(args, format); - vwprintw(m_window, format, args); + vw_printw(m_window, format, args); va_end(args); } @@ -474,8 +410,54 @@ public: PutCStringTruncated(right_pad, strm.GetData()); } - size_t LimitLengthToRestOfLine(size_t length) const { - return std::min<size_t>(length, std::max(0, GetWidth() - GetCursorX() - 1)); + void VerticalLine(int n, chtype v_char = ACS_VLINE) { + ::wvline(m_window, v_char, n); + } + void HorizontalLine(int n, chtype h_char = ACS_HLINE) { + ::whline(m_window, h_char, n); + } + void Box(chtype v_char = ACS_VLINE, chtype h_char = ACS_HLINE) { + ::box(m_window, v_char, h_char); + } + + void TitledBox(const char *title, chtype v_char = ACS_VLINE, + chtype h_char = ACS_HLINE) { + Box(v_char, h_char); + int title_offset = 2; + MoveCursor(title_offset, 0); + PutChar('['); + PutCString(title, GetWidth() - title_offset); + PutChar(']'); + } + + void Box(const Rect &bounds, chtype v_char = ACS_VLINE, + chtype h_char = ACS_HLINE) { + MoveCursor(bounds.origin.x, bounds.origin.y); + VerticalLine(bounds.size.height); + HorizontalLine(bounds.size.width); + PutChar(ACS_ULCORNER); + + MoveCursor(bounds.origin.x + bounds.size.width - 1, bounds.origin.y); + VerticalLine(bounds.size.height); + PutChar(ACS_URCORNER); + + MoveCursor(bounds.origin.x, bounds.origin.y + bounds.size.height - 1); + HorizontalLine(bounds.size.width); + PutChar(ACS_LLCORNER); + + MoveCursor(bounds.origin.x + bounds.size.width - 1, + bounds.origin.y + bounds.size.height - 1); + PutChar(ACS_LRCORNER); + } + + void TitledBox(const Rect &bounds, const char *title, + chtype v_char = ACS_VLINE, chtype h_char = ACS_HLINE) { + Box(bounds, v_char, h_char); + int title_offset = 2; + MoveCursor(bounds.origin.x + title_offset, bounds.origin.y); + PutChar('['); + PutCString(title, bounds.size.width - title_offset); + PutChar(']'); } // Curses doesn't allow direct output of color escape sequences, but that's @@ -551,6 +533,130 @@ public: return result; } +protected: + WINDOW *m_window; +}; + +class Pad : public Surface { +public: + Pad(Size size) { m_window = ::newpad(size.height, size.width); } + + ~Pad() { ::delwin(m_window); } +}; + +class SubPad : public Surface { +public: + SubPad(Pad &pad, Rect bounds) { + m_window = ::subpad(pad.get(), bounds.size.height, bounds.size.width, + bounds.origin.y, bounds.origin.x); + } + SubPad(SubPad &subpad, Rect bounds) { + m_window = ::subpad(subpad.get(), bounds.size.height, bounds.size.width, + bounds.origin.y, bounds.origin.x); + } + + ~SubPad() { ::delwin(m_window); } +}; + +class Window : public Surface { +public: + Window(const char *name) + : m_name(name), m_panel(nullptr), m_parent(nullptr), m_subwindows(), + m_delegate_sp(), m_curr_active_window_idx(UINT32_MAX), + m_prev_active_window_idx(UINT32_MAX), m_delete(false), + m_needs_update(true), m_can_activate(true), m_is_subwin(false) {} + + Window(const char *name, WINDOW *w, bool del = true) + : m_name(name), m_panel(nullptr), m_parent(nullptr), m_subwindows(), + m_delegate_sp(), m_curr_active_window_idx(UINT32_MAX), + m_prev_active_window_idx(UINT32_MAX), m_delete(del), + m_needs_update(true), m_can_activate(true), m_is_subwin(false) { + if (w) + Reset(w); + } + + Window(const char *name, const Rect &bounds) + : m_name(name), m_parent(nullptr), m_subwindows(), m_delegate_sp(), + m_curr_active_window_idx(UINT32_MAX), + m_prev_active_window_idx(UINT32_MAX), m_delete(true), + m_needs_update(true), m_can_activate(true), m_is_subwin(false) { + Reset(::newwin(bounds.size.height, bounds.size.width, bounds.origin.y, + bounds.origin.y)); + } + + virtual ~Window() { + RemoveSubWindows(); + Reset(); + } + + void Reset(WINDOW *w = nullptr, bool del = true) { + if (m_window == w) + return; + + if (m_panel) { + ::del_panel(m_panel); + m_panel = nullptr; + } + if (m_window && m_delete) { + ::delwin(m_window); + m_window = nullptr; + m_delete = false; + } + if (w) { + m_window = w; + m_panel = ::new_panel(m_window); + m_delete = del; + } + } + + // Get the rectangle in our parent window + Rect GetBounds() const { return Rect(GetParentOrigin(), GetSize()); } + + Rect GetCenteredRect(int width, int height) { + Size size = GetSize(); + width = std::min(size.width, width); + height = std::min(size.height, height); + int x = (size.width - width) / 2; + int y = (size.height - height) / 2; + return Rect(Point(x, y), Size(width, height)); + } + + int GetChar() { return ::wgetch(m_window); } + Point GetParentOrigin() const { return Point(GetParentX(), GetParentY()); } + int GetParentX() const { return getparx(m_window); } + int GetParentY() const { return getpary(m_window); } + void MoveWindow(int x, int y) { MoveWindow(Point(x, y)); } + void Resize(int w, int h) { ::wresize(m_window, h, w); } + void Resize(const Size &size) { + ::wresize(m_window, size.height, size.width); + } + void MoveWindow(const Point &origin) { + const bool moving_window = origin != GetParentOrigin(); + if (m_is_subwin && moving_window) { + // Can't move subwindows, must delete and re-create + Size size = GetSize(); + Reset(::subwin(m_parent->m_window, size.height, size.width, origin.y, + origin.x), + true); + } else { + ::mvwin(m_window, origin.y, origin.x); + } + } + + void SetBounds(const Rect &bounds) { + const bool moving_window = bounds.origin != GetParentOrigin(); + if (m_is_subwin && moving_window) { + // Can't move subwindows, must delete and re-create + Reset(::subwin(m_parent->m_window, bounds.size.height, bounds.size.width, + bounds.origin.y, bounds.origin.x), + true); + } else { + if (moving_window) + MoveWindow(bounds.origin); + Resize(bounds.size); + } + } + void Touch() { ::touchwin(m_window); if (m_parent) @@ -631,10 +737,6 @@ public: ::touchwin(stdscr); } - WINDOW *get() { return m_window; } - - operator WINDOW *() { return m_window; } - // Window drawing utilities void DrawTitleBox(const char *title, const char *bottom_message = nullptr) { attr_t attr = 0; @@ -851,7 +953,6 @@ public: protected: std::string m_name; - WINDOW *m_window; PANEL *m_panel; Window *m_parent; Windows m_subwindows; @@ -868,6 +969,1688 @@ private: const Window &operator=(const Window &) = delete; }; +class DerivedWindow : public Surface { +public: + DerivedWindow(Window &window, Rect bounds) { + m_window = ::derwin(window.get(), bounds.size.height, bounds.size.width, + bounds.origin.y, bounds.origin.x); + } + DerivedWindow(DerivedWindow &derived_window, Rect bounds) { + m_window = ::derwin(derived_window.get(), bounds.size.height, + bounds.size.width, bounds.origin.y, bounds.origin.x); + } + + ~DerivedWindow() { ::delwin(m_window); } +}; + +///////// +// Forms +///////// + +// A scroll context defines a vertical region that needs to be visible in a +// scrolling area. The region is defined by the index of the start and end lines +// of the region. The start and end lines may be equal, in which case, the +// region is a single line. +struct ScrollContext { + int start; + int end; + + ScrollContext(int line) : start(line), end(line) {} + ScrollContext(int _start, int _end) : start(_start), end(_end) {} + + void Offset(int offset) { + start += offset; + end += offset; + } +}; + +class FieldDelegate { +public: + virtual ~FieldDelegate() = default; + + // Returns the number of lines needed to draw the field. The draw method will + // be given a surface that have exactly this number of lines. + virtual int FieldDelegateGetHeight() = 0; + + // Returns the scroll context in the local coordinates of the field. By + // default, the scroll context spans the whole field. Bigger fields with + // internal navigation should override this method to provide a finer context. + // Typical override methods would first get the scroll context of the internal + // element then add the offset of the element in the field. + virtual ScrollContext FieldDelegateGetScrollContext() { + return ScrollContext(0, FieldDelegateGetHeight() - 1); + } + + // Draw the field in the given subpad surface. The surface have a height that + // is equal to the height returned by FieldDelegateGetHeight(). If the field + // is selected in the form window, then is_selected will be true. + virtual void FieldDelegateDraw(SubPad &surface, bool is_selected) = 0; + + // Handle the key that wasn't handled by the form window or a container field. + virtual HandleCharResult FieldDelegateHandleChar(int key) { + return eKeyNotHandled; + } + + // This is executed once the user exists the field, that is, once the user + // navigates to the next or the previous field. This is particularly useful to + // do in-field validation and error setting. Fields with internal navigation + // should call this method on their fields. + virtual void FieldDelegateExitCallback() { return; } + + // Fields may have internal navigation, for instance, a List Field have + // multiple internal elements, which needs to be navigated. To allow for this + // mechanism, the window shouldn't handle the navigation keys all the time, + // and instead call the key handing method of the selected field. It should + // only handle the navigation keys when the field contains a single element or + // have the last or first element selected depending on if the user is + // navigating forward or backward. Additionally, once a field is selected in + // the forward or backward direction, its first or last internal element + // should be selected. The following methods implements those mechanisms. + + // Returns true if the first element in the field is selected or if the field + // contains a single element. + virtual bool FieldDelegateOnFirstOrOnlyElement() { return true; } + + // Returns true if the last element in the field is selected or if the field + // contains a single element. + virtual bool FieldDelegateOnLastOrOnlyElement() { return true; } + + // Select the first element in the field if multiple elements exists. + virtual void FieldDelegateSelectFirstElement() { return; } + + // Select the last element in the field if multiple elements exists. + virtual void FieldDelegateSelectLastElement() { return; } + + // Returns true if the field has an error, false otherwise. + virtual bool FieldDelegateHasError() { return false; } + + bool FieldDelegateIsVisible() { return m_is_visible; } + + void FieldDelegateHide() { m_is_visible = false; } + + void FieldDelegateShow() { m_is_visible = true; } + +protected: + bool m_is_visible = true; +}; + +typedef std::unique_ptr<FieldDelegate> FieldDelegateUP; + +class TextFieldDelegate : public FieldDelegate { +public: + TextFieldDelegate(const char *label, const char *content, bool required) + : m_label(label), m_required(required), m_cursor_position(0), + m_first_visibile_char(0) { + if (content) + m_content = content; + } + + // Text fields are drawn as titled boxes of a single line, with a possible + // error messages at the end. + // + // __[Label]___________ + // | | + // |__________________| + // - Error message if it exists. + + // The text field has a height of 3 lines. 2 lines for borders and 1 line for + // the content. + int GetFieldHeight() { return 3; } + + // The text field has a full height of 3 or 4 lines. 3 lines for the actual + // field and an optional line for an error if it exists. + int FieldDelegateGetHeight() override { + int height = GetFieldHeight(); + if (FieldDelegateHasError()) + height++; + return height; + } + + // Get the cursor X position in the surface coordinate. + int GetCursorXPosition() { return m_cursor_position - m_first_visibile_char; } + + int GetContentLength() { return m_content.length(); } + + void DrawContent(SubPad &surface, bool is_selected) { + surface.MoveCursor(0, 0); + const char *text = m_content.c_str() + m_first_visibile_char; + surface.PutCString(text, surface.GetWidth()); + m_last_drawn_content_width = surface.GetWidth(); + + // Highlight the cursor. + surface.MoveCursor(GetCursorXPosition(), 0); + if (is_selected) + surface.AttributeOn(A_REVERSE); + if (m_cursor_position == GetContentLength()) + // Cursor is past the last character. Highlight an empty space. + surface.PutChar(' '); + else + surface.PutChar(m_content[m_cursor_position]); + if (is_selected) + surface.AttributeOff(A_REVERSE); + } + + void DrawField(SubPad &surface, bool is_selected) { + surface.TitledBox(m_label.c_str()); + + Rect content_bounds = surface.GetFrame(); + content_bounds.Inset(1, 1); + SubPad content_surface = SubPad(surface, content_bounds); + + DrawContent(content_surface, is_selected); + } + + void DrawError(SubPad &surface) { + if (!FieldDelegateHasError()) + return; + surface.MoveCursor(0, 0); + surface.AttributeOn(COLOR_PAIR(RedOnBlack)); + surface.PutChar(ACS_DIAMOND); + surface.PutChar(' '); + surface.PutCStringTruncated(1, GetError().c_str()); + surface.AttributeOff(COLOR_PAIR(RedOnBlack)); + } + + void FieldDelegateDraw(SubPad &surface, bool is_selected) override { + Rect frame = surface.GetFrame(); + Rect field_bounds, error_bounds; + frame.HorizontalSplit(GetFieldHeight(), field_bounds, error_bounds); + SubPad field_surface = SubPad(surface, field_bounds); + SubPad error_surface = SubPad(surface, error_bounds); + + DrawField(field_surface, is_selected); + DrawError(error_surface); + } + + // The cursor is allowed to move one character past the string. + // m_cursor_position is in range [0, GetContentLength()]. + void MoveCursorRight() { + if (m_cursor_position < GetContentLength()) + m_cursor_position++; + } + + void MoveCursorLeft() { + if (m_cursor_position > 0) + m_cursor_position--; + } + + // If the cursor moved past the last visible character, scroll right by one + // character. + void ScrollRightIfNeeded() { + if (m_cursor_position - m_first_visibile_char == m_last_drawn_content_width) + m_first_visibile_char++; + } + + void ScrollLeft() { + if (m_first_visibile_char > 0) + m_first_visibile_char--; + } + + // If the cursor moved past the first visible character, scroll left by one + // character. + void ScrollLeftIfNeeded() { + if (m_cursor_position < m_first_visibile_char) + m_first_visibile_char--; + } + + // Insert a character at the current cursor position, advance the cursor + // position, and make sure to scroll right if needed. + void InsertChar(char character) { + m_content.insert(m_cursor_position, 1, character); + m_cursor_position++; + ScrollRightIfNeeded(); + } + + // Remove the character before the cursor position, retreat the cursor + // position, and make sure to scroll left if needed. + void RemoveChar() { + if (m_cursor_position == 0) + return; + + m_content.erase(m_cursor_position - 1, 1); + m_cursor_position--; + ScrollLeft(); + } + + // True if the key represents a char that can be inserted in the field + // content, false otherwise. + virtual bool IsAcceptableChar(int key) { return isprint(key); } + + HandleCharResult FieldDelegateHandleChar(int key) override { + if (IsAcceptableChar(key)) { + ClearError(); + InsertChar((char)key); + return eKeyHandled; + } + + switch (key) { + case KEY_RIGHT: + MoveCursorRight(); + ScrollRightIfNeeded(); + return eKeyHandled; + case KEY_LEFT: + MoveCursorLeft(); + ScrollLeftIfNeeded(); + return eKeyHandled; + case KEY_BACKSPACE: + ClearError(); + RemoveChar(); + return eKeyHandled; + default: + break; + } + return eKeyNotHandled; + } + + bool FieldDelegateHasError() override { return !m_error.empty(); } + + void FieldDelegateExitCallback() override { + if (!IsSpecified() && m_required) + SetError("This field is required!"); + } + + bool IsSpecified() { return !m_content.empty(); } + + void ClearError() { m_error.clear(); } + + const std::string &GetError() { return m_error; } + + void SetError(const char *error) { m_error = error; } + + const std::string &GetText() { return m_content; } + +protected: + std::string m_label; + bool m_required; + // The position of the top left corner character of the border. + std::string m_content; + // The cursor position in the content string itself. Can be in the range + // [0, GetContentLength()]. + int m_cursor_position; + // The index of the first visible character in the content. + int m_first_visibile_char; + // The width of the fields content that was last drawn. Width can change, so + // this is used to determine if scrolling is needed dynamically. + int m_last_drawn_content_width; + // Optional error message. If empty, field is considered to have no error. + std::string m_error; +}; + +class IntegerFieldDelegate : public TextFieldDelegate { +public: + IntegerFieldDelegate(const char *label, int content, bool required) + : TextFieldDelegate(label, std::to_string(content).c_str(), required) {} + + // Only accept digits. + bool IsAcceptableChar(int key) override { return isdigit(key); } + + // Returns the integer content of the field. + int GetInteger() { return std::stoi(m_content); } +}; + +class FileFieldDelegate : public TextFieldDelegate { +public: + FileFieldDelegate(const char *label, const char *content, bool need_to_exist, + bool required) + : TextFieldDelegate(label, content, required), + m_need_to_exist(need_to_exist) {} + + void FieldDelegateExitCallback() override { + TextFieldDelegate::FieldDelegateExitCallback(); + if (!IsSpecified()) + return; + + if (!m_need_to_exist) + return; + + FileSpec file = GetResolvedFileSpec(); + if (!FileSystem::Instance().Exists(file)) { + SetError("File doesn't exist!"); + return; + } + if (FileSystem::Instance().IsDirectory(file)) { + SetError("Not a file!"); + return; + } + } + + FileSpec GetFileSpec() { + FileSpec file_spec(GetPath()); + return file_spec; + } + + FileSpec GetResolvedFileSpec() { + FileSpec file_spec(GetPath()); + FileSystem::Instance().Resolve(file_spec); + return file_spec; + } + + const std::string &GetPath() { return m_content; } + +protected: + bool m_need_to_exist; +}; + +class DirectoryFieldDelegate : public TextFieldDelegate { +public: + DirectoryFieldDelegate(const char *label, const char *content, + bool need_to_exist, bool required) + : TextFieldDelegate(label, content, required), + m_need_to_exist(need_to_exist) {} + + void FieldDelegateExitCallback() override { + TextFieldDelegate::FieldDelegateExitCallback(); + if (!IsSpecified()) + return; + + if (!m_need_to_exist) + return; + + FileSpec file = GetResolvedFileSpec(); + if (!FileSystem::Instance().Exists(file)) { + SetError("Directory doesn't exist!"); + return; + } + if (!FileSystem::Instance().IsDirectory(file)) { + SetError("Not a directory!"); + return; + } + } + + FileSpec GetFileSpec() { + FileSpec file_spec(GetPath()); + return file_spec; + } + + FileSpec GetResolvedFileSpec() { + FileSpec file_spec(GetPath()); + FileSystem::Instance().Resolve(file_spec); + return file_spec; + } + + const std::string &GetPath() { return m_content; } + +protected: + bool m_need_to_exist; +}; + +class ArchFieldDelegate : public TextFieldDelegate { +public: + ArchFieldDelegate(const char *label, const char *content, bool required) + : TextFieldDelegate(label, content, required) {} + + void FieldDelegateExitCallback() override { + TextFieldDelegate::FieldDelegateExitCallback(); + if (!IsSpecified()) + return; + + if (!GetArchSpec().IsValid()) + SetError("Not a valid arch!"); + } + + const std::string &GetArchString() { return m_content; } + + ArchSpec GetArchSpec() { return ArchSpec(GetArchString()); } +}; + +class BooleanFieldDelegate : public FieldDelegate { +public: + BooleanFieldDelegate(const char *label, bool content) + : m_label(label), m_content(content) {} + + // Boolean fields are drawn as checkboxes. + // + // [X] Label or [ ] Label + + // Boolean fields are have a single line. + int FieldDelegateGetHeight() override { return 1; } + + void FieldDelegateDraw(SubPad &surface, bool is_selected) override { + surface.MoveCursor(0, 0); + surface.PutChar('['); + if (is_selected) + surface.AttributeOn(A_REVERSE); + surface.PutChar(m_content ? ACS_DIAMOND : ' '); + if (is_selected) + surface.AttributeOff(A_REVERSE); + surface.PutChar(']'); + surface.PutChar(' '); + surface.PutCString(m_label.c_str()); + } + + void ToggleContent() { m_content = !m_content; } + + void SetContentToTrue() { m_content = true; } + + void SetContentToFalse() { m_content = false; } + + HandleCharResult FieldDelegateHandleChar(int key) override { + switch (key) { + case 't': + case '1': + SetContentToTrue(); + return eKeyHandled; + case 'f': + case '0': + SetContentToFalse(); + return eKeyHandled; + case ' ': + case '\r': + case '\n': + case KEY_ENTER: + ToggleContent(); + return eKeyHandled; + default: + break; + } + return eKeyNotHandled; + } + + // Returns the boolean content of the field. + bool GetBoolean() { return m_content; } + +protected: + std::string m_label; + bool m_content; +}; + +class ChoicesFieldDelegate : public FieldDelegate { +public: + ChoicesFieldDelegate(const char *label, int number_of_visible_choices, + std::vector<std::string> choices) + : m_label(label), m_number_of_visible_choices(number_of_visible_choices), + m_choices(choices), m_choice(0), m_first_visibile_choice(0) {} + + // Choices fields are drawn as titles boxses of a number of visible choices. + // The rest of the choices become visible as the user scroll. The selected + // choice is denoted by a diamond as the first character. + // + // __[Label]___________ + // |-Choice 1 | + // | Choice 2 | + // | Choice 3 | + // |__________________| + + // Choices field have two border characters plus the number of visible + // choices. + int FieldDelegateGetHeight() override { + return m_number_of_visible_choices + 2; + } + + int GetNumberOfChoices() { return m_choices.size(); } + + // Get the index of the last visible choice. + int GetLastVisibleChoice() { + int index = m_first_visibile_choice + m_number_of_visible_choices; + return std::min(index, GetNumberOfChoices()) - 1; + } + + void DrawContent(SubPad &surface, bool is_selected) { + int choices_to_draw = GetLastVisibleChoice() - m_first_visibile_choice + 1; + for (int i = 0; i < choices_to_draw; i++) { + surface.MoveCursor(0, i); + int current_choice = m_first_visibile_choice + i; + const char *text = m_choices[current_choice].c_str(); + bool highlight = is_selected && current_choice == m_choice; + if (highlight) + surface.AttributeOn(A_REVERSE); + surface.PutChar(current_choice == m_choice ? ACS_DIAMOND : ' '); + surface.PutCString(text); + if (highlight) + surface.AttributeOff(A_REVERSE); + } + } + + void FieldDelegateDraw(SubPad &surface, bool is_selected) override { + UpdateScrolling(); + + surface.TitledBox(m_label.c_str()); + + Rect content_bounds = surface.GetFrame(); + content_bounds.Inset(1, 1); + SubPad content_surface = SubPad(surface, content_bounds); + + DrawContent(content_surface, is_selected); + } + + void SelectPrevious() { + if (m_choice > 0) + m_choice--; + } + + void SelectNext() { + if (m_choice < GetNumberOfChoices() - 1) + m_choice++; + } + + void UpdateScrolling() { + if (m_choice > GetLastVisibleChoice()) { + m_first_visibile_choice = m_choice - (m_number_of_visible_choices - 1); + return; + } + + if (m_choice < m_first_visibile_choice) + m_first_visibile_choice = m_choice; + } + + HandleCharResult FieldDelegateHandleChar(int key) override { + switch (key) { + case KEY_UP: + SelectPrevious(); + return eKeyHandled; + case KEY_DOWN: + SelectNext(); + return eKeyHandled; + default: + break; + } + return eKeyNotHandled; + } + + // Returns the content of the choice as a string. + std::string GetChoiceContent() { return m_choices[m_choice]; } + + // Returns the index of the choice. + int GetChoice() { return m_choice; } + + void SetChoice(const std::string &choice) { + for (int i = 0; i < GetNumberOfChoices(); i++) { + if (choice == m_choices[i]) { + m_choice = i; + return; + } + } + } + +protected: + std::string m_label; + int m_number_of_visible_choices; + std::vector<std::string> m_choices; + // The index of the selected choice. + int m_choice; + // The index of the first visible choice in the field. + int m_first_visibile_choice; +}; + +class PlatformPluginFieldDelegate : public ChoicesFieldDelegate { +public: + PlatformPluginFieldDelegate(Debugger &debugger) + : ChoicesFieldDelegate("Platform Plugin", 3, GetPossiblePluginNames()) { + PlatformSP platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); + if (platform_sp) + SetChoice(platform_sp->GetName().AsCString()); + } + + std::vector<std::string> GetPossiblePluginNames() { + std::vector<std::string> names; + size_t i = 0; + while (auto name = PluginManager::GetPlatformPluginNameAtIndex(i++)) + names.push_back(name); + return names; + } + + std::string GetPluginName() { + std::string plugin_name = GetChoiceContent(); + return plugin_name; + } +}; + +class ProcessPluginFieldDelegate : public ChoicesFieldDelegate { +public: + ProcessPluginFieldDelegate() + : ChoicesFieldDelegate("Process Plugin", 3, GetPossiblePluginNames()) {} + + std::vector<std::string> GetPossiblePluginNames() { + std::vector<std::string> names; + names.push_back("<default>"); + + size_t i = 0; + while (auto name = PluginManager::GetProcessPluginNameAtIndex(i++)) + names.push_back(name); + return names; + } + + std::string GetPluginName() { + std::string plugin_name = GetChoiceContent(); + if (plugin_name == "<default>") + return ""; + return plugin_name; + } +}; + +template <class T> class ListFieldDelegate : public FieldDelegate { +public: + ListFieldDelegate(const char *label, T default_field) + : m_label(label), m_default_field(default_field), m_selection_index(0), + m_selection_type(SelectionType::NewButton) {} + + // Signify which element is selected. If a field or a remove button is + // selected, then m_selection_index signifies the particular field that + // is selected or the field that the remove button belongs to. + enum class SelectionType { Field, RemoveButton, NewButton }; + + // A List field is drawn as a titled box of a number of other fields of the + // same type. Each field has a Remove button next to it that removes the + // corresponding field. Finally, the last line contains a New button to add a + // new field. + // + // __[Label]___________ + // | Field 0 [Remove] | + // | Field 1 [Remove] | + // | Field 2 [Remove] | + // | [New] | + // |__________________| + + // List fields have two lines for border characters, 1 line for the New + // button, and the total height of the available fields. + int FieldDelegateGetHeight() override { + // 2 border characters. + int height = 2; + // Total height of the fields. + for (int i = 0; i < GetNumberOfFields(); i++) { + height += m_fields[i].FieldDelegateGetHeight(); + } + // A line for the New button. + height++; + return height; + } + + ScrollContext FieldDelegateGetScrollContext() override { + int height = FieldDelegateGetHeight(); + if (m_selection_type == SelectionType::NewButton) + return ScrollContext(height - 2, height - 1); + + FieldDelegate &field = m_fields[m_selection_index]; + ScrollContext context = field.FieldDelegateGetScrollContext(); + + // Start at 1 because of the top border. + int offset = 1; + for (int i = 0; i < m_selection_index; i++) { + offset += m_fields[i].FieldDelegateGetHeight(); + } + context.Offset(offset); + + // If the scroll context is touching the top border, include it in the + // context to show the label. + if (context.start == 1) + context.start--; + + // If the scroll context is touching the new button, include it as well as + // the bottom border in the context. + if (context.end == height - 3) + context.end += 2; + + return context; + } + + void DrawRemoveButton(SubPad &surface, int highlight) { + surface.MoveCursor(1, surface.GetHeight() / 2); + if (highlight) + surface.AttributeOn(A_REVERSE); + surface.PutCString("[Remove]"); + if (highlight) + surface.AttributeOff(A_REVERSE); + } + + void DrawFields(SubPad &surface, bool is_selected) { + int line = 0; + int width = surface.GetWidth(); + for (int i = 0; i < GetNumberOfFields(); i++) { + int height = m_fields[i].FieldDelegateGetHeight(); + Rect bounds = Rect(Point(0, line), Size(width, height)); + Rect field_bounds, remove_button_bounds; + bounds.VerticalSplit(bounds.size.width - sizeof(" [Remove]"), + field_bounds, remove_button_bounds); + SubPad field_surface = SubPad(surface, field_bounds); + SubPad remove_button_surface = SubPad(surface, remove_button_bounds); + + bool is_element_selected = m_selection_index == i && is_selected; + bool is_field_selected = + is_element_selected && m_selection_type == SelectionType::Field; + bool is_remove_button_selected = + is_element_selected && + m_selection_type == SelectionType::RemoveButton; + m_fields[i].FieldDelegateDraw(field_surface, is_field_selected); + DrawRemoveButton(remove_button_surface, is_remove_button_selected); + + line += height; + } + } + + void DrawNewButton(SubPad &surface, bool is_selected) { + const char *button_text = "[New]"; + int x = (surface.GetWidth() - sizeof(button_text) - 1) / 2; + surface.MoveCursor(x, 0); + bool highlight = + is_selected && m_selection_type == SelectionType::NewButton; + if (highlight) + surface.AttributeOn(A_REVERSE); + surface.PutCString(button_text); + if (highlight) + surface.AttributeOff(A_REVERSE); + } + + void FieldDelegateDraw(SubPad &surface, bool is_selected) override { + surface.TitledBox(m_label.c_str()); + + Rect content_bounds = surface.GetFrame(); + content_bounds.Inset(1, 1); + Rect fields_bounds, new_button_bounds; + content_bounds.HorizontalSplit(content_bounds.size.height - 1, + fields_bounds, new_button_bounds); + SubPad fields_surface = SubPad(surface, fields_bounds); + SubPad new_button_surface = SubPad(surface, new_button_bounds); + + DrawFields(fields_surface, is_selected); + DrawNewButton(new_button_surface, is_selected); + } + + void AddNewField() { + m_fields.push_back(m_default_field); + m_selection_index = GetNumberOfFields() - 1; + m_selection_type = SelectionType::Field; + FieldDelegate &field = m_fields[m_selection_index]; + field.FieldDelegateSelectFirstElement(); + } + + void RemoveField() { + m_fields.erase(m_fields.begin() + m_selection_index); + if (m_selection_index != 0) + m_selection_index--; + + if (GetNumberOfFields() > 0) { + m_selection_type = SelectionType::Field; + FieldDelegate &field = m_fields[m_selection_index]; + field.FieldDelegateSelectFirstElement(); + } else + m_selection_type = SelectionType::NewButton; + } + + HandleCharResult SelectNext(int key) { + if (m_selection_type == SelectionType::NewButton) + return eKeyNotHandled; + + if (m_selection_type == SelectionType::RemoveButton) { + if (m_selection_index == GetNumberOfFields() - 1) { + m_selection_type = SelectionType::NewButton; + return eKeyHandled; + } + m_selection_index++; + m_selection_type = SelectionType::Field; + FieldDelegate &next_field = m_fields[m_selection_index]; + next_field.FieldDelegateSelectFirstElement(); + return eKeyHandled; + } + + FieldDelegate &field = m_fields[m_selection_index]; + if (!field.FieldDelegateOnLastOrOnlyElement()) { + return field.FieldDelegateHandleChar(key); + } + + field.FieldDelegateExitCallback(); + + m_selection_type = SelectionType::RemoveButton; + return eKeyHandled; + } + + HandleCharResult SelectPrevious(int key) { + if (FieldDelegateOnFirstOrOnlyElement()) + return eKeyNotHandled; + + if (m_selection_type == SelectionType::RemoveButton) { + m_selection_type = SelectionType::Field; + FieldDelegate &field = m_fields[m_selection_index]; + field.FieldDelegateSelectLastElement(); + return eKeyHandled; + } + + if (m_selection_type == SelectionType::NewButton) { + m_selection_type = SelectionType::RemoveButton; + m_selection_index = GetNumberOfFields() - 1; + return eKeyHandled; + } + + FieldDelegate &field = m_fields[m_selection_index]; + if (!field.FieldDelegateOnFirstOrOnlyElement()) { + return field.FieldDelegateHandleChar(key); + } + + field.FieldDelegateExitCallback(); + + m_selection_type = SelectionType::RemoveButton; + m_selection_index--; + return eKeyHandled; + } + + HandleCharResult FieldDelegateHandleChar(int key) override { + switch (key) { + case '\r': + case '\n': + case KEY_ENTER: + switch (m_selection_type) { + case SelectionType::NewButton: + AddNewField(); + return eKeyHandled; + case SelectionType::RemoveButton: + RemoveField(); + return eKeyHandled; + default: + break; + } + break; + case '\t': + SelectNext(key); + return eKeyHandled; + case KEY_SHIFT_TAB: + SelectPrevious(key); + return eKeyHandled; + default: + break; + } + + // If the key wasn't handled and one of the fields is selected, pass the key + // to that field. + if (m_selection_type == SelectionType::Field) { + return m_fields[m_selection_index].FieldDelegateHandleChar(key); + } + + return eKeyNotHandled; + } + + bool FieldDelegateOnLastOrOnlyElement() override { + if (m_selection_type == SelectionType::NewButton) { + return true; + } + return false; + } + + bool FieldDelegateOnFirstOrOnlyElement() override { + if (m_selection_type == SelectionType::NewButton && + GetNumberOfFields() == 0) + return true; + + if (m_selection_type == SelectionType::Field && m_selection_index == 0) { + FieldDelegate &field = m_fields[m_selection_index]; + return field.FieldDelegateOnFirstOrOnlyElement(); + } + + return false; + } + + void FieldDelegateSelectFirstElement() override { + if (GetNumberOfFields() == 0) { + m_selection_type = SelectionType::NewButton; + return; + } + + m_selection_type = SelectionType::Field; + m_selection_index = 0; + } + + void FieldDelegateSelectLastElement() override { + m_selection_type = SelectionType::NewButton; + return; + } + + int GetNumberOfFields() { return m_fields.size(); } + + // Returns the form delegate at the current index. + T &GetField(int index) { return m_fields[index]; } + +protected: + std::string m_label; + // The default field delegate instance from which new field delegates will be + // created though a copy. + T m_default_field; + std::vector<T> m_fields; + int m_selection_index; + // See SelectionType class enum. + SelectionType m_selection_type; +}; + +class FormAction { +public: + FormAction(const char *label, std::function<void(Window &)> action) + : m_action(action) { + if (label) + m_label = label; + } + + // Draw a centered [Label]. + void Draw(SubPad &surface, bool is_selected) { + int x = (surface.GetWidth() - m_label.length()) / 2; + surface.MoveCursor(x, 0); + if (is_selected) + surface.AttributeOn(A_REVERSE); + surface.PutChar('['); + surface.PutCString(m_label.c_str()); + surface.PutChar(']'); + if (is_selected) + surface.AttributeOff(A_REVERSE); + } + + void Execute(Window &window) { m_action(window); } + + const std::string &GetLabel() { return m_label; } + +protected: + std::string m_label; + std::function<void(Window &)> m_action; +}; + +class FormDelegate { +public: + FormDelegate() {} + + virtual ~FormDelegate() = default; + + virtual std::string GetName() = 0; + + virtual void UpdateFieldsVisibility() { return; } + + FieldDelegate *GetField(uint32_t field_index) { + if (field_index < m_fields.size()) + return m_fields[field_index].get(); + return nullptr; + } + + FormAction &GetAction(int action_index) { return m_actions[action_index]; } + + int GetNumberOfFields() { return m_fields.size(); } + + int GetNumberOfActions() { return m_actions.size(); } + + bool HasError() { return !m_error.empty(); } + + void ClearError() { m_error.clear(); } + + const std::string &GetError() { return m_error; } + + void SetError(const char *error) { m_error = error; } + + // If all fields are valid, true is returned. Otherwise, an error message is + // set and false is returned. This method is usually called at the start of an + // action that requires valid fields. + bool CheckFieldsValidity() { + for (int i = 0; i < GetNumberOfFields(); i++) { + if (GetField(i)->FieldDelegateHasError()) { + SetError("Some fields are invalid!"); + return false; + } + } + return true; + } + + // Factory methods to create and add fields of specific types. + + TextFieldDelegate *AddTextField(const char *label, const char *content, + bool required) { + TextFieldDelegate *delegate = + new TextFieldDelegate(label, content, required); + m_fields.push_back(FieldDelegateUP(delegate)); + return delegate; + } + + FileFieldDelegate *AddFileField(const char *label, const char *content, + bool need_to_exist, bool required) { + FileFieldDelegate *delegate = + new FileFieldDelegate(label, content, need_to_exist, required); + m_fields.push_back(FieldDelegateUP(delegate)); + return delegate; + } + + DirectoryFieldDelegate *AddDirectoryField(const char *label, + const char *content, + bool need_to_exist, bool required) { + DirectoryFieldDelegate *delegate = + new DirectoryFieldDelegate(label, content, need_to_exist, required); + m_fields.push_back(FieldDelegateUP(delegate)); + return delegate; + } + + ArchFieldDelegate *AddArchField(const char *label, const char *content, + bool required) { + ArchFieldDelegate *delegate = + new ArchFieldDelegate(label, content, required); + m_fields.push_back(FieldDelegateUP(delegate)); + return delegate; + } + + IntegerFieldDelegate *AddIntegerField(const char *label, int content, + bool required) { + IntegerFieldDelegate *delegate = + new IntegerFieldDelegate(label, content, required); + m_fields.push_back(FieldDelegateUP(delegate)); + return delegate; + } + + BooleanFieldDelegate *AddBooleanField(const char *label, bool content) { + BooleanFieldDelegate *delegate = new BooleanFieldDelegate(label, content); + m_fields.push_back(FieldDelegateUP(delegate)); + return delegate; + } + + ChoicesFieldDelegate *AddChoicesField(const char *label, int height, + std::vector<std::string> choices) { + ChoicesFieldDelegate *delegate = + new ChoicesFieldDelegate(label, height, choices); + m_fields.push_back(FieldDelegateUP(delegate)); + return delegate; + } + + PlatformPluginFieldDelegate *AddPlatformPluginField(Debugger &debugger) { + PlatformPluginFieldDelegate *delegate = + new PlatformPluginFieldDelegate(debugger); + m_fields.push_back(FieldDelegateUP(delegate)); + return delegate; + } + + ProcessPluginFieldDelegate *AddProcessPluginField() { + ProcessPluginFieldDelegate *delegate = new ProcessPluginFieldDelegate(); + m_fields.push_back(FieldDelegateUP(delegate)); + return delegate; + } + + template <class T> + ListFieldDelegate<T> *AddListField(const char *label, T default_field) { + ListFieldDelegate<T> *delegate = + new ListFieldDelegate<T>(label, default_field); + m_fields.push_back(FieldDelegateUP(delegate)); + return delegate; + } + + // Factory methods for adding actions. + + void AddAction(const char *label, std::function<void(Window &)> action) { + m_actions.push_back(FormAction(label, action)); + } + +protected: + std::vector<FieldDelegateUP> m_fields; + std::vector<FormAction> m_actions; + // Optional error message. If empty, form is considered to have no error. + std::string m_error; +}; + +typedef std::shared_ptr<FormDelegate> FormDelegateSP; + +class FormWindowDelegate : public WindowDelegate { +public: + FormWindowDelegate(FormDelegateSP &delegate_sp) + : m_delegate_sp(delegate_sp), m_selection_index(0), + m_first_visible_line(0) { + assert(m_delegate_sp->GetNumberOfActions() > 0); + if (m_delegate_sp->GetNumberOfFields() > 0) + m_selection_type = SelectionType::Field; + else + m_selection_type = SelectionType::Action; + } + + // Signify which element is selected. If a field or an action is selected, + // then m_selection_index signifies the particular field or action that is + // selected. + enum class SelectionType { Field, Action }; + + // A form window is padded by one character from all sides. First, if an error + // message exists, it is drawn followed by a separator. Then one or more + // fields are drawn. Finally, all available actions are drawn on a single + // line. + // + // ___<Form Name>_________________________________________________ + // | | + // | - Error message if it exists. | + // |-------------------------------------------------------------| + // | Form elements here. | + // | Form actions here. | + // | | + // |______________________________________[Press Esc to cancel]__| + // + + // One line for the error and another for the horizontal line. + int GetErrorHeight() { + if (m_delegate_sp->HasError()) + return 2; + return 0; + } + + // Actions span a single line. + int GetActionsHeight() { + if (m_delegate_sp->GetNumberOfActions() > 0) + return 1; + return 0; + } + + // Get the total number of needed lines to draw the contents. + int GetContentHeight() { + int height = 0; + height += GetErrorHeight(); + for (int i = 0; i < m_delegate_sp->GetNumberOfFields(); i++) { + if (!m_delegate_sp->GetField(i)->FieldDelegateIsVisible()) + continue; + height += m_delegate_sp->GetField(i)->FieldDelegateGetHeight(); + } + height += GetActionsHeight(); + return height; + } + + ScrollContext GetScrollContext() { + if (m_selection_type == SelectionType::Action) + return ScrollContext(GetContentHeight() - 1); + + FieldDelegate *field = m_delegate_sp->GetField(m_selection_index); + ScrollContext context = field->FieldDelegateGetScrollContext(); + + int offset = GetErrorHeight(); + for (int i = 0; i < m_selection_index; i++) { + if (!m_delegate_sp->GetField(i)->FieldDelegateIsVisible()) + continue; + offset += m_delegate_sp->GetField(i)->FieldDelegateGetHeight(); + } + context.Offset(offset); + + // If the context is touching the error, include the error in the context as + // well. + if (context.start == GetErrorHeight()) + context.start = 0; + + return context; + } + + void UpdateScrolling(DerivedWindow &surface) { + ScrollContext context = GetScrollContext(); + int content_height = GetContentHeight(); + int surface_height = surface.GetHeight(); + int visible_height = std::min(content_height, surface_height); + int last_visible_line = m_first_visible_line + visible_height - 1; + + // If the last visible line is bigger than the content, then it is invalid + // and needs to be set to the last line in the content. This can happen when + // a field has shrunk in height. + if (last_visible_line > content_height - 1) { + m_first_visible_line = content_height - visible_height; + } + + if (context.start < m_first_visible_line) { + m_first_visible_line = context.start; + return; + } + + if (context.end > last_visible_line) { + m_first_visible_line = context.end - visible_height + 1; + } + } + + void DrawError(SubPad &surface) { + if (!m_delegate_sp->HasError()) + return; + surface.MoveCursor(0, 0); + surface.AttributeOn(COLOR_PAIR(RedOnBlack)); + surface.PutChar(ACS_DIAMOND); + surface.PutChar(' '); + surface.PutCStringTruncated(1, m_delegate_sp->GetError().c_str()); + surface.AttributeOff(COLOR_PAIR(RedOnBlack)); + + surface.MoveCursor(0, 1); + surface.HorizontalLine(surface.GetWidth()); + } + + void DrawFields(SubPad &surface) { + int line = 0; + int width = surface.GetWidth(); + bool a_field_is_selected = m_selection_type == SelectionType::Field; + for (int i = 0; i < m_delegate_sp->GetNumberOfFields(); i++) { + FieldDelegate *field = m_delegate_sp->GetField(i); + if (!field->FieldDelegateIsVisible()) + continue; + bool is_field_selected = a_field_is_selected && m_selection_index == i; + int height = field->FieldDelegateGetHeight(); + Rect bounds = Rect(Point(0, line), Size(width, height)); + SubPad field_surface = SubPad(surface, bounds); + field->FieldDelegateDraw(field_surface, is_field_selected); + line += height; + } + } + + void DrawActions(SubPad &surface) { + int number_of_actions = m_delegate_sp->GetNumberOfActions(); + int width = surface.GetWidth() / number_of_actions; + bool an_action_is_selected = m_selection_type == SelectionType::Action; + int x = 0; + for (int i = 0; i < number_of_actions; i++) { + bool is_action_selected = an_action_is_selected && m_selection_index == i; + FormAction &action = m_delegate_sp->GetAction(i); + Rect bounds = Rect(Point(x, 0), Size(width, 1)); + SubPad action_surface = SubPad(surface, bounds); + action.Draw(action_surface, is_action_selected); + x += width; + } + } + + void DrawElements(SubPad &surface) { + Rect frame = surface.GetFrame(); + Rect fields_bounds, actions_bounds; + frame.HorizontalSplit(surface.GetHeight() - GetActionsHeight(), + fields_bounds, actions_bounds); + SubPad fields_surface = SubPad(surface, fields_bounds); + SubPad actions_surface = SubPad(surface, actions_bounds); + + DrawFields(fields_surface); + DrawActions(actions_surface); + } + + // Contents are first drawn on a pad. Then a subset of that pad is copied to + // the derived window starting at the first visible line. This essentially + // provides scrolling functionality. + void DrawContent(DerivedWindow &surface) { + UpdateScrolling(surface); + + int width = surface.GetWidth(); + int height = GetContentHeight(); + Pad pad = Pad(Size(width, height)); + + Rect frame = pad.GetFrame(); + Rect error_bounds, elements_bounds; + frame.HorizontalSplit(GetErrorHeight(), error_bounds, elements_bounds); + SubPad error_surface = SubPad(pad, error_bounds); + SubPad elements_surface = SubPad(pad, elements_bounds); + + DrawError(error_surface); + DrawElements(elements_surface); + + int copy_height = std::min(surface.GetHeight(), pad.GetHeight()); + pad.CopyToSurface(surface, Point(0, m_first_visible_line), Point(), + Size(width, copy_height)); + } + + bool WindowDelegateDraw(Window &window, bool force) override { + m_delegate_sp->UpdateFieldsVisibility(); + + window.Erase(); + + window.DrawTitleBox(m_delegate_sp->GetName().c_str(), + "Press Esc to cancel"); + + Rect content_bounds = window.GetFrame(); + content_bounds.Inset(2, 2); + DerivedWindow content_surface = DerivedWindow(window, content_bounds); + + DrawContent(content_surface); + return true; + } + + void SkipNextHiddenFields() { + while (true) { + if (m_delegate_sp->GetField(m_selection_index)->FieldDelegateIsVisible()) + return; + + if (m_selection_index == m_delegate_sp->GetNumberOfFields() - 1) { + m_selection_type = SelectionType::Action; + m_selection_index = 0; + return; + } + + m_selection_index++; + } + } + + HandleCharResult SelectNext(int key) { + if (m_selection_type == SelectionType::Action) { + if (m_selection_index < m_delegate_sp->GetNumberOfActions() - 1) { + m_selection_index++; + return eKeyHandled; + } + + m_selection_index = 0; + m_selection_type = SelectionType::Field; + SkipNextHiddenFields(); + if (m_selection_type == SelectionType::Field) { + FieldDelegate *next_field = m_delegate_sp->GetField(m_selection_index); + next_field->FieldDelegateSelectFirstElement(); + } + return eKeyHandled; + } + + FieldDelegate *field = m_delegate_sp->GetField(m_selection_index); + if (!field->FieldDelegateOnLastOrOnlyElement()) { + return field->FieldDelegateHandleChar(key); + } + + field->FieldDelegateExitCallback(); + + if (m_selection_index == m_delegate_sp->GetNumberOfFields() - 1) { + m_selection_type = SelectionType::Action; + m_selection_index = 0; + return eKeyHandled; + } + + m_selection_index++; + SkipNextHiddenFields(); + + if (m_selection_type == SelectionType::Field) { + FieldDelegate *next_field = m_delegate_sp->GetField(m_selection_index); + next_field->FieldDelegateSelectFirstElement(); + } + + return eKeyHandled; + } + + void SkipPreviousHiddenFields() { + while (true) { + if (m_delegate_sp->GetField(m_selection_index)->FieldDelegateIsVisible()) + return; + + if (m_selection_index == 0) { + m_selection_type = SelectionType::Action; + m_selection_index = 0; + return; + } + + m_selection_index--; + } + } + + HandleCharResult SelectPrevious(int key) { + if (m_selection_type == SelectionType::Action) { + if (m_selection_index > 0) { + m_selection_index--; + return eKeyHandled; + } + m_selection_index = m_delegate_sp->GetNumberOfFields() - 1; + m_selection_type = SelectionType::Field; + SkipPreviousHiddenFields(); + if (m_selection_type == SelectionType::Field) { + FieldDelegate *previous_field = + m_delegate_sp->GetField(m_selection_index); + previous_field->FieldDelegateSelectLastElement(); + } + return eKeyHandled; + } + + FieldDelegate *field = m_delegate_sp->GetField(m_selection_index); + if (!field->FieldDelegateOnFirstOrOnlyElement()) { + return field->FieldDelegateHandleChar(key); + } + + field->FieldDelegateExitCallback(); + + if (m_selection_index == 0) { + m_selection_type = SelectionType::Action; + m_selection_index = m_delegate_sp->GetNumberOfActions() - 1; + return eKeyHandled; + } + + m_selection_index--; + SkipPreviousHiddenFields(); + + if (m_selection_type == SelectionType::Field) { + FieldDelegate *previous_field = + m_delegate_sp->GetField(m_selection_index); + previous_field->FieldDelegateSelectLastElement(); + } + + return eKeyHandled; + } + + void ExecuteAction(Window &window) { + FormAction &action = m_delegate_sp->GetAction(m_selection_index); + action.Execute(window); + if (m_delegate_sp->HasError()) { + m_first_visible_line = 0; + m_selection_index = 0; + m_selection_type = SelectionType::Field; + } + } + + HandleCharResult WindowDelegateHandleChar(Window &window, int key) override { + switch (key) { + case '\r': + case '\n': + case KEY_ENTER: + if (m_selection_type == SelectionType::Action) { + ExecuteAction(window); + return eKeyHandled; + } + break; + case '\t': + return SelectNext(key); + case KEY_SHIFT_TAB: + return SelectPrevious(key); + case KEY_ESCAPE: + window.GetParent()->RemoveSubWindow(&window); + return eKeyHandled; + default: + break; + } + + // If the key wasn't handled and one of the fields is selected, pass the key + // to that field. + if (m_selection_type == SelectionType::Field) { + FieldDelegate *field = m_delegate_sp->GetField(m_selection_index); + return field->FieldDelegateHandleChar(key); + } + + return eKeyNotHandled; + } + +protected: + FormDelegateSP m_delegate_sp; + // The index of the currently selected SelectionType. + int m_selection_index; + // See SelectionType class enum. + SelectionType m_selection_type; + // The first visible line from the pad. + int m_first_visible_line; +}; + +/////////////////////////// +// Form Delegate Instances +/////////////////////////// + +class DetachOrKillProcessFormDelegate : public FormDelegate { +public: + DetachOrKillProcessFormDelegate(Process *process) : m_process(process) { + SetError("There is a running process, either detach or kill it."); + + m_keep_stopped_field = + AddBooleanField("Keep process stopped when detaching.", false); + + AddAction("Detach", [this](Window &window) { Detach(window); }); + AddAction("Kill", [this](Window &window) { Kill(window); }); + } + + std::string GetName() override { return "Detach/Kill Process"; } + + void Kill(Window &window) { + Status destroy_status(m_process->Destroy(false)); + if (destroy_status.Fail()) { + SetError("Failed to kill process."); + return; + } + window.GetParent()->RemoveSubWindow(&window); + } + + void Detach(Window &window) { + Status detach_status(m_process->Detach(m_keep_stopped_field->GetBoolean())); + if (detach_status.Fail()) { + SetError("Failed to detach from process."); + return; + } + window.GetParent()->RemoveSubWindow(&window); + } + +protected: + Process *m_process; + BooleanFieldDelegate *m_keep_stopped_field; +}; + +class ProcessAttachFormDelegate : public FormDelegate { +public: + ProcessAttachFormDelegate(Debugger &debugger, WindowSP main_window_sp) + : m_debugger(debugger), m_main_window_sp(main_window_sp) { + std::vector<std::string> types; + types.push_back(std::string("Name")); + types.push_back(std::string("PID")); + m_type_field = AddChoicesField("Attach By", 2, types); + m_pid_field = AddIntegerField("PID", 0, true); + m_name_field = + AddTextField("Process Name", GetDefaultProcessName().c_str(), true); + m_continue_field = AddBooleanField("Continue once attached.", false); + m_wait_for_field = AddBooleanField("Wait for process to launch.", false); + m_include_existing_field = + AddBooleanField("Include existing processes.", false); + m_show_advanced_field = AddBooleanField("Show advanced settings.", false); + m_plugin_field = AddProcessPluginField(); + + AddAction("Attach", [this](Window &window) { Attach(window); }); + } + + std::string GetName() override { return "Attach Process"; } + + void UpdateFieldsVisibility() override { + if (m_type_field->GetChoiceContent() == "Name") { + m_pid_field->FieldDelegateHide(); + m_name_field->FieldDelegateShow(); + m_wait_for_field->FieldDelegateShow(); + if (m_wait_for_field->GetBoolean()) + m_include_existing_field->FieldDelegateShow(); + else + m_include_existing_field->FieldDelegateHide(); + } else { + m_pid_field->FieldDelegateShow(); + m_name_field->FieldDelegateHide(); + m_wait_for_field->FieldDelegateHide(); + m_include_existing_field->FieldDelegateHide(); + } + if (m_show_advanced_field->GetBoolean()) + m_plugin_field->FieldDelegateShow(); + else + m_plugin_field->FieldDelegateHide(); + } + + // Get the basename of the target's main executable if available, empty string + // otherwise. + std::string GetDefaultProcessName() { + Target *target = m_debugger.GetSelectedTarget().get(); + if (target == nullptr) + return ""; + + ModuleSP module_sp = target->GetExecutableModule(); + if (!module_sp->IsExecutable()) + return ""; + + return module_sp->GetFileSpec().GetFilename().AsCString(); + } + + bool StopRunningProcess() { + ExecutionContext exe_ctx = + m_debugger.GetCommandInterpreter().GetExecutionContext(); + + if (!exe_ctx.HasProcessScope()) + return false; + + Process *process = exe_ctx.GetProcessPtr(); + if (!(process && process->IsAlive())) + return false; + + FormDelegateSP form_delegate_sp = + FormDelegateSP(new DetachOrKillProcessFormDelegate(process)); + Rect bounds = m_main_window_sp->GetCenteredRect(85, 8); + WindowSP form_window_sp = m_main_window_sp->CreateSubWindow( + form_delegate_sp->GetName().c_str(), bounds, true); + WindowDelegateSP window_delegate_sp = + WindowDelegateSP(new FormWindowDelegate(form_delegate_sp)); + form_window_sp->SetDelegate(window_delegate_sp); + + return true; + } + + Target *GetTarget() { + Target *target = m_debugger.GetSelectedTarget().get(); + + if (target != nullptr) + return target; + + TargetSP new_target_sp; + m_debugger.GetTargetList().CreateTarget( + m_debugger, "", "", eLoadDependentsNo, nullptr, new_target_sp); + + target = new_target_sp.get(); + + if (target == nullptr) + SetError("Failed to create target."); + + m_debugger.GetTargetList().SetSelectedTarget(new_target_sp); + + return target; + } + + ProcessAttachInfo GetAttachInfo() { + ProcessAttachInfo attach_info; + attach_info.SetContinueOnceAttached(m_continue_field->GetBoolean()); + if (m_type_field->GetChoiceContent() == "Name") { + attach_info.GetExecutableFile().SetFile(m_name_field->GetText(), + FileSpec::Style::native); + attach_info.SetWaitForLaunch(m_wait_for_field->GetBoolean()); + if (m_wait_for_field->GetBoolean()) + attach_info.SetIgnoreExisting(!m_include_existing_field->GetBoolean()); + } else { + attach_info.SetProcessID(m_pid_field->GetInteger()); + } + attach_info.SetProcessPluginName(m_plugin_field->GetPluginName()); + + return attach_info; + } + + void Attach(Window &window) { + ClearError(); + + bool all_fields_are_valid = CheckFieldsValidity(); + if (!all_fields_are_valid) + return; + + bool process_is_running = StopRunningProcess(); + if (process_is_running) + return; + + Target *target = GetTarget(); + if (HasError()) + return; + + StreamString stream; + ProcessAttachInfo attach_info = GetAttachInfo(); + Status status = target->Attach(attach_info, &stream); + + if (status.Fail()) { + SetError(status.AsCString()); + return; + } + + ProcessSP process_sp(target->GetProcessSP()); + if (!process_sp) { + SetError("Attached sucessfully but target has no process."); + return; + } + + if (attach_info.GetContinueOnceAttached()) + process_sp->Resume(); + + window.GetParent()->RemoveSubWindow(&window); + } + +protected: + Debugger &m_debugger; + WindowSP m_main_window_sp; + + ChoicesFieldDelegate *m_type_field; + IntegerFieldDelegate *m_pid_field; + TextFieldDelegate *m_name_field; + BooleanFieldDelegate *m_continue_field; + BooleanFieldDelegate *m_wait_for_field; + BooleanFieldDelegate *m_include_existing_field; + BooleanFieldDelegate *m_show_advanced_field; + ProcessPluginFieldDelegate *m_plugin_field; +}; + class MenuDelegate { public: virtual ~MenuDelegate() = default; @@ -1282,8 +3065,6 @@ public: } void Initialize() { - ::setlocale(LC_ALL, ""); - ::setlocale(LC_CTYPE, ""); m_screen = ::newterm(nullptr, m_out, m_in); ::start_color(); ::curs_set(0); @@ -1390,8 +3171,6 @@ public: ConstString broadcaster_class( broadcaster->GetBroadcasterClass()); if (broadcaster_class == broadcaster_class_process) { - debugger.GetCommandInterpreter().UpdateExecutionContext( - nullptr); m_update_screen = true; continue; // Don't get any key, just update our view } @@ -1403,7 +3182,6 @@ public: HandleCharResult key_result = m_window_sp->HandleChar(ch); switch (key_result) { case eKeyHandled: - debugger.GetCommandInterpreter().UpdateExecutionContext(nullptr); m_update_screen = true; break; case eKeyNotHandled: @@ -1494,7 +3272,7 @@ protected: using namespace curses; struct Row { - ValueObjectManager value; + ValueObjectUpdater value; Row *parent; // The process stop ID when the children were calculated. uint32_t children_stop_id = 0; @@ -1507,7 +3285,7 @@ struct Row { std::vector<Row> children; Row(const ValueObjectSP &v, Row *p) - : value(v, lldb::eDynamicDontRunTarget, true), parent(p), + : value(v), parent(p), might_have_children(v ? v->MightHaveChildren() : false) {} size_t GetDepth() const { @@ -1610,8 +3388,13 @@ public: virtual void TreeDelegateDrawTreeItem(TreeItem &item, Window &window) = 0; virtual void TreeDelegateGenerateChildren(TreeItem &item) = 0; + virtual void TreeDelegateUpdateSelection(TreeItem &root, int &selection_index, + TreeItem *&selected_item) { + return; + } virtual bool TreeDelegateItemSelected( TreeItem &item) = 0; // Return true if we need to update views + virtual bool TreeDelegateExpandRootByDefault() { return false; } }; typedef std::shared_ptr<TreeDelegate> TreeDelegateSP; @@ -1621,7 +3404,10 @@ public: TreeItem(TreeItem *parent, TreeDelegate &delegate, bool might_have_children) : m_parent(parent), m_delegate(delegate), m_user_data(nullptr), m_identifier(0), m_row_idx(-1), m_children(), - m_might_have_children(might_have_children), m_is_expanded(false) {} + m_might_have_children(might_have_children), m_is_expanded(false) { + if (m_parent == nullptr) + m_is_expanded = m_delegate.TreeDelegateExpandRootByDefault(); + } TreeItem &operator=(const TreeItem &rhs) { if (this != &rhs) { @@ -1850,6 +3636,8 @@ public: const int num_visible_rows = NumVisibleRows(); m_num_rows = 0; m_root.CalculateRowIndexes(m_num_rows); + m_delegate_sp->TreeDelegateUpdateSelection(m_root, m_selected_row_idx, + m_selected_item); // If we unexpanded while having something selected our total number of // rows is less than the num visible rows, then make sure we show all the @@ -2151,7 +3939,7 @@ class ThreadsTreeDelegate : public TreeDelegate { public: ThreadsTreeDelegate(Debugger &debugger) : TreeDelegate(), m_thread_delegate_sp(), m_debugger(debugger), - m_stop_id(UINT32_MAX) { + m_stop_id(UINT32_MAX), m_update_selection(false) { FormatEntity::Parse("process ${process.id}{, name = ${process.name}}", m_format); } @@ -2179,6 +3967,7 @@ public: void TreeDelegateGenerateChildren(TreeItem &item) override { ProcessSP process_sp = GetProcess(); + m_update_selection = false; if (process_sp && process_sp->IsAlive()) { StateType state = process_sp->GetState(); if (StateIsStoppedState(state, true)) { @@ -2187,6 +3976,7 @@ public: return; // Children are already up to date m_stop_id = stop_id; + m_update_selection = true; if (!m_thread_delegate_sp) { // Always expand the thread item the first time we show it @@ -2198,11 +3988,15 @@ public: TreeItem t(&item, *m_thread_delegate_sp, false); ThreadList &threads = process_sp->GetThreadList(); std::lock_guard<std::recursive_mutex> guard(threads.GetMutex()); + ThreadSP selected_thread = threads.GetSelectedThread(); size_t num_threads = threads.GetSize(); item.Resize(num_threads, t); for (size_t i = 0; i < num_threads; ++i) { - item[i].SetIdentifier(threads.GetThreadAtIndex(i)->GetID()); + ThreadSP thread = threads.GetThreadAtIndex(i); + item[i].SetIdentifier(thread->GetID()); item[i].SetMightHaveChildren(true); + if (selected_thread->GetID() == thread->GetID()) + item[i].Expand(); } return; } @@ -2210,20 +4004,48 @@ public: item.ClearChildren(); } + void TreeDelegateUpdateSelection(TreeItem &root, int &selection_index, + TreeItem *&selected_item) override { + if (!m_update_selection) + return; + + ProcessSP process_sp = GetProcess(); + if (!(process_sp && process_sp->IsAlive())) + return; + + StateType state = process_sp->GetState(); + if (!StateIsStoppedState(state, true)) + return; + + ThreadList &threads = process_sp->GetThreadList(); + std::lock_guard<std::recursive_mutex> guard(threads.GetMutex()); + ThreadSP selected_thread = threads.GetSelectedThread(); + size_t num_threads = threads.GetSize(); + for (size_t i = 0; i < num_threads; ++i) { + ThreadSP thread = threads.GetThreadAtIndex(i); + if (selected_thread->GetID() == thread->GetID()) { + selected_item = &root[i][thread->GetSelectedFrameIndex()]; + selection_index = selected_item->GetRowIndex(); + return; + } + } + } + bool TreeDelegateItemSelected(TreeItem &item) override { return false; } + bool TreeDelegateExpandRootByDefault() override { return true; } + protected: std::shared_ptr<ThreadTreeDelegate> m_thread_delegate_sp; Debugger &m_debugger; uint32_t m_stop_id; + bool m_update_selection; FormatEntity::Entry m_format; }; class ValueObjectListDelegate : public WindowDelegate { public: - ValueObjectListDelegate() - : m_rows(), m_selected_row(nullptr), m_selected_row_idx(0), - m_first_visible_row(0), m_num_rows(0), m_max_x(0), m_max_y(0) {} + ValueObjectListDelegate() : m_rows() {} ValueObjectListDelegate(ValueObjectList &valobj_list) : m_rows(), m_selected_row(nullptr), m_selected_row_idx(0), @@ -2411,14 +4233,14 @@ public: protected: std::vector<Row> m_rows; - Row *m_selected_row; - uint32_t m_selected_row_idx; - uint32_t m_first_visible_row; - uint32_t m_num_rows; + Row *m_selected_row = nullptr; + uint32_t m_selected_row_idx = 0; + uint32_t m_first_visible_row = 0; + uint32_t m_num_rows = 0; int m_min_x; int m_min_y; - int m_max_x; - int m_max_y; + int m_max_x = 0; + int m_max_y = 0; static Format FormatForChar(int c) { switch (c) { @@ -3042,7 +4864,7 @@ public: window.SelectNextWindowAsActive(); return eKeyHandled; - case KEY_BTAB: + case KEY_SHIFT_TAB: window.SelectPreviousWindowAsActive(); return eKeyHandled; @@ -3122,6 +4944,19 @@ public: } return MenuActionResult::Handled; + case eMenuID_ProcessAttach: { + WindowSP main_window_sp = m_app.GetMainWindow(); + FormDelegateSP form_delegate_sp = FormDelegateSP( + new ProcessAttachFormDelegate(m_debugger, main_window_sp)); + Rect bounds = main_window_sp->GetCenteredRect(80, 22); + WindowSP form_window_sp = main_window_sp->CreateSubWindow( + form_delegate_sp->GetName().c_str(), bounds, true); + WindowDelegateSP window_delegate_sp = + WindowDelegateSP(new FormWindowDelegate(form_delegate_sp)); + form_window_sp->SetDelegate(window_delegate_sp); + return MenuActionResult::Handled; + } + case eMenuID_ProcessContinue: { ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext(); @@ -3394,10 +5229,10 @@ public: SourceFileWindowDelegate(Debugger &debugger) : WindowDelegate(), m_debugger(debugger), m_sc(), m_file_sp(), m_disassembly_scope(nullptr), m_disassembly_sp(), m_disassembly_range(), - m_title(), m_line_width(4), m_selected_line(0), m_pc_line(0), - m_stop_id(0), m_frame_idx(UINT32_MAX), m_first_visible_line(0), - m_first_visible_column(0), m_min_x(0), m_min_y(0), m_max_x(0), - m_max_y(0) {} + m_title(), m_tid(LLDB_INVALID_THREAD_ID), m_line_width(4), + m_selected_line(0), m_pc_line(0), m_stop_id(0), m_frame_idx(UINT32_MAX), + m_first_visible_line(0), m_first_visible_column(0), m_min_x(0), + m_min_y(0), m_max_x(0), m_max_y(0) {} ~SourceFileWindowDelegate() override = default; @@ -3552,7 +5387,7 @@ public: if (m_disassembly_scope != m_sc.function) { m_disassembly_scope = m_sc.function; m_disassembly_sp = m_sc.function->GetInstructions( - exe_ctx, nullptr, prefer_file_cache); + exe_ctx, nullptr, !prefer_file_cache); if (m_disassembly_sp) { set_selected_line_to_pc = true; m_disassembly_range = m_sc.function->GetAddressRange(); @@ -3956,7 +5791,7 @@ public: false, // request_hardware eLazyBoolCalculate); // move_to_nearest_code // Make breakpoint one shot - bp_sp->GetOptions()->SetOneShot(true); + bp_sp->GetOptions().SetOneShot(true); exe_ctx.GetProcessRef().Resume(); } } else if (m_selected_line < GetNumDisassemblyLines()) { @@ -3972,7 +5807,7 @@ public: false, // internal false); // request_hardware // Make breakpoint one shot - bp_sp->GetOptions()->SetOneShot(true); + bp_sp->GetOptions().SetOneShot(true); exe_ctx.GetProcessRef().Resume(); } } @@ -4339,6 +6174,8 @@ void IOHandlerCursesGUI::Activate() { init_pair(17, COLOR_BLACK, COLOR_WHITE); init_pair(18, COLOR_MAGENTA, COLOR_WHITE); static_assert(LastColorPairIndex == 18, "Color indexes do not match."); + + define_key("\033[Z", KEY_SHIFT_TAB); } } diff --git a/contrib/llvm-project/lldb/source/Core/Mangled.cpp b/contrib/llvm-project/lldb/source/Core/Mangled.cpp index 627be94a303c..fbaf9ff7151a 100644 --- a/contrib/llvm-project/lldb/source/Core/Mangled.cpp +++ b/contrib/llvm-project/lldb/source/Core/Mangled.cpp @@ -17,7 +17,6 @@ #include "lldb/lldb-enumerations.h" #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" -#include "Plugins/Language/ObjC/ObjCLanguage.h" #include "llvm/ADT/StringRef.h" #include "llvm/Demangle/Demangle.h" @@ -27,34 +26,16 @@ #include <string> #include <utility> -#include <stdlib.h> -#include <string.h> +#include <cstdlib> +#include <cstring> using namespace lldb_private; static inline bool cstring_is_mangled(llvm::StringRef s) { return Mangled::GetManglingScheme(s) != Mangled::eManglingSchemeNone; } -static ConstString -get_demangled_name_without_arguments(ConstString mangled, - ConstString demangled) { - // This pair is <mangled name, demangled name without function arguments> - static std::pair<ConstString, ConstString> - g_most_recent_mangled_to_name_sans_args; - - // Need to have the mangled & demangled names we're currently examining as - // statics so we can return a const ref to them at the end of the func if we - // don't have anything better. - static ConstString g_last_mangled; - static ConstString g_last_demangled; - - if (mangled && g_most_recent_mangled_to_name_sans_args.first == mangled) { - return g_most_recent_mangled_to_name_sans_args.second; - } - - g_last_demangled = demangled; - g_last_mangled = mangled; - +static ConstString GetDemangledNameWithoutArguments(ConstString mangled, + ConstString demangled) { const char *mangled_name_cstr = mangled.GetCString(); if (demangled && mangled_name_cstr && mangled_name_cstr[0]) { @@ -73,17 +54,13 @@ get_demangled_name_without_arguments(ConstString mangled, if (!cxx_method.GetContext().empty()) shortname = cxx_method.GetContext().str() + "::"; shortname += cxx_method.GetBasename().str(); - ConstString result(shortname.c_str()); - g_most_recent_mangled_to_name_sans_args.first = mangled; - g_most_recent_mangled_to_name_sans_args.second = result; - return g_most_recent_mangled_to_name_sans_args.second; + return ConstString(shortname); } } } - if (demangled) - return g_last_demangled; - return g_last_mangled; + return demangled; + return mangled; } #pragma mark Mangled @@ -95,6 +72,9 @@ Mangled::ManglingScheme Mangled::GetManglingScheme(llvm::StringRef const name) { if (name.startswith("?")) return Mangled::eManglingSchemeMSVC; + if (name.startswith("_R")) + return Mangled::eManglingSchemeRustV0; + if (name.startswith("_Z")) return Mangled::eManglingSchemeItanium; @@ -222,6 +202,19 @@ static char *GetItaniumDemangledStr(const char *M) { return demangled_cstr; } +static char *GetRustV0DemangledStr(const char *M) { + char *demangled_cstr = llvm::rustDemangle(M, nullptr, nullptr, nullptr); + + if (Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE)) { + if (demangled_cstr && demangled_cstr[0]) + LLDB_LOG(log, "demangled rustv0: {0} -> \"{1}\"", M, demangled_cstr); + else + LLDB_LOG(log, "demangled rustv0: {0} -> error: failed to demangle", M); + } + + return demangled_cstr; +} + // Explicit demangling for scheduled requests during batch processing. This // makes use of ItaniumPartialDemangler's rich demangle info bool Mangled::DemangleWithRichManglingInfo( @@ -279,6 +272,10 @@ bool Mangled::DemangleWithRichManglingInfo( return context.FromCxxMethodName(m_demangled); } } + + case eManglingSchemeRustV0: + // Rich demangling scheme is not supported for Rust + return false; } llvm_unreachable("Fully covered switch above!"); } @@ -307,6 +304,9 @@ ConstString Mangled::GetDemangledName() const { demangled_name = GetItaniumDemangledStr(mangled_name); break; } + case eManglingSchemeRustV0: + demangled_name = GetRustV0DemangledStr(mangled_name); + break; case eManglingSchemeNone: llvm_unreachable("eManglingSchemeNone was handled already"); } @@ -347,7 +347,7 @@ ConstString Mangled::GetName(Mangled::NamePreference preference) const { ConstString demangled = GetDemangledName(); if (preference == ePreferDemangledWithoutArguments) { - return get_demangled_name_without_arguments(m_mangled, demangled); + return GetDemangledNameWithoutArguments(m_mangled, demangled); } if (preference == ePreferDemangled) { // Call the accessor to make sure we get a demangled name in case it hasn't @@ -395,22 +395,16 @@ size_t Mangled::MemorySize() const { // of mangling names from a given language, likewise the compilation units // within those targets. lldb::LanguageType Mangled::GuessLanguage() const { - ConstString mangled = GetMangledName(); - - if (mangled) { - const char *mangled_name = mangled.GetCString(); - if (CPlusPlusLanguage::IsCPPMangledName(mangled_name)) - return lldb::eLanguageTypeC_plus_plus; - } else { - // ObjC names aren't really mangled, so they won't necessarily be in the - // mangled name slot. - ConstString demangled_name = GetDemangledName(); - if (demangled_name - && ObjCLanguage::IsPossibleObjCMethodName(demangled_name.GetCString())) - return lldb::eLanguageTypeObjC; - - } - return lldb::eLanguageTypeUnknown; + lldb::LanguageType result = lldb::eLanguageTypeUnknown; + // Ask each language plugin to check if the mangled name belongs to it. + Language::ForEach([this, &result](Language *l) { + if (l->SymbolNameFitsToLanguage(*this)) { + result = l->GetLanguageType(); + return false; + } + return true; + }); + return result; } // Dump OBJ to the supplied stream S. diff --git a/contrib/llvm-project/lldb/source/Core/Module.cpp b/contrib/llvm-project/lldb/source/Core/Module.cpp index 1f9987c21658..19c97be15066 100644 --- a/contrib/llvm-project/lldb/source/Core/Module.cpp +++ b/contrib/llvm-project/lldb/source/Core/Module.cpp @@ -59,12 +59,12 @@ #include "llvm/Support/Signals.h" #include "llvm/Support/raw_ostream.h" -#include <assert.h> +#include <cassert> +#include <cinttypes> +#include <cstdarg> #include <cstdint> -#include <inttypes.h> +#include <cstring> #include <map> -#include <stdarg.h> -#include <string.h> #include <type_traits> #include <utility> @@ -257,9 +257,7 @@ Module::Module(const FileSpec &file_spec, const ArchSpec &arch, m_object_name.IsEmpty() ? "" : ")"); } -Module::Module() - : m_object_offset(0), m_file_has_changed(false), - m_first_file_changed_log(false) { +Module::Module() : m_file_has_changed(false), m_first_file_changed_log(false) { std::lock_guard<std::recursive_mutex> guard( GetAllocationModuleCollectionMutex()); GetModuleCollection().push_back(this); @@ -440,8 +438,6 @@ CompUnitSP Module::GetCompileUnitAtIndex(size_t index) { bool Module::ResolveFileAddress(lldb::addr_t vm_addr, Address &so_addr) { std::lock_guard<std::recursive_mutex> guard(m_mutex); - LLDB_SCOPED_TIMERF("Module::ResolveFileAddress (vm_addr = 0x%" PRIx64 ")", - vm_addr); SectionList *section_list = GetSectionList(); if (section_list) return so_addr.ResolveAddressUsingFileSections(vm_addr, section_list); @@ -598,9 +594,13 @@ uint32_t Module::ResolveSymbolContextsForFileSpec( const uint32_t initial_count = sc_list.GetSize(); - if (SymbolFile *symbols = GetSymbolFile()) - symbols->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, - sc_list); + if (SymbolFile *symbols = GetSymbolFile()) { + // TODO: Handle SourceLocationSpec column information + SourceLocationSpec location_spec(file_spec, line, /*column=*/llvm::None, + check_inlines, /*exact_match=*/false); + + symbols->ResolveSymbolContext(location_spec, resolve_scope, sc_list); + } return sc_list.GetSize() - initial_count; } @@ -917,7 +917,12 @@ void Module::FindAddressesForLine(const lldb::TargetSP target_sp, std::vector<Address> &output_local, std::vector<Address> &output_extern) { SearchFilterByModule filter(target_sp, m_file); - AddressResolverFileLine resolver(file, line, true); + + // TODO: Handle SourceLocationSpec column information + SourceLocationSpec location_spec(file, line, /*column=*/llvm::None, + /*check_inlines=*/true, + /*exact_match=*/false); + AddressResolverFileLine resolver(location_spec); resolver.ResolveAddress(filter); for (size_t n = 0; n < resolver.GetNumberOfAddresses(); n++) { @@ -1072,8 +1077,6 @@ std::string Module::GetSpecificationDescription() const { void Module::GetDescription(llvm::raw_ostream &s, lldb::DescriptionLevel level) { - std::lock_guard<std::recursive_mutex> guard(m_mutex); - if (level >= eDescriptionLevelFull) { if (m_arch.IsValid()) s << llvm::formatv("({0}) ", m_arch.GetArchitectureName()); @@ -1525,9 +1528,9 @@ bool Module::LoadScriptingResourceInTarget(Target *target, Status &error, } StreamString scripting_stream; scripting_fspec.Dump(scripting_stream.AsRawOstream()); - const bool init_lldb_globals = false; + LoadScriptOptions options; bool did_load = script_interpreter->LoadScriptingModule( - scripting_stream.GetData(), init_lldb_globals, error); + scripting_stream.GetData(), options, error); if (!did_load) return false; } @@ -1595,13 +1598,18 @@ bool Module::MatchesModuleSpec(const ModuleSpec &module_ref) { bool Module::FindSourceFile(const FileSpec &orig_spec, FileSpec &new_spec) const { std::lock_guard<std::recursive_mutex> guard(m_mutex); - return m_source_mappings.FindFile(orig_spec, new_spec); + if (auto remapped = m_source_mappings.FindFile(orig_spec)) { + new_spec = *remapped; + return true; + } + return false; } -bool Module::RemapSourceFile(llvm::StringRef path, - std::string &new_path) const { +llvm::Optional<std::string> Module::RemapSourceFile(llvm::StringRef path) const { std::lock_guard<std::recursive_mutex> guard(m_mutex); - return m_source_mappings.RemapPath(path, new_path); + if (auto remapped = m_source_mappings.RemapPath(path)) + return remapped->GetPath(); + return {}; } void Module::RegisterXcodeSDK(llvm::StringRef sdk_name, llvm::StringRef sysroot) { diff --git a/contrib/llvm-project/lldb/source/Core/ModuleChild.cpp b/contrib/llvm-project/lldb/source/Core/ModuleChild.cpp index 6e04bb4589e3..7aaa8f2ac250 100644 --- a/contrib/llvm-project/lldb/source/Core/ModuleChild.cpp +++ b/contrib/llvm-project/lldb/source/Core/ModuleChild.cpp @@ -13,7 +13,7 @@ using namespace lldb_private; ModuleChild::ModuleChild(const lldb::ModuleSP &module_sp) : m_module_wp(module_sp) {} -ModuleChild::~ModuleChild() {} +ModuleChild::~ModuleChild() = default; const ModuleChild &ModuleChild::operator=(const ModuleChild &rhs) { if (this != &rhs) diff --git a/contrib/llvm-project/lldb/source/Core/ModuleList.cpp b/contrib/llvm-project/lldb/source/Core/ModuleList.cpp index 98f6ae2c62b0..56bc4c72d8e9 100644 --- a/contrib/llvm-project/lldb/source/Core/ModuleList.cpp +++ b/contrib/llvm-project/lldb/source/Core/ModuleList.cpp @@ -132,8 +132,7 @@ PathMappingList ModuleListProperties::GetSymlinkMappings() const { return m_symlink_paths; } -ModuleList::ModuleList() - : m_modules(), m_modules_mutex(), m_notifier(nullptr) {} +ModuleList::ModuleList() : m_modules(), m_modules_mutex() {} ModuleList::ModuleList(const ModuleList &rhs) : m_modules(), m_modules_mutex(), m_notifier(nullptr) { diff --git a/contrib/llvm-project/lldb/source/Core/Opcode.cpp b/contrib/llvm-project/lldb/source/Core/Opcode.cpp index b544064b061e..a3fc97f95266 100644 --- a/contrib/llvm-project/lldb/source/Core/Opcode.cpp +++ b/contrib/llvm-project/lldb/source/Core/Opcode.cpp @@ -16,7 +16,7 @@ #include <memory> -#include <inttypes.h> +#include <cinttypes> using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm-project/lldb/source/Core/PluginManager.cpp b/contrib/llvm-project/lldb/source/Core/PluginManager.cpp index 97e1e8d14039..fcaa868b083e 100644 --- a/contrib/llvm-project/lldb/source/Core/PluginManager.cpp +++ b/contrib/llvm-project/lldb/source/Core/PluginManager.cpp @@ -20,7 +20,7 @@ #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/raw_ostream.h" -#include <assert.h> +#include <cassert> #include <map> #include <memory> #include <mutex> @@ -38,11 +38,11 @@ typedef bool (*PluginInitCallback)(); typedef void (*PluginTermCallback)(); struct PluginInfo { - PluginInfo() : plugin_init_callback(nullptr), plugin_term_callback(nullptr) {} + PluginInfo() = default; llvm::sys::DynamicLibrary library; - PluginInitCallback plugin_init_callback; - PluginTermCallback plugin_term_callback; + PluginInitCallback plugin_init_callback = nullptr; + PluginTermCallback plugin_term_callback = nullptr; }; typedef std::map<FileSpec, PluginInfo> PluginTerminateMap; @@ -684,11 +684,13 @@ PluginManager::GetObjectFileCreateMemoryCallbackForPluginName( } Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp, - const FileSpec &outfile) { + const FileSpec &outfile, + lldb::SaveCoreStyle &core_style) { Status error; auto &instances = GetObjectFileInstances().GetInstances(); for (auto &instance : instances) { - if (instance.save_core && instance.save_core(process_sp, outfile, error)) + if (instance.save_core && + instance.save_core(process_sp, outfile, core_style, error)) return error; } error.SetErrorString( @@ -1008,16 +1010,20 @@ PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) { #pragma mark Trace -struct TraceInstance : public PluginInstance<TraceCreateInstance> { - TraceInstance(ConstString name, std::string description, - CallbackType create_callback, llvm::StringRef schema, - TraceGetStartCommand get_start_command) - : PluginInstance<TraceCreateInstance>(name, std::move(description), - create_callback), - schema(schema), get_start_command(get_start_command) {} +struct TraceInstance + : public PluginInstance<TraceCreateInstanceForSessionFile> { + TraceInstance( + ConstString name, std::string description, + CallbackType create_callback_for_session_file, + TraceCreateInstanceForLiveProcess create_callback_for_live_process, + llvm::StringRef schema) + : PluginInstance<TraceCreateInstanceForSessionFile>( + name, std::move(description), create_callback_for_session_file), + schema(schema), + create_callback_for_live_process(create_callback_for_live_process) {} llvm::StringRef schema; - TraceGetStartCommand get_start_command; + TraceCreateInstanceForLiveProcess create_callback_for_live_process; }; typedef PluginInstances<TraceInstance> TraceInstances; @@ -1027,37 +1033,40 @@ static TraceInstances &GetTracePluginInstances() { return g_instances; } -bool PluginManager::RegisterPlugin(ConstString name, const char *description, - TraceCreateInstance create_callback, - llvm::StringRef schema, - TraceGetStartCommand get_start_command) { +bool PluginManager::RegisterPlugin( + ConstString name, const char *description, + TraceCreateInstanceForSessionFile create_callback_for_session_file, + TraceCreateInstanceForLiveProcess create_callback_for_live_process, + llvm::StringRef schema) { return GetTracePluginInstances().RegisterPlugin( - name, description, create_callback, schema, get_start_command); + name, description, create_callback_for_session_file, + create_callback_for_live_process, schema); } -bool PluginManager::UnregisterPlugin(TraceCreateInstance create_callback) { - return GetTracePluginInstances().UnregisterPlugin(create_callback); +bool PluginManager::UnregisterPlugin( + TraceCreateInstanceForSessionFile create_callback_for_session_file) { + return GetTracePluginInstances().UnregisterPlugin( + create_callback_for_session_file); } -TraceCreateInstance +TraceCreateInstanceForSessionFile PluginManager::GetTraceCreateCallback(ConstString plugin_name) { return GetTracePluginInstances().GetCallbackForName(plugin_name); } -llvm::StringRef PluginManager::GetTraceSchema(ConstString plugin_name) { +TraceCreateInstanceForLiveProcess +PluginManager::GetTraceCreateCallbackForLiveProcess(ConstString plugin_name) { for (const TraceInstance &instance : GetTracePluginInstances().GetInstances()) if (instance.name == plugin_name) - return instance.schema; - return llvm::StringRef(); + return instance.create_callback_for_live_process; + return nullptr; } -CommandObjectSP -PluginManager::GetTraceStartCommand(llvm::StringRef plugin_name, - CommandInterpreter &interpreter) { +llvm::StringRef PluginManager::GetTraceSchema(ConstString plugin_name) { for (const TraceInstance &instance : GetTracePluginInstances().GetInstances()) - if (instance.name.GetStringRef() == plugin_name) - return instance.get_start_command(interpreter); - return CommandObjectSP(); + if (instance.name == plugin_name) + return instance.schema; + return llvm::StringRef(); } llvm::StringRef PluginManager::GetTraceSchema(size_t index) { @@ -1067,6 +1076,59 @@ llvm::StringRef PluginManager::GetTraceSchema(size_t index) { return llvm::StringRef(); } +#pragma mark TraceExporter + +struct TraceExporterInstance + : public PluginInstance<TraceExporterCreateInstance> { + TraceExporterInstance( + ConstString name, std::string description, + TraceExporterCreateInstance create_instance, + ThreadTraceExportCommandCreator create_thread_trace_export_command) + : PluginInstance<TraceExporterCreateInstance>( + name, std::move(description), create_instance), + create_thread_trace_export_command(create_thread_trace_export_command) { + } + + ThreadTraceExportCommandCreator create_thread_trace_export_command; +}; + +typedef PluginInstances<TraceExporterInstance> TraceExporterInstances; + +static TraceExporterInstances &GetTraceExporterInstances() { + static TraceExporterInstances g_instances; + return g_instances; +} + +bool PluginManager::RegisterPlugin( + ConstString name, const char *description, + TraceExporterCreateInstance create_callback, + ThreadTraceExportCommandCreator create_thread_trace_export_command) { + return GetTraceExporterInstances().RegisterPlugin( + name, description, create_callback, create_thread_trace_export_command); +} + +TraceExporterCreateInstance +PluginManager::GetTraceExporterCreateCallback(ConstString plugin_name) { + return GetTraceExporterInstances().GetCallbackForName(plugin_name); +} + +bool PluginManager::UnregisterPlugin( + TraceExporterCreateInstance create_callback) { + return GetTraceExporterInstances().UnregisterPlugin(create_callback); +} + +ThreadTraceExportCommandCreator +PluginManager::GetThreadTraceExportCommandCreatorAtIndex(uint32_t index) { + if (TraceExporterInstance *instance = + GetTraceExporterInstances().GetInstanceAtIndex(index)) + return instance->create_thread_trace_export_command; + return nullptr; +} + +const char *PluginManager::GetTraceExporterPluginNameAtIndex(uint32_t index) { + return GetTraceExporterInstances().GetNameAtIndex(index); +} + #pragma mark UnwindAssembly typedef PluginInstance<UnwindAssemblyCreateInstance> UnwindAssemblyInstance; diff --git a/contrib/llvm-project/lldb/source/Core/Progress.cpp b/contrib/llvm-project/lldb/source/Core/Progress.cpp new file mode 100644 index 000000000000..c54e7774adf3 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Core/Progress.cpp @@ -0,0 +1,60 @@ +//===-- Progress.cpp ------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/Progress.h" + +#include "lldb/Core/Debugger.h" +#include "lldb/Utility/StreamString.h" + +using namespace lldb; +using namespace lldb_private; + +std::atomic<uint64_t> Progress::g_id(0); + +Progress::Progress(std::string title, uint64_t total, + lldb_private::Debugger *debugger) + : m_title(title), m_id(++g_id), m_completed(0), m_total(total) { + assert(total > 0); + if (debugger) + m_debugger_id = debugger->GetID(); + std::lock_guard<std::mutex> guard(m_mutex); + ReportProgress(); +} + +Progress::~Progress() { + // Make sure to always report progress completed when this object is + // destructed so it indicates the progress dialog/activity should go away. + std::lock_guard<std::mutex> guard(m_mutex); + if (!m_completed) { + m_completed = m_total; + ReportProgress(); + } +} + +void Progress::Increment(uint64_t amount) { + if (amount > 0) { + std::lock_guard<std::mutex> guard(m_mutex); + // Watch out for unsigned overflow and make sure we don't increment too + // much and exceed m_total. + if (amount > (m_total - m_completed)) + m_completed = m_total; + else + m_completed += amount; + ReportProgress(); + } +} + +void Progress::ReportProgress() { + if (!m_complete) { + // Make sure we only send one notification that indicates the progress is + // complete. + m_complete = m_completed == m_total; + Debugger::ReportProgress(m_id, m_title, m_completed, m_total, + m_debugger_id); + } +} diff --git a/contrib/llvm-project/lldb/source/Core/RichManglingContext.cpp b/contrib/llvm-project/lldb/source/Core/RichManglingContext.cpp index 2094d96acd7c..2dcb1407e6c7 100644 --- a/contrib/llvm-project/lldb/source/Core/RichManglingContext.cpp +++ b/contrib/llvm-project/lldb/source/Core/RichManglingContext.cpp @@ -19,7 +19,12 @@ using namespace lldb; using namespace lldb_private; // RichManglingContext -void RichManglingContext::ResetProvider(InfoProvider new_provider) { +RichManglingContext::~RichManglingContext() { + std::free(m_ipd_buf); + ResetCxxMethodParser(); +} + +void RichManglingContext::ResetCxxMethodParser() { // If we want to support parsers for other languages some day, we need a // switch here to delete the correct parser type. if (m_cxx_method_parser.hasValue()) { @@ -27,6 +32,10 @@ void RichManglingContext::ResetProvider(InfoProvider new_provider) { delete get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser); m_cxx_method_parser.reset(); } +} + +void RichManglingContext::ResetProvider(InfoProvider new_provider) { + ResetCxxMethodParser(); assert(new_provider != None && "Only reset to a valid provider"); m_provider = new_provider; diff --git a/contrib/llvm-project/lldb/source/Core/SearchFilter.cpp b/contrib/llvm-project/lldb/source/Core/SearchFilter.cpp index e3327ff5e750..4f9519b5cc9a 100644 --- a/contrib/llvm-project/lldb/source/Core/SearchFilter.cpp +++ b/contrib/llvm-project/lldb/source/Core/SearchFilter.cpp @@ -27,8 +27,8 @@ #include <mutex> #include <string> -#include <inttypes.h> -#include <string.h> +#include <cinttypes> +#include <cstring> namespace lldb_private { class Address; diff --git a/contrib/llvm-project/lldb/source/Core/Section.cpp b/contrib/llvm-project/lldb/source/Core/Section.cpp index 9bf1c62c5ab8..a5a10141aa64 100644 --- a/contrib/llvm-project/lldb/source/Core/Section.cpp +++ b/contrib/llvm-project/lldb/source/Core/Section.cpp @@ -15,7 +15,7 @@ #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/VMRange.h" -#include <inttypes.h> +#include <cinttypes> #include <limits> #include <utility> diff --git a/contrib/llvm-project/lldb/source/Core/SourceLocationSpec.cpp b/contrib/llvm-project/lldb/source/Core/SourceLocationSpec.cpp new file mode 100644 index 000000000000..610754bb187c --- /dev/null +++ b/contrib/llvm-project/lldb/source/Core/SourceLocationSpec.cpp @@ -0,0 +1,81 @@ +//===-- SourceLocationSpec.cpp --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/SourceLocationSpec.h" +#include "lldb/Utility/StreamString.h" + +using namespace lldb; +using namespace lldb_private; + +SourceLocationSpec::SourceLocationSpec(FileSpec file_spec, uint32_t line, + llvm::Optional<uint16_t> column, + bool check_inlines, bool exact_match) + : m_declaration(file_spec, line, + column.getValueOr(LLDB_INVALID_COLUMN_NUMBER)), + m_check_inlines(check_inlines), m_exact_match(exact_match) {} + +SourceLocationSpec::operator bool() const { return m_declaration.IsValid(); } + +bool SourceLocationSpec::operator!() const { return !operator bool(); } + +bool SourceLocationSpec::operator==(const SourceLocationSpec &rhs) const { + return m_declaration == rhs.m_declaration && + m_check_inlines == rhs.GetCheckInlines() && + m_exact_match == rhs.GetExactMatch(); +} + +bool SourceLocationSpec::operator!=(const SourceLocationSpec &rhs) const { + return !(*this == rhs); +} + +bool SourceLocationSpec::operator<(const SourceLocationSpec &rhs) const { + return SourceLocationSpec::Compare(*this, rhs) < 0; +} + +Stream &lldb_private::operator<<(Stream &s, const SourceLocationSpec &loc) { + loc.Dump(s); + return s; +} + +int SourceLocationSpec::Compare(const SourceLocationSpec &lhs, + const SourceLocationSpec &rhs) { + return Declaration::Compare(lhs.m_declaration, rhs.m_declaration); +} + +bool SourceLocationSpec::Equal(const SourceLocationSpec &lhs, + const SourceLocationSpec &rhs, bool full) { + return full ? lhs == rhs + : (lhs.GetFileSpec() == rhs.GetFileSpec() && + lhs.GetLine() == rhs.GetLine()); +} + +void SourceLocationSpec::Dump(Stream &s) const { + s << "check inlines = " << llvm::toStringRef(m_check_inlines); + s << ", exact match = " << llvm::toStringRef(m_exact_match); + m_declaration.Dump(&s, true); +} + +std::string SourceLocationSpec::GetString() const { + StreamString ss; + Dump(ss); + return ss.GetString().str(); +} + +llvm::Optional<uint32_t> SourceLocationSpec::GetLine() const { + uint32_t line = m_declaration.GetLine(); + if (line == 0 || line == LLDB_INVALID_LINE_NUMBER) + return llvm::None; + return line; +} + +llvm::Optional<uint16_t> SourceLocationSpec::GetColumn() const { + uint16_t column = m_declaration.GetColumn(); + if (column == LLDB_INVALID_COLUMN_NUMBER) + return llvm::None; + return column; +} diff --git a/contrib/llvm-project/lldb/source/Core/SourceManager.cpp b/contrib/llvm-project/lldb/source/Core/SourceManager.cpp index e79fcb48742d..9c1112979c54 100644 --- a/contrib/llvm-project/lldb/source/Core/SourceManager.cpp +++ b/contrib/llvm-project/lldb/source/Core/SourceManager.cpp @@ -35,8 +35,8 @@ #include <memory> #include <utility> -#include <assert.h> -#include <stdio.h> +#include <cassert> +#include <cstdio> namespace lldb_private { class ExecutionContext; @@ -61,7 +61,7 @@ SourceManager::SourceManager(const DebuggerSP &debugger_sp) m_debugger_wp(debugger_sp) {} // Destructor -SourceManager::~SourceManager() {} +SourceManager::~SourceManager() = default; SourceManager::FileSP SourceManager::GetFile(const FileSpec &file_spec) { if (!file_spec) @@ -441,13 +441,17 @@ void SourceManager::File::CommonInitializer(const FileSpec &file_spec, } // Try remapping if m_file_spec does not correspond to an existing file. if (!FileSystem::Instance().Exists(m_file_spec)) { - FileSpec new_file_spec; - // Check target specific source remappings first, then fall back to - // modules objects can have individual path remappings that were - // detected when the debug info for a module was found. then - if (target->GetSourcePathMap().FindFile(m_file_spec, new_file_spec) || - target->GetImages().FindSourceFile(m_file_spec, new_file_spec)) { - m_file_spec = new_file_spec; + // Check target specific source remappings (i.e., the + // target.source-map setting), then fall back to the module + // specific remapping (i.e., the .dSYM remapping dictionary). + auto remapped = target->GetSourcePathMap().FindFile(m_file_spec); + if (!remapped) { + FileSpec new_spec; + if (target->GetImages().FindSourceFile(m_file_spec, new_spec)) + remapped = new_spec; + } + if (remapped) { + m_file_spec = *remapped; m_mod_time = FileSystem::Instance().GetModificationTime(m_file_spec); } } diff --git a/contrib/llvm-project/lldb/source/Core/StreamFile.cpp b/contrib/llvm-project/lldb/source/Core/StreamFile.cpp index 43a9df802f7e..2f922fe11440 100644 --- a/contrib/llvm-project/lldb/source/Core/StreamFile.cpp +++ b/contrib/llvm-project/lldb/source/Core/StreamFile.cpp @@ -10,7 +10,7 @@ #include "lldb/Host/FileSystem.h" #include "lldb/Utility/Log.h" -#include <stdio.h> +#include <cstdio> using namespace lldb; using namespace lldb_private; @@ -43,7 +43,7 @@ StreamFile::StreamFile(const char *path, File::OpenOptions options, } } -StreamFile::~StreamFile() {} +StreamFile::~StreamFile() = default; void StreamFile::Flush() { m_file_sp->Flush(); } diff --git a/contrib/llvm-project/lldb/source/Core/Value.cpp b/contrib/llvm-project/lldb/source/Core/Value.cpp index cc8f3f4e2615..fb57c0fedf04 100644 --- a/contrib/llvm-project/lldb/source/Core/Value.cpp +++ b/contrib/llvm-project/lldb/source/Core/Value.cpp @@ -33,24 +33,21 @@ #include <memory> #include <string> -#include <inttypes.h> +#include <cinttypes> using namespace lldb; using namespace lldb_private; -Value::Value() - : m_value(), m_compiler_type(), m_context(nullptr), - m_value_type(eValueTypeScalar), m_context_type(eContextTypeInvalid), - m_data_buffer() {} +Value::Value() : m_value(), m_compiler_type(), m_data_buffer() {} Value::Value(const Scalar &scalar) : m_value(scalar), m_compiler_type(), m_context(nullptr), - m_value_type(eValueTypeScalar), m_context_type(eContextTypeInvalid), + m_value_type(ValueType::Scalar), m_context_type(ContextType::Invalid), m_data_buffer() {} Value::Value(const void *bytes, int len) : m_value(), m_compiler_type(), m_context(nullptr), - m_value_type(eValueTypeHostAddress), m_context_type(eContextTypeInvalid), + m_value_type(ValueType::HostAddress), m_context_type(ContextType::Invalid), m_data_buffer() { SetBytes(bytes, len); } @@ -91,13 +88,13 @@ Value &Value::operator=(const Value &rhs) { } void Value::SetBytes(const void *bytes, int len) { - m_value_type = eValueTypeHostAddress; + m_value_type = ValueType::HostAddress; m_data_buffer.CopyData(bytes, len); m_value = (uintptr_t)m_data_buffer.GetBytes(); } void Value::AppendBytes(const void *bytes, int len) { - m_value_type = eValueTypeHostAddress; + m_value_type = ValueType::HostAddress; m_data_buffer.AppendData(bytes, len); m_value = (uintptr_t)m_data_buffer.GetBytes(); } @@ -113,26 +110,27 @@ Value::ValueType Value::GetValueType() const { return m_value_type; } AddressType Value::GetValueAddressType() const { switch (m_value_type) { - case eValueTypeScalar: + case ValueType::Invalid: + case ValueType::Scalar: break; - case eValueTypeLoadAddress: + case ValueType::LoadAddress: return eAddressTypeLoad; - case eValueTypeFileAddress: + case ValueType::FileAddress: return eAddressTypeFile; - case eValueTypeHostAddress: + case ValueType::HostAddress: return eAddressTypeHost; } return eAddressTypeInvalid; } RegisterInfo *Value::GetRegisterInfo() const { - if (m_context_type == eContextTypeRegisterInfo) + if (m_context_type == ContextType::RegisterInfo) return static_cast<RegisterInfo *>(m_context); return nullptr; } Type *Value::GetType() { - if (m_context_type == eContextTypeLLDBType) + if (m_context_type == ContextType::LLDBType) return static_cast<Type *>(m_context); return nullptr; } @@ -144,7 +142,9 @@ size_t Value::AppendDataToHostBuffer(const Value &rhs) { size_t curr_size = m_data_buffer.GetByteSize(); Status error; switch (rhs.GetValueType()) { - case eValueTypeScalar: { + case ValueType::Invalid: + return 0; + case ValueType::Scalar: { const size_t scalar_size = rhs.m_value.GetByteSize(); if (scalar_size > 0) { const size_t new_size = curr_size + scalar_size; @@ -156,9 +156,9 @@ size_t Value::AppendDataToHostBuffer(const Value &rhs) { } } } break; - case eValueTypeFileAddress: - case eValueTypeLoadAddress: - case eValueTypeHostAddress: { + case ValueType::FileAddress: + case ValueType::LoadAddress: + case ValueType::HostAddress: { const uint8_t *src = rhs.GetBuffer().GetBytes(); const size_t src_len = rhs.GetBuffer().GetByteSize(); if (src && src_len > 0) { @@ -174,7 +174,7 @@ size_t Value::AppendDataToHostBuffer(const Value &rhs) { } size_t Value::ResizeData(size_t len) { - m_value_type = eValueTypeHostAddress; + m_value_type = ValueType::HostAddress; m_data_buffer.SetByteSize(len); m_value = (uintptr_t)m_data_buffer.GetBytes(); return m_data_buffer.GetByteSize(); @@ -182,12 +182,12 @@ size_t Value::ResizeData(size_t len) { bool Value::ValueOf(ExecutionContext *exe_ctx) { switch (m_context_type) { - case eContextTypeInvalid: - case eContextTypeRegisterInfo: // RegisterInfo * - case eContextTypeLLDBType: // Type * + case ContextType::Invalid: + case ContextType::RegisterInfo: // RegisterInfo * + case ContextType::LLDBType: // Type * break; - case eContextTypeVariable: // Variable * + case ContextType::Variable: // Variable * ResolveValue(exe_ctx); return true; } @@ -196,7 +196,7 @@ bool Value::ValueOf(ExecutionContext *exe_ctx) { uint64_t Value::GetValueByteSize(Status *error_ptr, ExecutionContext *exe_ctx) { switch (m_context_type) { - case eContextTypeRegisterInfo: // RegisterInfo * + case ContextType::RegisterInfo: // RegisterInfo * if (GetRegisterInfo()) { if (error_ptr) error_ptr->Clear(); @@ -204,9 +204,9 @@ uint64_t Value::GetValueByteSize(Status *error_ptr, ExecutionContext *exe_ctx) { } break; - case eContextTypeInvalid: - case eContextTypeLLDBType: // Type * - case eContextTypeVariable: // Variable * + case ContextType::Invalid: + case ContextType::LLDBType: // Type * + case ContextType::Variable: // Variable * { auto *scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr; if (llvm::Optional<uint64_t> size = GetCompilerType().GetByteSize(scope)) { @@ -225,19 +225,19 @@ uint64_t Value::GetValueByteSize(Status *error_ptr, ExecutionContext *exe_ctx) { const CompilerType &Value::GetCompilerType() { if (!m_compiler_type.IsValid()) { switch (m_context_type) { - case eContextTypeInvalid: + case ContextType::Invalid: break; - case eContextTypeRegisterInfo: + case ContextType::RegisterInfo: break; // TODO: Eventually convert into a compiler type? - case eContextTypeLLDBType: { + case ContextType::LLDBType: { Type *lldb_type = GetType(); if (lldb_type) m_compiler_type = lldb_type->GetForwardCompilerType(); } break; - case eContextTypeVariable: { + case ContextType::Variable: { Variable *variable = GetVariable(); if (variable) { Type *variable_type = variable->GetType(); @@ -257,14 +257,14 @@ void Value::SetCompilerType(const CompilerType &compiler_type) { lldb::Format Value::GetValueDefaultFormat() { switch (m_context_type) { - case eContextTypeRegisterInfo: + case ContextType::RegisterInfo: if (GetRegisterInfo()) return GetRegisterInfo()->format; break; - case eContextTypeInvalid: - case eContextTypeLLDBType: - case eContextTypeVariable: { + case ContextType::Invalid: + case ContextType::LLDBType: + case ContextType::Variable: { const CompilerType &ast_type = GetCompilerType(); if (ast_type.IsValid()) return ast_type.GetFormat(); @@ -277,14 +277,16 @@ lldb::Format Value::GetValueDefaultFormat() { bool Value::GetData(DataExtractor &data) { switch (m_value_type) { - case eValueTypeScalar: + case ValueType::Invalid: + return false; + case ValueType::Scalar: if (m_value.GetData(data)) return true; break; - case eValueTypeLoadAddress: - case eValueTypeFileAddress: - case eValueTypeHostAddress: + case ValueType::LoadAddress: + case ValueType::FileAddress: + case ValueType::HostAddress: if (m_data_buffer.GetByteSize()) { data.SetData(m_data_buffer.GetBytes(), m_data_buffer.GetByteSize(), data.GetByteOrder()); @@ -312,7 +314,10 @@ Status Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data, return error; switch (m_value_type) { - case eValueTypeScalar: { + case ValueType::Invalid: + error.SetErrorString("invalid value"); + break; + case ValueType::Scalar: { data.SetByteOrder(endian::InlHostByteOrder()); if (ast_type.IsValid()) data.SetAddressByteSize(ast_type.GetPointerByteSize()); @@ -332,7 +337,7 @@ Status Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data, error.SetErrorString("extracting data from value failed"); break; } - case eValueTypeLoadAddress: + case ValueType::LoadAddress: if (exe_ctx == nullptr) { error.SetErrorString("can't read load address (no execution context)"); } else { @@ -369,7 +374,7 @@ Status Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data, } break; - case eValueTypeFileAddress: + case ValueType::FileAddress: if (exe_ctx == nullptr) { error.SetErrorString("can't read file address (no execution context)"); } else if (exe_ctx->GetTargetPtr() == nullptr) { @@ -459,7 +464,7 @@ Status Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data, } break; - case eValueTypeHostAddress: + case ValueType::HostAddress: address = m_value.ULongLong(LLDB_INVALID_ADDRESS); address_type = eAddressTypeHost; if (exe_ctx) { @@ -517,15 +522,10 @@ Status Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data, } else if ((address_type == eAddressTypeLoad) || (address_type == eAddressTypeFile)) { if (file_so_addr.IsValid()) { - // We have a file address that we were able to translate into a section - // offset address so we might be able to read this from the object - // files if we don't have a live process. Lets always try and read from - // the process if we have one though since we want to read the actual - // value by setting "prefer_file_cache" to false. - const bool prefer_file_cache = false; - if (exe_ctx->GetTargetRef().ReadMemory(file_so_addr, prefer_file_cache, - dst, byte_size, - error) != byte_size) { + const bool force_live_memory = true; + if (exe_ctx->GetTargetRef().ReadMemory(file_so_addr, dst, byte_size, + error, force_live_memory) != + byte_size) { error.SetErrorStringWithFormat( "read memory from 0x%" PRIx64 " failed", (uint64_t)address); } @@ -564,12 +564,13 @@ Scalar &Value::ResolveValue(ExecutionContext *exe_ctx) { const CompilerType &compiler_type = GetCompilerType(); if (compiler_type.IsValid()) { switch (m_value_type) { - case eValueTypeScalar: // raw scalar value + case ValueType::Invalid: + case ValueType::Scalar: // raw scalar value break; - case eValueTypeFileAddress: - case eValueTypeLoadAddress: // load address value - case eValueTypeHostAddress: // host address value (for memory in the process + case ValueType::FileAddress: + case ValueType::LoadAddress: // load address value + case ValueType::HostAddress: // host address value (for memory in the process // that is using liblldb) { DataExtractor data; @@ -581,17 +582,17 @@ Scalar &Value::ResolveValue(ExecutionContext *exe_ctx) { data, 0, data.GetByteSize(), scalar, exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr)) { m_value = scalar; - m_value_type = eValueTypeScalar; + m_value_type = ValueType::Scalar; } else { if ((uintptr_t)addr != (uintptr_t)m_data_buffer.GetBytes()) { m_value.Clear(); - m_value_type = eValueTypeScalar; + m_value_type = ValueType::Scalar; } } } else { if ((uintptr_t)addr != (uintptr_t)m_data_buffer.GetBytes()) { m_value.Clear(); - m_value_type = eValueTypeScalar; + m_value_type = ValueType::Scalar; } } } break; @@ -601,7 +602,7 @@ Scalar &Value::ResolveValue(ExecutionContext *exe_ctx) { } Variable *Value::GetVariable() { - if (m_context_type == eContextTypeVariable) + if (m_context_type == ContextType::Variable) return static_cast<Variable *>(m_context); return nullptr; } @@ -609,42 +610,44 @@ Variable *Value::GetVariable() { void Value::Clear() { m_value.Clear(); m_compiler_type.Clear(); - m_value_type = eValueTypeScalar; + m_value_type = ValueType::Scalar; m_context = nullptr; - m_context_type = eContextTypeInvalid; + m_context_type = ContextType::Invalid; m_data_buffer.Clear(); } const char *Value::GetValueTypeAsCString(ValueType value_type) { switch (value_type) { - case eValueTypeScalar: + case ValueType::Invalid: + return "invalid"; + case ValueType::Scalar: return "scalar"; - case eValueTypeFileAddress: + case ValueType::FileAddress: return "file address"; - case eValueTypeLoadAddress: + case ValueType::LoadAddress: return "load address"; - case eValueTypeHostAddress: + case ValueType::HostAddress: return "host address"; }; - return "???"; + llvm_unreachable("enum cases exhausted."); } const char *Value::GetContextTypeAsCString(ContextType context_type) { switch (context_type) { - case eContextTypeInvalid: + case ContextType::Invalid: return "invalid"; - case eContextTypeRegisterInfo: + case ContextType::RegisterInfo: return "RegisterInfo *"; - case eContextTypeLLDBType: + case ContextType::LLDBType: return "Type *"; - case eContextTypeVariable: + case ContextType::Variable: return "Variable *"; }; - return "???"; + llvm_unreachable("enum cases exhausted."); } void Value::ConvertToLoadAddress(Module *module, Target *target) { - if (!module || !target || (GetValueType() != eValueTypeFileAddress)) + if (!module || !target || (GetValueType() != ValueType::FileAddress)) return; lldb::addr_t file_addr = GetScalar().ULongLong(LLDB_INVALID_ADDRESS); @@ -658,7 +661,7 @@ void Value::ConvertToLoadAddress(Module *module, Target *target) { if (load_addr == LLDB_INVALID_ADDRESS) return; - SetValueType(Value::eValueTypeLoadAddress); + SetValueType(Value::ValueType::LoadAddress); GetScalar() = load_addr; } diff --git a/contrib/llvm-project/lldb/source/Core/ValueObject.cpp b/contrib/llvm-project/lldb/source/Core/ValueObject.cpp index da90092336d6..9c1ba99da1d0 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObject.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObject.cpp @@ -9,6 +9,7 @@ #include "lldb/Core/ValueObject.h" #include "lldb/Core/Address.h" +#include "lldb/Core/Declaration.h" #include "lldb/Core/Module.h" #include "lldb/Core/ValueObjectCast.h" #include "lldb/Core/ValueObjectChild.h" @@ -27,7 +28,6 @@ #include "lldb/Host/Config.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/CompilerType.h" -#include "lldb/Symbol/Declaration.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/Type.h" #include "lldb/Symbol/Variable.h" @@ -57,10 +57,12 @@ #include <memory> #include <tuple> -#include <assert.h> -#include <inttypes.h> -#include <stdio.h> -#include <string.h> +#include <cassert> +#include <cinttypes> +#include <cstdio> +#include <cstring> + +#include <lldb/Core/ValueObject.h> namespace lldb_private { class ExecutionContextScope; @@ -76,27 +78,10 @@ static user_id_t g_value_obj_uid = 0; // ValueObject constructor ValueObject::ValueObject(ValueObject &parent) - : UserID(++g_value_obj_uid), // Unique identifier for every value object - m_parent(&parent), m_root(nullptr), - m_update_point(parent.GetUpdatePoint()), m_name(), m_data(), m_value(), - m_error(), m_value_str(), m_old_value_str(), m_location_str(), - m_summary_str(), m_object_desc_str(), m_manager(parent.GetManager()), - m_children(), m_synthetic_children(), m_dynamic_value(nullptr), - m_synthetic_value(nullptr), m_deref_valobj(nullptr), - m_format(eFormatDefault), m_last_format(eFormatDefault), - m_last_format_mgr_revision(0), m_type_summary_sp(), m_type_format_sp(), - m_synthetic_children_sp(), m_user_id_of_forced_summary(), - m_address_type_of_ptr_or_ref_children(eAddressTypeInvalid), - m_value_checksum(), - m_preferred_display_language(lldb::eLanguageTypeUnknown), - m_language_flags(0), m_value_is_valid(false), m_value_did_change(false), - m_children_count_valid(false), m_old_value_valid(false), - m_is_deref_of_parent(false), m_is_array_item_for_pointer(false), - m_is_bitfield_for_scalar(false), m_is_child_at_offset(false), - m_is_getting_summary(false), - m_did_calculate_complete_objc_class_type(false), - m_is_synthetic_children_generated( - parent.m_is_synthetic_children_generated) { + : m_parent(&parent), m_update_point(parent.GetUpdatePoint()), + m_manager(parent.GetManager()), m_id(++g_value_obj_uid) { + m_flags.m_is_synthetic_children_generated = + parent.m_flags.m_is_synthetic_children_generated; m_data.SetByteOrder(parent.GetDataExtractor().GetByteOrder()); m_data.SetAddressByteSize(parent.GetDataExtractor().GetAddressByteSize()); m_manager->ManageObject(this); @@ -106,26 +91,9 @@ ValueObject::ValueObject(ValueObject &parent) ValueObject::ValueObject(ExecutionContextScope *exe_scope, ValueObjectManager &manager, AddressType child_ptr_or_ref_addr_type) - : UserID(++g_value_obj_uid), // Unique identifier for every value object - m_parent(nullptr), m_root(nullptr), m_update_point(exe_scope), m_name(), - m_data(), m_value(), m_error(), m_value_str(), m_old_value_str(), - m_location_str(), m_summary_str(), m_object_desc_str(), - m_manager(&manager), m_children(), m_synthetic_children(), - m_dynamic_value(nullptr), m_synthetic_value(nullptr), - m_deref_valobj(nullptr), m_format(eFormatDefault), - m_last_format(eFormatDefault), m_last_format_mgr_revision(0), - m_type_summary_sp(), m_type_format_sp(), m_synthetic_children_sp(), - m_user_id_of_forced_summary(), + : m_update_point(exe_scope), m_manager(&manager), m_address_type_of_ptr_or_ref_children(child_ptr_or_ref_addr_type), - m_value_checksum(), - m_preferred_display_language(lldb::eLanguageTypeUnknown), - m_language_flags(0), m_value_is_valid(false), m_value_did_change(false), - m_children_count_valid(false), m_old_value_valid(false), - m_is_deref_of_parent(false), m_is_array_item_for_pointer(false), - m_is_bitfield_for_scalar(false), m_is_child_at_offset(false), - m_is_getting_summary(false), - m_did_calculate_complete_objc_class_type(false), - m_is_synthetic_children_generated(false) { + m_id(++g_value_obj_uid) { if (exe_scope) { TargetSP target_sp(exe_scope->CalculateTarget()); if (target_sp) { @@ -138,7 +106,7 @@ ValueObject::ValueObject(ExecutionContextScope *exe_scope, } // Destructor -ValueObject::~ValueObject() {} +ValueObject::~ValueObject() = default; bool ValueObject::UpdateValueIfNeeded(bool update_format) { @@ -170,9 +138,9 @@ bool ValueObject::UpdateValueIfNeeded(bool update_format) { // Save the old value using swap to avoid a string copy which also will // clear our m_value_str if (m_value_str.empty()) { - m_old_value_valid = false; + m_flags.m_old_value_valid = false; } else { - m_old_value_valid = true; + m_flags.m_old_value_valid = true; m_old_value_str.swap(m_value_str); ClearUserVisibleData(eClearUserVisibleDataItemsValue); } @@ -215,7 +183,7 @@ bool ValueObject::UpdateValueIfNeeded(bool update_format) { if (first_update) SetValueDidChange(false); - else if (!m_value_did_change && !success) { + else if (!m_flags.m_value_did_change && !success) { // The value wasn't gotten successfully, so we mark this as changed if // the value used to be valid and now isn't SetValueDidChange(value_was_valid); @@ -266,8 +234,8 @@ void ValueObject::SetNeedsUpdate() { } void ValueObject::ClearDynamicTypeInformation() { - m_children_count_valid = false; - m_did_calculate_complete_objc_class_type = false; + m_flags.m_children_count_valid = false; + m_flags.m_did_calculate_complete_objc_class_type = false; m_last_format_mgr_revision = 0; m_override_type = CompilerType(); SetValueFormat(lldb::TypeFormatImplSP()); @@ -278,14 +246,14 @@ void ValueObject::ClearDynamicTypeInformation() { CompilerType ValueObject::MaybeCalculateCompleteType() { CompilerType compiler_type(GetCompilerTypeImpl()); - if (m_did_calculate_complete_objc_class_type) { + if (m_flags.m_did_calculate_complete_objc_class_type) { if (m_override_type.IsValid()) return m_override_type; else return compiler_type; } - m_did_calculate_complete_objc_class_type = true; + m_flags.m_did_calculate_complete_objc_class_type = true; ProcessSP process_sp( GetUpdatePoint().GetExecutionContextRef().GetProcessSP()); @@ -305,11 +273,7 @@ CompilerType ValueObject::MaybeCalculateCompleteType() { return compiler_type; } -CompilerType ValueObject::GetCompilerType() { - return MaybeCalculateCompleteType(); -} -TypeImpl ValueObject::GetTypeImpl() { return TypeImpl(GetCompilerType()); } DataExtractor &ValueObject::GetDataExtractor() { UpdateValueIfNeeded(false); @@ -321,12 +285,6 @@ const Status &ValueObject::GetError() { return m_error; } -ConstString ValueObject::GetName() const { return m_name; } - -const char *ValueObject::GetLocationAsCString() { - return GetLocationAsCStringImpl(m_value, m_data); -} - const char *ValueObject::GetLocationAsCStringImpl(const Value &value, const DataExtractor &data) { if (UpdateValueIfNeeded(false)) { @@ -336,8 +294,11 @@ const char *ValueObject::GetLocationAsCStringImpl(const Value &value, Value::ValueType value_type = value.GetValueType(); switch (value_type) { - case Value::eValueTypeScalar: - if (value.GetContextType() == Value::eContextTypeRegisterInfo) { + case Value::ValueType::Invalid: + m_location_str = "invalid"; + break; + case Value::ValueType::Scalar: + if (value.GetContextType() == Value::ContextType::RegisterInfo) { RegisterInfo *reg_info = value.GetRegisterInfo(); if (reg_info) { if (reg_info->name) @@ -354,9 +315,9 @@ const char *ValueObject::GetLocationAsCStringImpl(const Value &value, m_location_str = "scalar"; break; - case Value::eValueTypeLoadAddress: - case Value::eValueTypeFileAddress: - case Value::eValueTypeHostAddress: { + case Value::ValueType::LoadAddress: + case Value::ValueType::FileAddress: + case Value::ValueType::HostAddress: { uint32_t addr_nibble_size = data.GetAddressByteSize() * 2; sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size, value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS)); @@ -368,10 +329,6 @@ const char *ValueObject::GetLocationAsCStringImpl(const Value &value, return m_location_str.c_str(); } -Value &ValueObject::GetValue() { return m_value; } - -const Value &ValueObject::GetValue() const { return m_value; } - bool ValueObject::ResolveValue(Scalar &scalar) { if (UpdateValueIfNeeded( false)) // make sure that you are up to date before returning anything @@ -415,16 +372,6 @@ bool ValueObject::IsLogicalTrue(Status &error) { return ret; } -bool ValueObject::GetValueIsValid() const { return m_value_is_valid; } - -void ValueObject::SetValueIsValid(bool b) { m_value_is_valid = b; } - -bool ValueObject::GetValueDidChange() { return m_value_did_change; } - -void ValueObject::SetValueDidChange(bool value_changed) { - m_value_did_change = value_changed; -} - ValueObjectSP ValueObject::GetChildAtIndex(size_t idx, bool can_create) { ValueObjectSP child_sp; // We may need to update our value if we are dynamic @@ -550,14 +497,14 @@ size_t ValueObject::GetNumChildren(uint32_t max) { UpdateValueIfNeeded(); if (max < UINT32_MAX) { - if (m_children_count_valid) { + if (m_flags.m_children_count_valid) { size_t children_count = m_children.GetChildrenCount(); return children_count <= max ? children_count : max; } else return CalculateNumChildren(max); } - if (!m_children_count_valid) { + if (!m_flags.m_children_count_valid) { SetNumChildren(CalculateNumChildren()); } return m_children.GetChildrenCount(); @@ -577,12 +524,10 @@ bool ValueObject::MightHaveChildren() { // Should only be called by ValueObject::GetNumChildren() void ValueObject::SetNumChildren(size_t num_children) { - m_children_count_valid = true; + m_flags.m_children_count_valid = true; m_children.SetChildrenCount(num_children); } -void ValueObject::SetName(ConstString name) { m_name = name; } - ValueObject *ValueObject::CreateChildAtIndex(size_t idx, bool synthetic_array_member, int32_t synthetic_index) { @@ -651,10 +596,10 @@ bool ValueObject::GetSummaryAsCString(TypeSummaryImpl *summary_ptr, // ideally we would like to bail out if passing NULL, but if we do so we end // up not providing the summary for function pointers anymore - if (/*summary_ptr == NULL ||*/ m_is_getting_summary) + if (/*summary_ptr == NULL ||*/ m_flags.m_is_getting_summary) return false; - m_is_getting_summary = true; + m_flags.m_is_getting_summary = true; TypeSummaryOptions actual_options(options); @@ -677,7 +622,7 @@ bool ValueObject::GetSummaryAsCString(TypeSummaryImpl *summary_ptr, // up-to-date (e.g. ${svar%#}) summary_ptr->FormatObject(this, destination, actual_options); } - m_is_getting_summary = false; + m_flags.m_is_getting_summary = false; return !destination.empty(); } @@ -776,7 +721,7 @@ size_t ValueObject::GetPointeeData(DataExtractor &data, uint32_t item_idx, if (target) { heap_buf_ptr->SetByteSize(bytes); size_t bytes_read = target->ReadMemory( - so_addr, false, heap_buf_ptr->GetBytes(), bytes, error); + so_addr, heap_buf_ptr->GetBytes(), bytes, error, true); if (error.Success()) { data.SetData(data_sp); return bytes_read; @@ -852,7 +797,10 @@ bool ValueObject::SetData(DataExtractor &data, Status &error) { Value::ValueType value_type = m_value.GetValueType(); switch (value_type) { - case Value::eValueTypeScalar: { + case Value::ValueType::Invalid: + error.SetErrorString("invalid location"); + return false; + case Value::ValueType::Scalar: { Status set_error = m_value.GetScalar().SetValueFromData(data, encoding, byte_size); @@ -862,7 +810,7 @@ bool ValueObject::SetData(DataExtractor &data, Status &error) { return false; } } break; - case Value::eValueTypeLoadAddress: { + case Value::ValueType::LoadAddress: { // If it is a load address, then the scalar value is the storage location // of the data, and we have to shove this value down to that load location. ExecutionContext exe_ctx(GetExecutionContextRef()); @@ -879,7 +827,7 @@ bool ValueObject::SetData(DataExtractor &data, Status &error) { } } } break; - case Value::eValueTypeHostAddress: { + case Value::ValueType::HostAddress: { // If it is a host address, then we stuff the scalar as a DataBuffer into // the Value's data. DataBufferSP buffer_sp(new DataBufferHeap(byte_size, 0)); @@ -889,7 +837,7 @@ bool ValueObject::SetData(DataExtractor &data, Status &error) { byte_size, m_data.GetByteOrder()); m_value.GetScalar() = (uintptr_t)m_data.GetDataStart(); } break; - case Value::eValueTypeFileAddress: + case Value::ValueType::FileAddress: break; } @@ -942,7 +890,7 @@ ValueObject::ReadPointedString(lldb::DataBufferSP &buffer_sp, Status &error, if (is_array) { // We have an array uint64_t array_size = 0; - if (compiler_type.IsArrayType(nullptr, &array_size, nullptr)) { + if (compiler_type.IsArrayType(nullptr, &array_size)) { cstr_len = array_size; if (cstr_len > max_length) { capped_data = true; @@ -1104,10 +1052,10 @@ const char *ValueObject::GetValueAsCString() { if (m_type_format_sp) format_sp = m_type_format_sp; else { - if (m_is_bitfield_for_scalar) + if (m_flags.m_is_bitfield_for_scalar) my_format = eFormatUnsigned; else { - if (m_value.GetContextType() == Value::eContextTypeRegisterInfo) { + if (m_value.GetContextType() == Value::ContextType::RegisterInfo) { const RegisterInfo *reg_info = m_value.GetRegisterInfo(); if (reg_info) my_format = reg_info->format; @@ -1122,7 +1070,7 @@ const char *ValueObject::GetValueAsCString() { if (!format_sp) format_sp = std::make_shared<TypeFormatImpl_Format>(my_format); if (GetValueAsCString(*format_sp.get(), m_value_str)) { - if (!m_value_did_change && m_old_value_valid) { + if (!m_flags.m_value_did_change && m_flags.m_old_value_valid) { // The value was gotten successfully, so we consider the value as // changed if the value string differs SetValueDidChange(m_old_value_str != m_value_str); @@ -1455,7 +1403,9 @@ addr_t ValueObject::GetAddressOf(bool scalar_is_load_address, return LLDB_INVALID_ADDRESS; switch (m_value.GetValueType()) { - case Value::eValueTypeScalar: + case Value::ValueType::Invalid: + return LLDB_INVALID_ADDRESS; + case Value::ValueType::Scalar: if (scalar_is_load_address) { if (address_type) *address_type = eAddressTypeLoad; @@ -1463,13 +1413,13 @@ addr_t ValueObject::GetAddressOf(bool scalar_is_load_address, } break; - case Value::eValueTypeLoadAddress: - case Value::eValueTypeFileAddress: { + case Value::ValueType::LoadAddress: + case Value::ValueType::FileAddress: { if (address_type) *address_type = m_value.GetValueAddressType(); return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); } break; - case Value::eValueTypeHostAddress: { + case Value::ValueType::HostAddress: { if (address_type) *address_type = m_value.GetValueAddressType(); return LLDB_INVALID_ADDRESS; @@ -1489,13 +1439,15 @@ addr_t ValueObject::GetPointerValue(AddressType *address_type) { return address; switch (m_value.GetValueType()) { - case Value::eValueTypeScalar: + case Value::ValueType::Invalid: + return LLDB_INVALID_ADDRESS; + case Value::ValueType::Scalar: address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); break; - case Value::eValueTypeHostAddress: - case Value::eValueTypeLoadAddress: - case Value::eValueTypeFileAddress: { + case Value::ValueType::HostAddress: + case Value::ValueType::LoadAddress: + case Value::ValueType::FileAddress: { lldb::offset_t data_offset = 0; address = m_data.GetAddress(&data_offset); } break; @@ -1523,7 +1475,7 @@ bool ValueObject::SetValueFromCString(const char *value_str, Status &error) { Value::ValueType value_type = m_value.GetValueType(); - if (value_type == Value::eValueTypeScalar) { + if (value_type == Value::ValueType::Scalar) { // If the value is already a scalar, then let the scalar change itself: m_value.GetScalar().SetValueFromCString(value_str, encoding, byte_size); } else if (byte_size <= 16) { @@ -1534,7 +1486,7 @@ bool ValueObject::SetValueFromCString(const char *value_str, Status &error) { error = new_scalar.SetValueFromCString(value_str, encoding, byte_size); if (error.Success()) { switch (value_type) { - case Value::eValueTypeLoadAddress: { + case Value::ValueType::LoadAddress: { // If it is a load address, then the scalar value is the storage // location of the data, and we have to shove this value down to that // load location. @@ -1553,7 +1505,7 @@ bool ValueObject::SetValueFromCString(const char *value_str, Status &error) { } } } break; - case Value::eValueTypeHostAddress: { + case Value::ValueType::HostAddress: { // If it is a host address, then we stuff the scalar as a DataBuffer // into the Value's data. DataExtractor new_data; @@ -1570,8 +1522,11 @@ bool ValueObject::SetValueFromCString(const char *value_str, Status &error) { m_value.GetScalar() = (uintptr_t)m_data.GetDataStart(); } break; - case Value::eValueTypeFileAddress: - case Value::eValueTypeScalar: + case Value::ValueType::Invalid: + error.SetErrorString("invalid location"); + return false; + case Value::ValueType::FileAddress: + case Value::ValueType::Scalar: break; } } else { @@ -1594,20 +1549,6 @@ bool ValueObject::GetDeclaration(Declaration &decl) { return false; } -ConstString ValueObject::GetTypeName() { - return GetCompilerType().GetTypeName(); -} - -ConstString ValueObject::GetDisplayTypeName() { return GetTypeName(); } - -ConstString ValueObject::GetQualifiedTypeName() { - return GetCompilerType().GetTypeName(); -} - -LanguageType ValueObject::GetObjectRuntimeLanguage() { - return GetCompilerType().GetMinimumLanguage(); -} - void ValueObject::AddSyntheticChild(ConstString key, ValueObject *valobj) { m_synthetic_children[key] = valobj; @@ -1622,27 +1563,6 @@ ValueObjectSP ValueObject::GetSyntheticChild(ConstString key) const { return synthetic_child_sp; } -uint32_t -ValueObject::GetTypeInfo(CompilerType *pointee_or_element_compiler_type) { - return GetCompilerType().GetTypeInfo(pointee_or_element_compiler_type); -} - -bool ValueObject::IsPointerType() { return GetCompilerType().IsPointerType(); } - -bool ValueObject::IsArrayType() { - return GetCompilerType().IsArrayType(nullptr, nullptr, nullptr); -} - -bool ValueObject::IsScalarType() { return GetCompilerType().IsScalarType(); } - -bool ValueObject::IsIntegerType(bool &is_signed) { - return GetCompilerType().IsIntegerType(is_signed); -} - -bool ValueObject::IsPointerOrReferenceType() { - return GetCompilerType().IsPointerOrReferenceType(); -} - bool ValueObject::IsPossibleDynamicType() { ExecutionContext exe_ctx(GetExecutionContextRef()); Process *process = exe_ctx.GetProcessPtr(); @@ -1657,7 +1577,7 @@ bool ValueObject::IsRuntimeSupportValue() { if (!process) return false; - // We trust the the compiler did the right thing and marked runtime support + // We trust that the compiler did the right thing and marked runtime support // values as artificial. if (!GetVariable() || !GetVariable()->IsArtificial()) return false; @@ -1712,7 +1632,7 @@ ValueObjectSP ValueObject::GetSyntheticArrayMember(size_t index, AddSyntheticChild(index_const_str, synthetic_child); synthetic_child_sp = synthetic_child->GetSP(); synthetic_child_sp->SetName(ConstString(index_str)); - synthetic_child_sp->m_is_array_item_for_pointer = true; + synthetic_child_sp->m_flags.m_is_array_item_for_pointer = true; } } } @@ -1746,7 +1666,7 @@ ValueObjectSP ValueObject::GetSyntheticBitFieldChild(uint32_t from, uint32_t to, AddSyntheticChild(index_const_str, synthetic_child); synthetic_child_sp = synthetic_child->GetSP(); synthetic_child_sp->SetName(ConstString(index_str)); - synthetic_child_sp->m_is_bitfield_for_scalar = true; + synthetic_child_sp->m_flags.m_is_bitfield_for_scalar = true; } } } @@ -1785,7 +1705,7 @@ ValueObjectSP ValueObject::GetSyntheticChildAtOffset( AddSyntheticChild(name_const_str, synthetic_child); synthetic_child_sp = synthetic_child->GetSP(); synthetic_child_sp->SetName(name_const_str); - synthetic_child_sp->m_is_child_at_offset = true; + synthetic_child_sp->m_flags.m_is_child_at_offset = true; } return synthetic_child_sp; } @@ -1922,10 +1842,6 @@ ValueObjectSP ValueObject::GetDynamicValue(DynamicValueType use_dynamic) { return ValueObjectSP(); } -ValueObjectSP ValueObject::GetStaticValue() { return GetSP(); } - -lldb::ValueObjectSP ValueObject::GetNonSyntheticValue() { return GetSP(); } - ValueObjectSP ValueObject::GetSyntheticValue() { CalculateSyntheticValue(); @@ -1977,10 +1893,10 @@ void ValueObject::GetExpressionPath(Stream &s, // sometimes they are consed up in ways that don't make sense from an // underlying language/API standpoint. So, use a special code path here to // return something that can hopefully be used in expression - if (m_is_synthetic_children_generated) { + if (m_flags.m_is_synthetic_children_generated) { UpdateValueIfNeeded(); - if (m_value.GetValueType() == Value::eValueTypeLoadAddress) { + if (m_value.GetValueType() == Value::ValueType::LoadAddress) { if (IsPointerOrReferenceType()) { s.Printf("((%s)0x%" PRIx64 ")", GetTypeName().AsCString("void"), GetValueAsUnsigned(0)); @@ -2025,7 +1941,7 @@ void ValueObject::GetExpressionPath(Stream &s, // if we are a deref_of_parent just because we are synthetic array members // made up to allow ptr[%d] syntax to work in variable printing, then add our // name ([%d]) to the expression path - if (m_is_array_item_for_pointer && + if (m_flags.m_is_array_item_for_pointer && epformat == eGetExpressionPathFormatHonorPointers) s.PutCString(m_name.GetStringRef()); @@ -2640,21 +2556,6 @@ ValueObjectSP ValueObject::GetValueForExpressionPath_Impl( } } -void ValueObject::LogValueObject(Log *log) { - if (log) - return LogValueObject(log, DumpValueObjectOptions(*this)); -} - -void ValueObject::LogValueObject(Log *log, - const DumpValueObjectOptions &options) { - if (log) { - StreamString s; - Dump(s, options); - if (s.GetSize()) - log->PutCString(s.GetData()); - } -} - void ValueObject::Dump(Stream &s) { Dump(s, DumpValueObjectOptions(*this)); } void ValueObject::Dump(Stream &s, const DumpValueObjectOptions &options) { @@ -2895,8 +2796,7 @@ ValueObjectSP ValueObject::CastPointerType(const char *name, TypeSP &type_sp) { return valobj_sp; } -ValueObject::EvaluationPoint::EvaluationPoint() - : m_mod_id(), m_exe_ctx_ref(), m_needs_update(true) {} +ValueObject::EvaluationPoint::EvaluationPoint() : m_mod_id(), m_exe_ctx_ref() {} ValueObject::EvaluationPoint::EvaluationPoint(ExecutionContextScope *exe_scope, bool use_selected) @@ -2939,7 +2839,7 @@ ValueObject::EvaluationPoint::EvaluationPoint( const ValueObject::EvaluationPoint &rhs) : m_mod_id(), m_exe_ctx_ref(rhs.m_exe_ctx_ref), m_needs_update(true) {} -ValueObject::EvaluationPoint::~EvaluationPoint() {} +ValueObject::EvaluationPoint::~EvaluationPoint() = default; // This function checks the EvaluationPoint against the current process state. // If the current state matches the evaluation point, or the evaluation point @@ -3093,7 +2993,7 @@ lldb::ValueObjectSP ValueObject::CreateValueObjectFromAddress( exe_ctx.GetAddressByteSize())); if (ptr_result_valobj_sp) { ptr_result_valobj_sp->GetValue().SetValueType( - Value::eValueTypeLoadAddress); + Value::ValueType::LoadAddress); Status err; ptr_result_valobj_sp = ptr_result_valobj_sp->Dereference(err); if (ptr_result_valobj_sp && !name.empty()) @@ -3192,10 +3092,6 @@ lldb::LanguageType ValueObject::GetPreferredDisplayLanguage() { return (m_preferred_display_language = type); // only compute it once } -void ValueObject::SetPreferredDisplayLanguage(lldb::LanguageType lt) { - m_preferred_display_language = lt; -} - void ValueObject::SetPreferredDisplayLanguageIfNeeded(lldb::LanguageType lt) { if (m_preferred_display_language == lldb::eLanguageTypeUnknown) SetPreferredDisplayLanguage(lt); @@ -3209,7 +3105,7 @@ bool ValueObject::CanProvideValue() { return (!type.IsValid()) || (0 != (type.GetTypeInfo() & eTypeHasValue)); } -bool ValueObject::IsChecksumEmpty() { return m_value_checksum.empty(); } + ValueObjectSP ValueObject::Persist() { if (!UpdateValueIfNeeded()) @@ -3238,109 +3134,3 @@ ValueObjectSP ValueObject::Persist() { return persistent_var_sp->GetValueObject(); } - -bool ValueObject::IsSyntheticChildrenGenerated() { - return m_is_synthetic_children_generated; -} - -void ValueObject::SetSyntheticChildrenGenerated(bool b) { - m_is_synthetic_children_generated = b; -} - -uint64_t ValueObject::GetLanguageFlags() { return m_language_flags; } - -void ValueObject::SetLanguageFlags(uint64_t flags) { m_language_flags = flags; } - -ValueObjectManager::ValueObjectManager(lldb::ValueObjectSP in_valobj_sp, - lldb::DynamicValueType use_dynamic, - bool use_synthetic) : m_root_valobj_sp(), - m_user_valobj_sp(), m_use_dynamic(use_dynamic), m_stop_id(UINT32_MAX), - m_use_synthetic(use_synthetic) { - if (!in_valobj_sp) - return; - // If the user passes in a value object that is dynamic or synthetic, then - // water it down to the static type. - m_root_valobj_sp = in_valobj_sp->GetQualifiedRepresentationIfAvailable(lldb::eNoDynamicValues, false); -} - -bool ValueObjectManager::IsValid() const { - if (!m_root_valobj_sp) - return false; - lldb::TargetSP target_sp = GetTargetSP(); - if (target_sp) - return target_sp->IsValid(); - return false; -} - -lldb::ValueObjectSP ValueObjectManager::GetSP() { - lldb::ProcessSP process_sp = GetProcessSP(); - if (!process_sp) - return lldb::ValueObjectSP(); - - const uint32_t current_stop_id = process_sp->GetLastNaturalStopID(); - if (current_stop_id == m_stop_id) - return m_user_valobj_sp; - - m_stop_id = current_stop_id; - - if (!m_root_valobj_sp) { - m_user_valobj_sp.reset(); - return m_root_valobj_sp; - } - - m_user_valobj_sp = m_root_valobj_sp; - - if (m_use_dynamic != lldb::eNoDynamicValues) { - lldb::ValueObjectSP dynamic_sp = m_user_valobj_sp->GetDynamicValue(m_use_dynamic); - if (dynamic_sp) - m_user_valobj_sp = dynamic_sp; - } - - if (m_use_synthetic) { - lldb::ValueObjectSP synthetic_sp = m_user_valobj_sp->GetSyntheticValue(); - if (synthetic_sp) - m_user_valobj_sp = synthetic_sp; - } - - return m_user_valobj_sp; -} - -void ValueObjectManager::SetUseDynamic(lldb::DynamicValueType use_dynamic) { - if (use_dynamic != m_use_dynamic) { - m_use_dynamic = use_dynamic; - m_user_valobj_sp.reset(); - m_stop_id = UINT32_MAX; - } -} - -void ValueObjectManager::SetUseSynthetic(bool use_synthetic) { - if (m_use_synthetic != use_synthetic) { - m_use_synthetic = use_synthetic; - m_user_valobj_sp.reset(); - m_stop_id = UINT32_MAX; - } -} - -lldb::TargetSP ValueObjectManager::GetTargetSP() const { - if (!m_root_valobj_sp) - return m_root_valobj_sp->GetTargetSP(); - return lldb::TargetSP(); -} - -lldb::ProcessSP ValueObjectManager::GetProcessSP() const { - if (m_root_valobj_sp) - return m_root_valobj_sp->GetProcessSP(); - return lldb::ProcessSP(); -} - -lldb::ThreadSP ValueObjectManager::GetThreadSP() const { - if (m_root_valobj_sp) - return m_root_valobj_sp->GetThreadSP(); - return lldb::ThreadSP(); -} - -lldb::StackFrameSP ValueObjectManager::GetFrameSP() const { - if (m_root_valobj_sp) - return m_root_valobj_sp->GetFrameSP(); - return lldb::StackFrameSP(); -} diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectCast.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectCast.cpp index 7b6d3591faf4..9f803912d0ca 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObjectCast.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObjectCast.cpp @@ -36,7 +36,7 @@ ValueObjectCast::ValueObjectCast(ValueObject &parent, ConstString name, m_value.SetCompilerType(cast_type); } -ValueObjectCast::~ValueObjectCast() {} +ValueObjectCast::~ValueObjectCast() = default; CompilerType ValueObjectCast::GetCompilerTypeImpl() { return m_cast_type; } diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectChild.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectChild.cpp index 34baa19f0a24..a2beeb0bcdeb 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObjectChild.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObjectChild.cpp @@ -21,8 +21,8 @@ #include <memory> #include <vector> -#include <stdio.h> -#include <string.h> +#include <cstdio> +#include <cstring> using namespace lldb_private; @@ -43,7 +43,7 @@ ValueObjectChild::ValueObjectChild( SetLanguageFlags(language_flags); } -ValueObjectChild::~ValueObjectChild() {} +ValueObjectChild::~ValueObjectChild() = default; lldb::ValueType ValueObjectChild::GetValueType() const { return m_parent->GetValueType(); @@ -125,28 +125,30 @@ bool ValueObjectChild::UpdateValue() { case eAddressTypeFile: { lldb::ProcessSP process_sp(GetProcessSP()); if (process_sp && process_sp->IsAlive()) - m_value.SetValueType(Value::eValueTypeLoadAddress); + m_value.SetValueType(Value::ValueType::LoadAddress); else - m_value.SetValueType(Value::eValueTypeFileAddress); + m_value.SetValueType(Value::ValueType::FileAddress); } break; case eAddressTypeLoad: m_value.SetValueType(is_instance_ptr_base - ? Value::eValueTypeScalar - : Value::eValueTypeLoadAddress); + ? Value::ValueType::Scalar + : Value::ValueType::LoadAddress); break; case eAddressTypeHost: - m_value.SetValueType(Value::eValueTypeHostAddress); + m_value.SetValueType(Value::ValueType::HostAddress); break; case eAddressTypeInvalid: // TODO: does this make sense? - m_value.SetValueType(Value::eValueTypeScalar); + m_value.SetValueType(Value::ValueType::Scalar); break; } } switch (m_value.GetValueType()) { - case Value::eValueTypeLoadAddress: - case Value::eValueTypeFileAddress: - case Value::eValueTypeHostAddress: { + case Value::ValueType::Invalid: + break; + case Value::ValueType::LoadAddress: + case Value::ValueType::FileAddress: + case Value::ValueType::HostAddress: { lldb::addr_t addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); if (addr == LLDB_INVALID_ADDRESS) { m_error.SetErrorString("parent address is invalid."); @@ -182,7 +184,7 @@ bool ValueObjectChild::UpdateValue() { } } break; - case Value::eValueTypeScalar: + case Value::ValueType::Scalar: // try to extract the child value from the parent's scalar value { Scalar scalar(m_value.GetScalar()); diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectConstResult.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectConstResult.cpp index ceb4491f8666..174b9359d52d 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObjectConstResult.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObjectConstResult.cpp @@ -73,7 +73,7 @@ ValueObjectConstResult::ValueObjectConstResult( } m_value.GetScalar() = (uintptr_t)m_data.GetDataStart(); - m_value.SetValueType(Value::eValueTypeHostAddress); + m_value.SetValueType(Value::ValueType::HostAddress); m_value.SetCompilerType(compiler_type); m_name = name; SetIsConstant(); @@ -115,7 +115,7 @@ ValueObjectConstResult::ValueObjectConstResult( m_data.SetAddressByteSize(data_addr_size); m_data.SetData(data_sp); m_value.GetScalar() = (uintptr_t)data_sp->GetBytes(); - m_value.SetValueType(Value::eValueTypeHostAddress); + m_value.SetValueType(Value::ValueType::HostAddress); m_value.SetCompilerType(compiler_type); m_name = name; SetIsConstant(); @@ -145,19 +145,19 @@ ValueObjectConstResult::ValueObjectConstResult( m_value.GetScalar() = address; m_data.SetAddressByteSize(addr_byte_size); m_value.GetScalar().GetData(m_data, addr_byte_size); - // m_value.SetValueType(Value::eValueTypeHostAddress); + // m_value.SetValueType(Value::ValueType::HostAddress); switch (address_type) { case eAddressTypeInvalid: - m_value.SetValueType(Value::eValueTypeScalar); + m_value.SetValueType(Value::ValueType::Scalar); break; case eAddressTypeFile: - m_value.SetValueType(Value::eValueTypeFileAddress); + m_value.SetValueType(Value::ValueType::FileAddress); break; case eAddressTypeLoad: - m_value.SetValueType(Value::eValueTypeLoadAddress); + m_value.SetValueType(Value::ValueType::LoadAddress); break; case eAddressTypeHost: - m_value.SetValueType(Value::eValueTypeHostAddress); + m_value.SetValueType(Value::ValueType::HostAddress); break; } m_value.SetCompilerType(compiler_type); @@ -193,7 +193,7 @@ ValueObjectConstResult::ValueObjectConstResult(ExecutionContextScope *exe_scope, m_error = m_value.GetValueAsData(&exe_ctx, m_data, module); } -ValueObjectConstResult::~ValueObjectConstResult() {} +ValueObjectConstResult::~ValueObjectConstResult() = default; CompilerType ValueObjectConstResult::GetCompilerTypeImpl() { return m_value.GetCompilerType(); diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultCast.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultCast.cpp index 53ec9db45540..e70d055ac57c 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultCast.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultCast.cpp @@ -27,7 +27,7 @@ ValueObjectConstResultCast::ValueObjectConstResultCast( m_name = name; } -ValueObjectConstResultCast::~ValueObjectConstResultCast() {} +ValueObjectConstResultCast::~ValueObjectConstResultCast() = default; lldb::ValueObjectSP ValueObjectConstResultCast::Dereference(Status &error) { return m_impl.Dereference(error); diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultChild.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultChild.cpp index 13c8393d8081..0fd81410ae54 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultChild.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultChild.cpp @@ -34,7 +34,7 @@ ValueObjectConstResultChild::ValueObjectConstResultChild( m_name = name; } -ValueObjectConstResultChild::~ValueObjectConstResultChild() {} +ValueObjectConstResultChild::~ValueObjectConstResultChild() = default; lldb::ValueObjectSP ValueObjectConstResultChild::Dereference(Status &error) { return m_impl.Dereference(error); diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultImpl.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultImpl.cpp index e4cbbec849ec..980cea049f6f 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultImpl.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultImpl.cpp @@ -132,7 +132,7 @@ lldb::ValueObjectSP ValueObjectConstResultImpl::AddressOf(Status &error) { ConstString(new_name.c_str()), buffer, endian::InlHostByteOrder(), exe_ctx.GetAddressByteSize()); - m_address_of_backend->GetValue().SetValueType(Value::eValueTypeScalar); + m_address_of_backend->GetValue().SetValueType(Value::ValueType::Scalar); m_address_of_backend->GetValue().GetScalar() = m_live_address; return m_address_of_backend; diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectDynamicValue.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectDynamicValue.cpp index 1c25b8c85a05..d77509496509 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObjectDynamicValue.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObjectDynamicValue.cpp @@ -22,7 +22,7 @@ #include "lldb/Utility/Status.h" #include "lldb/lldb-types.h" -#include <string.h> +#include <cstring> namespace lldb_private { class Declaration; } diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectMemory.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectMemory.cpp index abf7b38ed89a..af039ee4040b 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObjectMemory.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObjectMemory.cpp @@ -18,7 +18,7 @@ #include "lldb/lldb-types.h" #include "llvm/Support/ErrorHandling.h" -#include <assert.h> +#include <cassert> #include <memory> namespace lldb_private { @@ -57,20 +57,20 @@ ValueObjectMemory::ValueObjectMemory(ExecutionContextScope *exe_scope, // Do not attempt to construct one of these objects with no variable! assert(m_type_sp.get() != nullptr); SetName(ConstString(name)); - m_value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get()); + m_value.SetContext(Value::ContextType::LLDBType, m_type_sp.get()); TargetSP target_sp(GetTargetSP()); lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get()); if (load_address != LLDB_INVALID_ADDRESS) { - m_value.SetValueType(Value::eValueTypeLoadAddress); + m_value.SetValueType(Value::ValueType::LoadAddress); m_value.GetScalar() = load_address; } else { lldb::addr_t file_address = m_address.GetFileAddress(); if (file_address != LLDB_INVALID_ADDRESS) { - m_value.SetValueType(Value::eValueTypeFileAddress); + m_value.SetValueType(Value::ValueType::FileAddress); m_value.GetScalar() = file_address; } else { m_value.GetScalar() = m_address.GetOffset(); - m_value.SetValueType(Value::eValueTypeScalar); + m_value.SetValueType(Value::ValueType::Scalar); } } } @@ -92,21 +92,21 @@ ValueObjectMemory::ValueObjectMemory(ExecutionContextScope *exe_scope, m_value.SetCompilerType(m_compiler_type); lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get()); if (load_address != LLDB_INVALID_ADDRESS) { - m_value.SetValueType(Value::eValueTypeLoadAddress); + m_value.SetValueType(Value::ValueType::LoadAddress); m_value.GetScalar() = load_address; } else { lldb::addr_t file_address = m_address.GetFileAddress(); if (file_address != LLDB_INVALID_ADDRESS) { - m_value.SetValueType(Value::eValueTypeFileAddress); + m_value.SetValueType(Value::ValueType::FileAddress); m_value.GetScalar() = file_address; } else { m_value.GetScalar() = m_address.GetOffset(); - m_value.SetValueType(Value::eValueTypeScalar); + m_value.SetValueType(Value::ValueType::Scalar); } } } -ValueObjectMemory::~ValueObjectMemory() {} +ValueObjectMemory::~ValueObjectMemory() = default; CompilerType ValueObjectMemory::GetCompilerTypeImpl() { if (m_type_sp) @@ -168,15 +168,18 @@ bool ValueObjectMemory::UpdateValue() { Value::ValueType value_type = m_value.GetValueType(); switch (value_type) { - case Value::eValueTypeScalar: + case Value::ValueType::Invalid: + m_error.SetErrorString("Invalid value"); + return false; + case Value::ValueType::Scalar: // The variable value is in the Scalar value inside the m_value. We can // point our m_data right to it. m_error = m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get()); break; - case Value::eValueTypeFileAddress: - case Value::eValueTypeLoadAddress: - case Value::eValueTypeHostAddress: + case Value::ValueType::FileAddress: + case Value::ValueType::LoadAddress: + case Value::ValueType::HostAddress: // The DWARF expression result was an address in the inferior process. If // this variable is an aggregate type, we just need the address as the // main value as all child variable objects will rely upon this location @@ -185,11 +188,11 @@ bool ValueObjectMemory::UpdateValue() { // sure this type has a value before we try and read it // If we have a file address, convert it to a load address if we can. - if (value_type == Value::eValueTypeFileAddress && + if (value_type == Value::ValueType::FileAddress && exe_ctx.GetProcessPtr()) { lldb::addr_t load_addr = m_address.GetLoadAddress(target); if (load_addr != LLDB_INVALID_ADDRESS) { - m_value.SetValueType(Value::eValueTypeLoadAddress); + m_value.SetValueType(Value::ValueType::LoadAddress); m_value.GetScalar() = load_addr; } } @@ -205,7 +208,7 @@ bool ValueObjectMemory::UpdateValue() { // extract read its value into m_data appropriately Value value(m_value); if (m_type_sp) - value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get()); + value.SetContext(Value::ContextType::LLDBType, m_type_sp.get()); else { value.SetCompilerType(m_compiler_type); } diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectRegister.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectRegister.cpp index 27461e9cebc4..089fd7667080 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObjectRegister.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObjectRegister.cpp @@ -25,7 +25,7 @@ #include "llvm/ADT/StringRef.h" -#include <assert.h> +#include <cassert> #include <memory> namespace lldb_private { @@ -60,7 +60,7 @@ ValueObjectRegisterSet::ValueObjectRegisterSet(ExecutionContextScope *exe_scope, } } -ValueObjectRegisterSet::~ValueObjectRegisterSet() {} +ValueObjectRegisterSet::~ValueObjectRegisterSet() = default; CompilerType ValueObjectRegisterSet::GetCompilerTypeImpl() { return CompilerType(); @@ -193,7 +193,7 @@ ValueObjectRegister::ValueObjectRegister(ExecutionContextScope *exe_scope, ConstructObject(reg_num); } -ValueObjectRegister::~ValueObjectRegister() {} +ValueObjectRegister::~ValueObjectRegister() = default; CompilerType ValueObjectRegister::GetCompilerTypeImpl() { if (!m_compiler_type.IsValid()) { @@ -249,9 +249,9 @@ bool ValueObjectRegister::UpdateValue() { Process *process = exe_ctx.GetProcessPtr(); if (process) m_data.SetAddressByteSize(process->GetAddressByteSize()); - m_value.SetContext(Value::eContextTypeRegisterInfo, + m_value.SetContext(Value::ContextType::RegisterInfo, (void *)&m_reg_info); - m_value.SetValueType(Value::eValueTypeHostAddress); + m_value.SetValueType(Value::ValueType::HostAddress); m_value.GetScalar() = (uintptr_t)m_data.GetDataStart(); SetValueIsValid(true); SetValueDidChange(!(m_old_reg_value == m_reg_value)); diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectSyntheticFilter.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectSyntheticFilter.cpp index cebf7abfe523..aa55e3965706 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObjectSyntheticFilter.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObjectSyntheticFilter.cpp @@ -190,7 +190,7 @@ bool ValueObjectSynthetic::UpdateValue() { // children count for a synthetic VO that might indeed happen, so we need // to tell the upper echelons that they need to come back to us asking for // children - m_children_count_valid = false; + m_flags.m_children_count_valid = false; { std::lock_guard<std::mutex> guard(m_child_mutex); m_synthetic_children_cache.clear(); diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectUpdater.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectUpdater.cpp new file mode 100644 index 000000000000..af7f976a6d27 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Core/ValueObjectUpdater.cpp @@ -0,0 +1,56 @@ +//===-- ValueObjectUpdater.cpp --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/ValueObjectUpdater.h" + +using namespace lldb_private; + +ValueObjectUpdater::ValueObjectUpdater(lldb::ValueObjectSP in_valobj_sp) { + if (!in_valobj_sp) + return; + // If the user passes in a value object that is dynamic or synthetic, then + // water it down to the static type. + m_root_valobj_sp = in_valobj_sp->GetQualifiedRepresentationIfAvailable( + lldb::eNoDynamicValues, false); +} + +lldb::ValueObjectSP ValueObjectUpdater::GetSP() { + lldb::ProcessSP process_sp = GetProcessSP(); + if (!process_sp) + return lldb::ValueObjectSP(); + + const uint32_t current_stop_id = process_sp->GetLastNaturalStopID(); + if (current_stop_id == m_stop_id) + return m_user_valobj_sp; + + m_stop_id = current_stop_id; + + if (!m_root_valobj_sp) { + m_user_valobj_sp.reset(); + return m_root_valobj_sp; + } + + m_user_valobj_sp = m_root_valobj_sp; + + lldb::ValueObjectSP dynamic_sp = + m_user_valobj_sp->GetDynamicValue(lldb::eDynamicDontRunTarget); + if (dynamic_sp) + m_user_valobj_sp = dynamic_sp; + + lldb::ValueObjectSP synthetic_sp = m_user_valobj_sp->GetSyntheticValue(); + if (synthetic_sp) + m_user_valobj_sp = synthetic_sp; + + return m_user_valobj_sp; +} + +lldb::ProcessSP ValueObjectUpdater::GetProcessSP() const { + if (m_root_valobj_sp) + return m_root_valobj_sp->GetProcessSP(); + return lldb::ProcessSP(); +} diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectVariable.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectVariable.cpp index 5acb23aaac5b..8e89503a8a76 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObjectVariable.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObjectVariable.cpp @@ -10,10 +10,10 @@ #include "lldb/Core/Address.h" #include "lldb/Core/AddressRange.h" +#include "lldb/Core/Declaration.h" #include "lldb/Core/Module.h" #include "lldb/Core/Value.h" #include "lldb/Expression/DWARFExpression.h" -#include "lldb/Symbol/Declaration.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolContext.h" @@ -33,7 +33,7 @@ #include "llvm/ADT/StringRef.h" -#include <assert.h> +#include <cassert> #include <memory> namespace lldb_private { @@ -63,7 +63,7 @@ ValueObjectVariable::ValueObjectVariable(ExecutionContextScope *exe_scope, m_name = var_sp->GetName(); } -ValueObjectVariable::~ValueObjectVariable() {} +ValueObjectVariable::~ValueObjectVariable() = default; CompilerType ValueObjectVariable::GetCompilerTypeImpl() { Type *var_type = m_variable_sp->GetType(); @@ -135,12 +135,12 @@ bool ValueObjectVariable::UpdateValue() { if (expr.GetExpressionData(m_data)) { if (m_data.GetDataStart() && m_data.GetByteSize()) m_value.SetBytes(m_data.GetDataStart(), m_data.GetByteSize()); - m_value.SetContext(Value::eContextTypeVariable, variable); + m_value.SetContext(Value::ContextType::Variable, variable); } else m_error.SetErrorString("empty constant data"); // constant bytes can't be edited - sorry - m_resolved_value.SetContext(Value::eContextTypeInvalid, nullptr); + m_resolved_value.SetContext(Value::ContextType::Invalid, nullptr); } else { lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS; ExecutionContext exe_ctx(GetExecutionContextRef()); @@ -163,7 +163,7 @@ bool ValueObjectVariable::UpdateValue() { if (expr.Evaluate(&exe_ctx, nullptr, loclist_base_load_addr, nullptr, nullptr, m_value, &m_error)) { m_resolved_value = m_value; - m_value.SetContext(Value::eContextTypeVariable, variable); + m_value.SetContext(Value::ContextType::Variable, variable); CompilerType compiler_type = GetCompilerType(); if (compiler_type.IsValid()) @@ -183,7 +183,7 @@ bool ValueObjectVariable::UpdateValue() { // // FIXME: When we grow m_value, we should represent the added bits as // undefined somehow instead of as 0's. - if (value_type == Value::eValueTypeHostAddress && + if (value_type == Value::ValueType::HostAddress && compiler_type.IsValid()) { if (size_t value_buf_size = m_value.GetBuffer().GetByteSize()) { size_t value_size = m_value.GetValueByteSize(&m_error, &exe_ctx); @@ -196,16 +196,19 @@ bool ValueObjectVariable::UpdateValue() { const bool process_is_alive = process && process->IsAlive(); switch (value_type) { - case Value::eValueTypeScalar: + case Value::ValueType::Invalid: + m_error.SetErrorString("invalid value"); + break; + case Value::ValueType::Scalar: // The variable value is in the Scalar value inside the m_value. We can // point our m_data right to it. m_error = m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get()); break; - case Value::eValueTypeFileAddress: - case Value::eValueTypeLoadAddress: - case Value::eValueTypeHostAddress: + case Value::ValueType::FileAddress: + case Value::ValueType::LoadAddress: + case Value::ValueType::HostAddress: // The DWARF expression result was an address in the inferior process. // If this variable is an aggregate type, we just need the address as // the main value as all child variable objects will rely upon this @@ -214,7 +217,7 @@ bool ValueObjectVariable::UpdateValue() { // m_data. Make sure this type has a value before we try and read it // If we have a file address, convert it to a load address if we can. - if (value_type == Value::eValueTypeFileAddress && process_is_alive) + if (value_type == Value::ValueType::FileAddress && process_is_alive) m_value.ConvertToLoadAddress(GetModule().get(), target); if (!CanProvideValue()) { @@ -227,7 +230,7 @@ bool ValueObjectVariable::UpdateValue() { // Copy the Value and set the context to use our Variable so it can // extract read its value into m_data appropriately Value value(m_value); - value.SetContext(Value::eContextTypeVariable, variable); + value.SetContext(Value::ContextType::Variable, variable); m_error = value.GetValueAsData(&exe_ctx, m_data, GetModule().get()); @@ -240,7 +243,7 @@ bool ValueObjectVariable::UpdateValue() { SetValueIsValid(m_error.Success()); } else { // could not find location, won't allow editing - m_resolved_value.SetContext(Value::eContextTypeInvalid, nullptr); + m_resolved_value.SetContext(Value::ContextType::Invalid, nullptr); } } @@ -257,7 +260,9 @@ void ValueObjectVariable::DoUpdateChildrenAddressType(ValueObject &valobj) { (type_info & (lldb::eTypeIsPointer | lldb::eTypeIsReference)) != 0; switch (value_type) { - case Value::eValueTypeFileAddress: + case Value::ValueType::Invalid: + break; + case Value::ValueType::FileAddress: // If this type is a pointer, then its children will be considered load // addresses if the pointer or reference is dereferenced, but only if // the process is alive. @@ -280,7 +285,7 @@ void ValueObjectVariable::DoUpdateChildrenAddressType(ValueObject &valobj) { else valobj.SetAddressTypeOfChildren(eAddressTypeFile); break; - case Value::eValueTypeHostAddress: + case Value::ValueType::HostAddress: // Same as above for load addresses, except children of pointer or refs // are always load addresses. Host addresses are used to store freeze // dried variables. If this type is a struct, the entire struct @@ -291,8 +296,8 @@ void ValueObjectVariable::DoUpdateChildrenAddressType(ValueObject &valobj) { else valobj.SetAddressTypeOfChildren(eAddressTypeHost); break; - case Value::eValueTypeLoadAddress: - case Value::eValueTypeScalar: + case Value::ValueType::LoadAddress: + case Value::ValueType::Scalar: valobj.SetAddressTypeOfChildren(eAddressTypeLoad); break; } @@ -343,7 +348,7 @@ bool ValueObjectVariable::GetDeclaration(Declaration &decl) { } const char *ValueObjectVariable::GetLocationAsCString() { - if (m_resolved_value.GetContextType() == Value::eContextTypeRegisterInfo) + if (m_resolved_value.GetContextType() == Value::ContextType::RegisterInfo) return GetLocationAsCStringImpl(m_resolved_value, m_data); else return ValueObject::GetLocationAsCString(); @@ -356,7 +361,7 @@ bool ValueObjectVariable::SetValueFromCString(const char *value_str, return false; } - if (m_resolved_value.GetContextType() == Value::eContextTypeRegisterInfo) { + if (m_resolved_value.GetContextType() == Value::ContextType::RegisterInfo) { RegisterInfo *reg_info = m_resolved_value.GetRegisterInfo(); ExecutionContext exe_ctx(GetExecutionContextRef()); RegisterContext *reg_ctx = exe_ctx.GetRegisterContext(); @@ -385,7 +390,7 @@ bool ValueObjectVariable::SetData(DataExtractor &data, Status &error) { return false; } - if (m_resolved_value.GetContextType() == Value::eContextTypeRegisterInfo) { + if (m_resolved_value.GetContextType() == Value::ContextType::RegisterInfo) { RegisterInfo *reg_info = m_resolved_value.GetRegisterInfo(); ExecutionContext exe_ctx(GetExecutionContextRef()); RegisterContext *reg_ctx = exe_ctx.GetRegisterContext(); diff --git a/contrib/llvm-project/lldb/source/DataFormatters/StringPrinter.cpp b/contrib/llvm-project/lldb/source/DataFormatters/StringPrinter.cpp index 139f1ec0554f..0c6438f7dd86 100644 --- a/contrib/llvm-project/lldb/source/DataFormatters/StringPrinter.cpp +++ b/contrib/llvm-project/lldb/source/DataFormatters/StringPrinter.cpp @@ -18,7 +18,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/Support/ConvertUTF.h" -#include <ctype.h> +#include <cctype> #include <locale> #include <memory> diff --git a/contrib/llvm-project/lldb/source/DataFormatters/TypeFormat.cpp b/contrib/llvm-project/lldb/source/DataFormatters/TypeFormat.cpp index b9a9447c5f3e..9c5046687013 100644 --- a/contrib/llvm-project/lldb/source/DataFormatters/TypeFormat.cpp +++ b/contrib/llvm-project/lldb/source/DataFormatters/TypeFormat.cpp @@ -27,16 +27,15 @@ using namespace lldb; using namespace lldb_private; -TypeFormatImpl::TypeFormatImpl(const Flags &flags) - : m_flags(flags), m_my_revision(0) {} +TypeFormatImpl::TypeFormatImpl(const Flags &flags) : m_flags(flags) {} -TypeFormatImpl::~TypeFormatImpl() {} +TypeFormatImpl::~TypeFormatImpl() = default; TypeFormatImpl_Format::TypeFormatImpl_Format(lldb::Format f, const TypeFormatImpl::Flags &flags) : TypeFormatImpl(flags), m_format(f) {} -TypeFormatImpl_Format::~TypeFormatImpl_Format() {} +TypeFormatImpl_Format::~TypeFormatImpl_Format() = default; bool TypeFormatImpl_Format::FormatObject(ValueObject *valobj, std::string &dest) const { @@ -48,7 +47,7 @@ bool TypeFormatImpl_Format::FormatObject(ValueObject *valobj, ExecutionContext exe_ctx(valobj->GetExecutionContextRef()); DataExtractor data; - if (context_type == Value::eContextTypeRegisterInfo) { + if (context_type == Value::ContextType::RegisterInfo) { const RegisterInfo *reg_info = value.GetRegisterInfo(); if (reg_info) { Status error; @@ -135,7 +134,7 @@ TypeFormatImpl_EnumType::TypeFormatImpl_EnumType( ConstString type_name, const TypeFormatImpl::Flags &flags) : TypeFormatImpl(flags), m_enum_type(type_name), m_types() {} -TypeFormatImpl_EnumType::~TypeFormatImpl_EnumType() {} +TypeFormatImpl_EnumType::~TypeFormatImpl_EnumType() = default; bool TypeFormatImpl_EnumType::FormatObject(ValueObject *valobj, std::string &dest) const { diff --git a/contrib/llvm-project/lldb/source/DataFormatters/TypeSummary.cpp b/contrib/llvm-project/lldb/source/DataFormatters/TypeSummary.cpp index 5d4fe2e467f8..c09ed31d0338 100644 --- a/contrib/llvm-project/lldb/source/DataFormatters/TypeSummary.cpp +++ b/contrib/llvm-project/lldb/source/DataFormatters/TypeSummary.cpp @@ -26,8 +26,7 @@ using namespace lldb; using namespace lldb_private; -TypeSummaryOptions::TypeSummaryOptions() - : m_lang(eLanguageTypeUnknown), m_capping(eTypeSummaryCapped) {} +TypeSummaryOptions::TypeSummaryOptions() = default; lldb::LanguageType TypeSummaryOptions::GetLanguage() const { return m_lang; } diff --git a/contrib/llvm-project/lldb/source/DataFormatters/TypeSynthetic.cpp b/contrib/llvm-project/lldb/source/DataFormatters/TypeSynthetic.cpp index 75388a93cc64..2cca5d65f470 100644 --- a/contrib/llvm-project/lldb/source/DataFormatters/TypeSynthetic.cpp +++ b/contrib/llvm-project/lldb/source/DataFormatters/TypeSynthetic.cpp @@ -128,7 +128,7 @@ ScriptedSyntheticChildren::FrontEnd::FrontEnd(std::string pclass, ValueObject &backend) : SyntheticChildrenFrontEnd(backend), m_python_class(pclass), m_wrapper_sp(), m_interpreter(nullptr) { - if (backend == LLDB_INVALID_UID) + if (backend.GetID() == LLDB_INVALID_UID) return; TargetSP target_sp = backend.GetTargetSP(); @@ -143,7 +143,7 @@ ScriptedSyntheticChildren::FrontEnd::FrontEnd(std::string pclass, m_python_class.c_str(), backend.GetSP()); } -ScriptedSyntheticChildren::FrontEnd::~FrontEnd() {} +ScriptedSyntheticChildren::FrontEnd::~FrontEnd() = default; lldb::ValueObjectSP ScriptedSyntheticChildren::FrontEnd::GetChildAtIndex(size_t idx) { diff --git a/contrib/llvm-project/lldb/source/DataFormatters/VectorType.cpp b/contrib/llvm-project/lldb/source/DataFormatters/VectorType.cpp index cc24bb1de428..11371918830b 100644 --- a/contrib/llvm-project/lldb/source/DataFormatters/VectorType.cpp +++ b/contrib/llvm-project/lldb/source/DataFormatters/VectorType.cpp @@ -219,7 +219,7 @@ public: m_parent_format = m_backend.GetFormat(); CompilerType parent_type(m_backend.GetCompilerType()); CompilerType element_type; - parent_type.IsVectorType(&element_type, nullptr); + parent_type.IsVectorType(&element_type); m_child_type = ::GetCompilerTypeForFormat(m_parent_format, element_type, parent_type.GetTypeSystem()); m_num_children = ::CalculateNumChildren(parent_type, m_child_type); diff --git a/contrib/llvm-project/lldb/source/Expression/DWARFExpression.cpp b/contrib/llvm-project/lldb/source/Expression/DWARFExpression.cpp index c30fdf565cd5..a10546c1deae 100644 --- a/contrib/llvm-project/lldb/source/Expression/DWARFExpression.cpp +++ b/contrib/llvm-project/lldb/source/Expression/DWARFExpression.cpp @@ -8,7 +8,7 @@ #include "lldb/Expression/DWARFExpression.h" -#include <inttypes.h> +#include <cinttypes> #include <vector> @@ -55,9 +55,7 @@ ReadAddressFromDebugAddrSection(const DWARFUnit *dwarf_cu, } // DWARFExpression constructor -DWARFExpression::DWARFExpression() - : m_module_wp(), m_data(), m_dwarf_cu(nullptr), - m_reg_kind(eRegisterKindDWARF) {} +DWARFExpression::DWARFExpression() : m_module_wp(), m_data() {} DWARFExpression::DWARFExpression(lldb::ModuleSP module_sp, const DataExtractor &data, @@ -69,7 +67,7 @@ DWARFExpression::DWARFExpression(lldb::ModuleSP module_sp, } // Destructor -DWARFExpression::~DWARFExpression() {} +DWARFExpression::~DWARFExpression() = default; bool DWARFExpression::IsValid() const { return m_data.GetByteSize() > 0; } @@ -174,8 +172,8 @@ static bool ReadRegisterValueAsScalar(RegisterContext *reg_ctx, RegisterValue reg_value; if (reg_ctx->ReadRegister(reg_info, reg_value)) { if (reg_value.GetScalarValue(value.GetScalar())) { - value.SetValueType(Value::eValueTypeScalar); - value.SetContext(Value::eContextTypeRegisterInfo, + value.SetValueType(Value::ValueType::Scalar); + value.SetContext(Value::ContextType::RegisterInfo, const_cast<RegisterInfo *>(reg_info)); if (error_ptr) error_ptr->Clear(); @@ -904,6 +902,52 @@ bool DWARFExpression::Evaluate(ExecutionContext *exe_ctx, object_address_ptr, result, error_ptr); } +namespace { +/// The location description kinds described by the DWARF v5 +/// specification. Composite locations are handled out-of-band and +/// thus aren't part of the enum. +enum LocationDescriptionKind { + Empty, + Memory, + Register, + Implicit + /* Composite*/ +}; +/// Adjust value's ValueType according to the kind of location description. +void UpdateValueTypeFromLocationDescription(Log *log, const DWARFUnit *dwarf_cu, + LocationDescriptionKind kind, + Value *value = nullptr) { + // Note that this function is conflating DWARF expressions with + // DWARF location descriptions. Perhaps it would be better to define + // a wrapper for DWARFExpresssion::Eval() that deals with DWARF + // location descriptions (which consist of one or more DWARF + // expressions). But doing this would mean we'd also need factor the + // handling of DW_OP_(bit_)piece out of this function. + if (dwarf_cu && dwarf_cu->GetVersion() >= 4) { + const char *log_msg = "DWARF location description kind: %s"; + switch (kind) { + case Empty: + LLDB_LOGF(log, log_msg, "Empty"); + break; + case Memory: + LLDB_LOGF(log, log_msg, "Memory"); + if (value->GetValueType() == Value::ValueType::Scalar) + value->SetValueType(Value::ValueType::LoadAddress); + break; + case Register: + LLDB_LOGF(log, log_msg, "Register"); + value->SetValueType(Value::ValueType::Scalar); + break; + case Implicit: + LLDB_LOGF(log, log_msg, "Implicit"); + if (value->GetValueType() == Value::ValueType::LoadAddress) + value->SetValueType(Value::ValueType::Scalar); + break; + } + } +} +} // namespace + bool DWARFExpression::Evaluate( ExecutionContext *exe_ctx, RegisterContext *reg_ctx, lldb::ModuleSP module_sp, const DataExtractor &opcodes, @@ -952,6 +996,11 @@ bool DWARFExpression::Evaluate( !is_signed)); }; + // The default kind is a memory location. This is updated by any + // operation that changes this, such as DW_OP_stack_value, and reset + // by composition operations like DW_OP_piece. + LocationDescriptionKind dwarf4_location_description_kind = Memory; + while (opcodes.ValidOffset(offset)) { const lldb::offset_t op_offset = offset; const uint8_t op = opcodes.GetU8(&offset); @@ -975,7 +1024,7 @@ bool DWARFExpression::Evaluate( // address and whose size is the size of an address on the target machine. case DW_OP_addr: stack.push_back(Scalar(opcodes.GetAddress(&offset))); - stack.back().SetValueType(Value::eValueTypeFileAddress); + stack.back().SetValueType(Value::ValueType::FileAddress); // Convert the file address to a load address, so subsequent // DWARF operators can operate on it. if (frame) @@ -1034,14 +1083,14 @@ bool DWARFExpression::Evaluate( } Value::ValueType value_type = stack.back().GetValueType(); switch (value_type) { - case Value::eValueTypeHostAddress: { + case Value::ValueType::HostAddress: { void *src = (void *)stack.back().GetScalar().ULongLong(); intptr_t ptr; ::memcpy(&ptr, src, sizeof(void *)); stack.back().GetScalar() = ptr; stack.back().ClearContext(); } break; - case Value::eValueTypeFileAddress: { + case Value::ValueType::FileAddress: { auto file_addr = stack.back().GetScalar().ULongLong( LLDB_INVALID_ADDRESS); if (!module_sp) { @@ -1064,10 +1113,13 @@ bool DWARFExpression::Evaluate( return false; } stack.back().GetScalar() = load_Addr; - stack.back().SetValueType(Value::eValueTypeLoadAddress); - // Fall through to load address code below... + // Fall through to load address promotion code below. } LLVM_FALLTHROUGH; - case Value::eValueTypeLoadAddress: + case Value::ValueType::Scalar: + // Promote Scalar to LoadAddress and fall through. + stack.back().SetValueType(Value::ValueType::LoadAddress); + LLVM_FALLTHROUGH; + case Value::ValueType::LoadAddress: if (exe_ctx) { if (process) { lldb::addr_t pointer_addr = @@ -1076,6 +1128,8 @@ bool DWARFExpression::Evaluate( lldb::addr_t pointer_value = process->ReadPointerFromMemory(pointer_addr, error); if (pointer_value != LLDB_INVALID_ADDRESS) { + if (ABISP abi_sp = process->GetABI()) + pointer_value = abi_sp->FixCodeAddress(pointer_value); stack.back().GetScalar() = pointer_value; stack.back().ClearContext(); } else { @@ -1099,8 +1153,10 @@ bool DWARFExpression::Evaluate( } break; - default: - break; + case Value::ValueType::Invalid: + if (error_ptr) + error_ptr->SetErrorString("Invalid value type for DW_OP_deref.\n"); + return false; } } break; @@ -1127,7 +1183,7 @@ bool DWARFExpression::Evaluate( uint8_t size = opcodes.GetU8(&offset); Value::ValueType value_type = stack.back().GetValueType(); switch (value_type) { - case Value::eValueTypeHostAddress: { + case Value::ValueType::HostAddress: { void *src = (void *)stack.back().GetScalar().ULongLong(); intptr_t ptr; ::memcpy(&ptr, src, sizeof(void *)); @@ -1167,7 +1223,8 @@ bool DWARFExpression::Evaluate( stack.back().GetScalar() = ptr; stack.back().ClearContext(); } break; - case Value::eValueTypeLoadAddress: + case Value::ValueType::Scalar: + case Value::ValueType::LoadAddress: if (exe_ctx) { if (process) { lldb::addr_t pointer_addr = @@ -1207,19 +1264,22 @@ bool DWARFExpression::Evaluate( } } else { if (error_ptr) - error_ptr->SetErrorString("NULL process for DW_OP_deref.\n"); + error_ptr->SetErrorString("NULL process for DW_OP_deref_size.\n"); return false; } } else { if (error_ptr) error_ptr->SetErrorString( - "NULL execution context for DW_OP_deref.\n"); + "NULL execution context for DW_OP_deref_size.\n"); return false; } break; - default: - break; + case Value::ValueType::FileAddress: + case Value::ValueType::Invalid: + if (error_ptr) + error_ptr->SetErrorString("Invalid value for DW_OP_deref_size.\n"); + return false; } } break; @@ -1941,6 +2001,7 @@ bool DWARFExpression::Evaluate( case DW_OP_reg29: case DW_OP_reg30: case DW_OP_reg31: { + dwarf4_location_description_kind = Register; reg_num = op - DW_OP_reg0; if (ReadRegisterValueAsScalar(reg_ctx, reg_kind, reg_num, error_ptr, tmp)) @@ -1953,6 +2014,7 @@ bool DWARFExpression::Evaluate( // ULEB128 literal operand that encodes the register. // DESCRIPTION: Push the value in register on the top of the stack. case DW_OP_regx: { + dwarf4_location_description_kind = Register; reg_num = opcodes.GetULEB128(&offset); if (ReadRegisterValueAsScalar(reg_ctx, reg_kind, reg_num, error_ptr, tmp)) stack.push_back(tmp); @@ -2005,7 +2067,7 @@ bool DWARFExpression::Evaluate( tmp.ResolveValue(exe_ctx) += (uint64_t)breg_offset; tmp.ClearContext(); stack.push_back(tmp); - stack.back().SetValueType(Value::eValueTypeLoadAddress); + stack.back().SetValueType(Value::ValueType::LoadAddress); } else return false; } break; @@ -2024,7 +2086,7 @@ bool DWARFExpression::Evaluate( tmp.ResolveValue(exe_ctx) += (uint64_t)breg_offset; tmp.ClearContext(); stack.push_back(tmp); - stack.back().SetValueType(Value::eValueTypeLoadAddress); + stack.back().SetValueType(Value::ValueType::LoadAddress); } else return false; } break; @@ -2037,7 +2099,7 @@ bool DWARFExpression::Evaluate( int64_t fbreg_offset = opcodes.GetSLEB128(&offset); value += fbreg_offset; stack.push_back(value); - stack.back().SetValueType(Value::eValueTypeLoadAddress); + stack.back().SetValueType(Value::ValueType::LoadAddress); } else return false; } else { @@ -2076,12 +2138,18 @@ bool DWARFExpression::Evaluate( // provides a way of describing how large a part of a variable a particular // DWARF expression refers to. case DW_OP_piece: { + LocationDescriptionKind piece_locdesc = dwarf4_location_description_kind; + // Reset for the next piece. + dwarf4_location_description_kind = Memory; + const uint64_t piece_byte_size = opcodes.GetULEB128(&offset); if (piece_byte_size > 0) { Value curr_piece; if (stack.empty()) { + UpdateValueTypeFromLocationDescription( + log, dwarf_cu, LocationDescriptionKind::Empty); // In a multi-piece expression, this means that the current piece is // not available. Fill with zeros for now by resizing the data and // appending it @@ -2097,11 +2165,15 @@ bool DWARFExpression::Evaluate( // Extract the current piece into "curr_piece" Value curr_piece_source_value(stack.back()); stack.pop_back(); + UpdateValueTypeFromLocationDescription(log, dwarf_cu, piece_locdesc, + &curr_piece_source_value); const Value::ValueType curr_piece_source_value_type = curr_piece_source_value.GetValueType(); switch (curr_piece_source_value_type) { - case Value::eValueTypeLoadAddress: + case Value::ValueType::Invalid: + return false; + case Value::ValueType::LoadAddress: if (process) { if (curr_piece.ResizeData(piece_byte_size) == piece_byte_size) { lldb::addr_t load_addr = @@ -2128,8 +2200,8 @@ bool DWARFExpression::Evaluate( } break; - case Value::eValueTypeFileAddress: - case Value::eValueTypeHostAddress: + case Value::ValueType::FileAddress: + case Value::ValueType::HostAddress: if (error_ptr) { lldb::addr_t addr = curr_piece_source_value.GetScalar().ULongLong( LLDB_INVALID_ADDRESS); @@ -2137,14 +2209,14 @@ bool DWARFExpression::Evaluate( "failed to read memory DW_OP_piece(%" PRIu64 ") from %s address 0x%" PRIx64, piece_byte_size, curr_piece_source_value.GetValueType() == - Value::eValueTypeFileAddress + Value::ValueType::FileAddress ? "file" : "host", addr); } return false; - case Value::eValueTypeScalar: { + case Value::ValueType::Scalar: { uint32_t bit_size = piece_byte_size * 8; uint32_t bit_offset = 0; Scalar &scalar = curr_piece_source_value.GetScalar(); @@ -2205,15 +2277,25 @@ bool DWARFExpression::Evaluate( case DW_OP_bit_piece: // 0x9d ULEB128 bit size, ULEB128 bit offset (DWARF3); if (stack.size() < 1) { + UpdateValueTypeFromLocationDescription(log, dwarf_cu, + LocationDescriptionKind::Empty); + // Reset for the next piece. + dwarf4_location_description_kind = Memory; if (error_ptr) error_ptr->SetErrorString( "Expression stack needs at least 1 item for DW_OP_bit_piece."); return false; } else { + UpdateValueTypeFromLocationDescription( + log, dwarf_cu, dwarf4_location_description_kind, &stack.back()); + // Reset for the next piece. + dwarf4_location_description_kind = Memory; const uint64_t piece_bit_size = opcodes.GetULEB128(&offset); const uint64_t piece_bit_offset = opcodes.GetULEB128(&offset); switch (stack.back().GetValueType()) { - case Value::eValueTypeScalar: { + case Value::ValueType::Invalid: + return false; + case Value::ValueType::Scalar: { if (!stack.back().GetScalar().ExtractBitfield(piece_bit_size, piece_bit_offset)) { if (error_ptr) @@ -2226,9 +2308,9 @@ bool DWARFExpression::Evaluate( } } break; - case Value::eValueTypeFileAddress: - case Value::eValueTypeLoadAddress: - case Value::eValueTypeHostAddress: + case Value::ValueType::FileAddress: + case Value::ValueType::LoadAddress: + case Value::ValueType::HostAddress: if (error_ptr) { error_ptr->SetErrorStringWithFormat( "unable to extract DW_OP_bit_piece(bit_size = %" PRIu64 @@ -2248,6 +2330,8 @@ bool DWARFExpression::Evaluate( // DESCRIPTION: Value is immediately stored in block in the debug info with // the memory representation of the target. case DW_OP_implicit_value: { + dwarf4_location_description_kind = Implicit; + const uint32_t len = opcodes.GetULEB128(&offset); const void *data = opcodes.GetData(&offset, len); @@ -2263,6 +2347,12 @@ bool DWARFExpression::Evaluate( break; } + case DW_OP_implicit_pointer: { + dwarf4_location_description_kind = Implicit; + LLDB_ERRORF(error_ptr, "Could not evaluate %s.", DW_OP_value_to_name(op)); + return false; + } + // OPCODE: DW_OP_push_object_address // OPERANDS: none // DESCRIPTION: Pushes the address of the object currently being @@ -2334,13 +2424,14 @@ bool DWARFExpression::Evaluate( // rather is a constant value. The value from the top of the stack is the // value to be used. This is the actual object value and not the location. case DW_OP_stack_value: + dwarf4_location_description_kind = Implicit; if (stack.empty()) { if (error_ptr) error_ptr->SetErrorString( "Expression stack needs at least 1 item for DW_OP_stack_value."); return false; } - stack.back().SetValueType(Value::eValueTypeScalar); + stack.back().SetValueType(Value::ValueType::Scalar); break; // OPCODE: DW_OP_convert @@ -2428,7 +2519,7 @@ bool DWARFExpression::Evaluate( addr_t cfa = id.GetCallFrameAddress(); if (cfa != LLDB_INVALID_ADDRESS) { stack.push_back(Scalar(cfa)); - stack.back().SetValueType(Value::eValueTypeLoadAddress); + stack.back().SetValueType(Value::ValueType::LoadAddress); } else if (error_ptr) error_ptr->SetErrorString("Stack frame does not include a canonical " "frame address for DW_OP_call_frame_cfa " @@ -2488,7 +2579,7 @@ bool DWARFExpression::Evaluate( } stack.back().GetScalar() = tls_load_addr; - stack.back().SetValueType(Value::eValueTypeLoadAddress); + stack.back().SetValueType(Value::ValueType::LoadAddress); } break; // OPCODE: DW_OP_addrx (DW_OP_GNU_addr_index is the legacy name.) @@ -2508,7 +2599,7 @@ bool DWARFExpression::Evaluate( uint64_t index = opcodes.GetULEB128(&offset); lldb::addr_t value = ReadAddressFromDebugAddrSection(dwarf_cu, index); stack.push_back(Scalar(value)); - stack.back().SetValueType(Value::eValueTypeFileAddress); + stack.back().SetValueType(Value::ValueType::FileAddress); } break; // OPCODE: DW_OP_GNU_const_index @@ -2554,25 +2645,28 @@ bool DWARFExpression::Evaluate( // or DW_OP_bit_piece opcodes if (pieces.GetBuffer().GetByteSize()) { result = pieces; - } else { - if (error_ptr) - error_ptr->SetErrorString("Stack empty after evaluation."); - return false; + return true; } - } else { - if (log && log->GetVerbose()) { - size_t count = stack.size(); - LLDB_LOGF(log, "Stack after operation has %" PRIu64 " values:", - (uint64_t)count); - for (size_t i = 0; i < count; ++i) { - StreamString new_value; - new_value.Printf("[%" PRIu64 "]", (uint64_t)i); - stack[i].Dump(&new_value); - LLDB_LOGF(log, " %s", new_value.GetData()); - } + if (error_ptr) + error_ptr->SetErrorString("Stack empty after evaluation."); + return false; + } + + UpdateValueTypeFromLocationDescription( + log, dwarf_cu, dwarf4_location_description_kind, &stack.back()); + + if (log && log->GetVerbose()) { + size_t count = stack.size(); + LLDB_LOGF(log, + "Stack after operation has %" PRIu64 " values:", (uint64_t)count); + for (size_t i = 0; i < count; ++i) { + StreamString new_value; + new_value.Printf("[%" PRIu64 "]", (uint64_t)i); + stack[i].Dump(&new_value); + LLDB_LOGF(log, " %s", new_value.GetData()); } - result = stack.back(); } + result = stack.back(); return true; // Return true on success } diff --git a/contrib/llvm-project/lldb/source/Expression/ExpressionVariable.cpp b/contrib/llvm-project/lldb/source/Expression/ExpressionVariable.cpp index 8b3dda7b2fe1..565a3d1a8161 100644 --- a/contrib/llvm-project/lldb/source/Expression/ExpressionVariable.cpp +++ b/contrib/llvm-project/lldb/source/Expression/ExpressionVariable.cpp @@ -13,7 +13,7 @@ using namespace lldb_private; -ExpressionVariable::~ExpressionVariable() {} +ExpressionVariable::~ExpressionVariable() = default; uint8_t *ExpressionVariable::GetValueBytes() { llvm::Optional<uint64_t> byte_size = m_frozen_sp->GetByteSize(); @@ -28,7 +28,7 @@ uint8_t *ExpressionVariable::GetValueBytes() { return nullptr; } -PersistentExpressionState::~PersistentExpressionState() {} +PersistentExpressionState::~PersistentExpressionState() = default; lldb::addr_t PersistentExpressionState::LookupSymbol(ConstString name) { SymbolMap::iterator si = m_symbol_map.find(name.GetCString()); diff --git a/contrib/llvm-project/lldb/source/Expression/FunctionCaller.cpp b/contrib/llvm-project/lldb/source/Expression/FunctionCaller.cpp index 26ab4bfaff53..5f1eb24a905a 100644 --- a/contrib/llvm-project/lldb/source/Expression/FunctionCaller.cpp +++ b/contrib/llvm-project/lldb/source/Expression/FunctionCaller.cpp @@ -193,8 +193,8 @@ bool FunctionCaller::WriteFunctionArguments( // Special case: if it's a pointer, don't do anything (the ABI supports // passing cstrings) - if (arg_value->GetValueType() == Value::eValueTypeHostAddress && - arg_value->GetContextType() == Value::eContextTypeInvalid && + if (arg_value->GetValueType() == Value::ValueType::HostAddress && + arg_value->GetContextType() == Value::ContextType::Invalid && arg_value->GetCompilerType().IsPointerType()) continue; @@ -295,7 +295,7 @@ bool FunctionCaller::FetchFunctionResults(ExecutionContext &exe_ctx, return false; ret_value.SetCompilerType(m_function_return_type); - ret_value.SetValueType(Value::eValueTypeScalar); + ret_value.SetValueType(Value::ValueType::Scalar); return true; } @@ -317,12 +317,16 @@ lldb::ExpressionResults FunctionCaller::ExecuteFunction( lldb::ExpressionResults return_value = lldb::eExpressionSetupError; // FunctionCaller::ExecuteFunction execution is always just to get the - // result. Do make sure we ignore breakpoints, unwind on error, and don't try - // to debug it. + // result. Unless explicitly asked for, ignore breakpoints and unwind on + // error. + const bool enable_debugging = + exe_ctx.GetTargetPtr() && + exe_ctx.GetTargetPtr()->GetDebugUtilityExpression(); EvaluateExpressionOptions real_options = options; - real_options.SetDebug(false); - real_options.SetUnwindOnError(true); - real_options.SetIgnoreBreakpoints(true); + real_options.SetDebug(false); // This halts the expression for debugging. + real_options.SetGenerateDebugInfo(enable_debugging); + real_options.SetUnwindOnError(!enable_debugging); + real_options.SetIgnoreBreakpoints(!enable_debugging); lldb::addr_t args_addr; diff --git a/contrib/llvm-project/lldb/source/Expression/IRExecutionUnit.cpp b/contrib/llvm-project/lldb/source/Expression/IRExecutionUnit.cpp index 538935da52ee..63184ba477a6 100644 --- a/contrib/llvm-project/lldb/source/Expression/IRExecutionUnit.cpp +++ b/contrib/llvm-project/lldb/source/Expression/IRExecutionUnit.cpp @@ -9,6 +9,8 @@ #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/ExecutionEngine/ObjectCache.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DiagnosticHandler.h" +#include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/Support/SourceMgr.h" @@ -200,16 +202,26 @@ Status IRExecutionUnit::DisassembleFunction(Stream &stream, return ret; } -static void ReportInlineAsmError(const llvm::SMDiagnostic &diagnostic, - void *Context, unsigned LocCookie) { - Status *err = static_cast<Status *>(Context); +namespace { +struct IRExecDiagnosticHandler : public llvm::DiagnosticHandler { + Status *err; + IRExecDiagnosticHandler(Status *err) : err(err) {} + bool handleDiagnostics(const llvm::DiagnosticInfo &DI) override { + if (DI.getKind() == llvm::DK_SrcMgr) { + const auto &DISM = llvm::cast<llvm::DiagnosticInfoSrcMgr>(DI); + if (err && err->Success()) { + err->SetErrorToGenericError(); + err->SetErrorStringWithFormat( + "Inline assembly error: %s", + DISM.getSMDiag().getMessage().str().c_str()); + } + return true; + } - if (err && err->Success()) { - err->SetErrorToGenericError(); - err->SetErrorStringWithFormat("Inline assembly error: %s", - diagnostic.getMessage().str().c_str()); + return false; } -} +}; +} // namespace void IRExecutionUnit::ReportSymbolLookupError(ConstString name) { m_failed_lookups.push_back(name); @@ -257,8 +269,8 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr, LLDB_LOGF(log, "Module being sent to JIT: \n%s", s.c_str()); } - m_module_up->getContext().setInlineAsmDiagnosticHandler(ReportInlineAsmError, - &error); + m_module_up->getContext().setDiagnosticHandler( + std::make_unique<IRExecDiagnosticHandler>(&error)); llvm::EngineBuilder builder(std::move(m_module_up)); llvm::Triple triple(m_module->getTargetTriple()); @@ -484,7 +496,7 @@ IRExecutionUnit::~IRExecutionUnit() { IRExecutionUnit::MemoryManager::MemoryManager(IRExecutionUnit &parent) : m_default_mm_up(new llvm::SectionMemoryManager()), m_parent(parent) {} -IRExecutionUnit::MemoryManager::~MemoryManager() {} +IRExecutionUnit::MemoryManager::~MemoryManager() = default; lldb::SectionType IRExecutionUnit::GetSectionTypeFromSectionName( const llvm::StringRef &name, IRExecutionUnit::AllocationKind alloc_kind) { diff --git a/contrib/llvm-project/lldb/source/Expression/IRInterpreter.cpp b/contrib/llvm-project/lldb/source/Expression/IRInterpreter.cpp index b87a759aadc5..788520d1f32b 100644 --- a/contrib/llvm-project/lldb/source/Expression/IRInterpreter.cpp +++ b/contrib/llvm-project/lldb/source/Expression/IRInterpreter.cpp @@ -122,7 +122,7 @@ public: m_stack_pointer = stack_frame_top; } - ~InterpreterStackFrame() {} + ~InterpreterStackFrame() = default; void Jump(const BasicBlock *bb) { m_prev_bb = m_bb; @@ -1241,7 +1241,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, if (!write_error.Success()) { LLDB_LOGF(log, "Couldn't write to a region on behalf of a LoadInst"); error.SetErrorToGenericError(); - error.SetErrorString(memory_read_error); + error.SetErrorString(memory_write_error); return false; } diff --git a/contrib/llvm-project/lldb/source/Expression/IRMemoryMap.cpp b/contrib/llvm-project/lldb/source/Expression/IRMemoryMap.cpp index 6b1e4c313a39..4ae2724d4dd8 100644 --- a/contrib/llvm-project/lldb/source/Expression/IRMemoryMap.cpp +++ b/contrib/llvm-project/lldb/source/Expression/IRMemoryMap.cpp @@ -639,7 +639,7 @@ void IRMemoryMap::ReadMemory(uint8_t *bytes, lldb::addr_t process_address, if (target_sp) { Address absolute_address(process_address); - target_sp->ReadMemory(absolute_address, false, bytes, size, error); + target_sp->ReadMemory(absolute_address, bytes, size, error, true); return; } diff --git a/contrib/llvm-project/lldb/source/Expression/LLVMUserExpression.cpp b/contrib/llvm-project/lldb/source/Expression/LLVMUserExpression.cpp index 187b427e66aa..527dff8bf60f 100644 --- a/contrib/llvm-project/lldb/source/Expression/LLVMUserExpression.cpp +++ b/contrib/llvm-project/lldb/source/Expression/LLVMUserExpression.cpp @@ -188,9 +188,8 @@ LLVMUserExpression::DoExecute(DiagnosticManager &diagnostic_manager, execution_result == lldb::eExpressionHitBreakpoint) { const char *error_desc = nullptr; - if (call_plan_sp) { - lldb::StopInfoSP real_stop_info_sp = call_plan_sp->GetRealStopInfo(); - if (real_stop_info_sp) + if (user_expression_plan) { + if (auto real_stop_info_sp = user_expression_plan->GetRealStopInfo()) error_desc = real_stop_info_sp->GetDescription(); } if (error_desc) diff --git a/contrib/llvm-project/lldb/source/Expression/Materializer.cpp b/contrib/llvm-project/lldb/source/Expression/Materializer.cpp index a93c127dd0d0..3945f3a70f75 100644 --- a/contrib/llvm-project/lldb/source/Expression/Materializer.cpp +++ b/contrib/llvm-project/lldb/source/Expression/Materializer.cpp @@ -794,13 +794,15 @@ public: llvm::Optional<uint64_t> byte_size = m_type.GetByteSize(exe_scope); if (!byte_size) { - err.SetErrorString("can't get size of type"); + err.SetErrorStringWithFormat("can't get size of type \"%s\"", + m_type.GetTypeName().AsCString()); return; } llvm::Optional<size_t> opt_bit_align = m_type.GetTypeBitAlign(exe_scope); if (!opt_bit_align) { - err.SetErrorString("can't get the type alignment"); + err.SetErrorStringWithFormat("can't get the alignment of type \"%s\"", + m_type.GetTypeName().AsCString()); return; } diff --git a/contrib/llvm-project/lldb/source/Expression/UserExpression.cpp b/contrib/llvm-project/lldb/source/Expression/UserExpression.cpp index 5beed4657b37..eac89c24bc1e 100644 --- a/contrib/llvm-project/lldb/source/Expression/UserExpression.cpp +++ b/contrib/llvm-project/lldb/source/Expression/UserExpression.cpp @@ -8,7 +8,7 @@ #include "lldb/Host/Config.h" -#include <stdio.h> +#include <cstdio> #if HAVE_SYS_TYPES_H #include <sys/types.h> #endif @@ -57,7 +57,7 @@ UserExpression::UserExpression(ExecutionContextScope &exe_scope, m_expr_prefix(std::string(prefix)), m_language(language), m_desired_type(desired_type), m_options(options) {} -UserExpression::~UserExpression() {} +UserExpression::~UserExpression() = default; void UserExpression::InstallContext(ExecutionContext &exe_ctx) { m_jit_process_wp = exe_ctx.GetProcessSP(); @@ -187,7 +187,12 @@ UserExpression::Evaluate(ExecutionContext &exe_ctx, } } - if (process == nullptr || !process->CanJIT()) + // Explicitly force the IR interpreter to evaluate the expression when the + // there is no process that supports running the expression for us. Don't + // change the execution policy if we have the special top-level policy that + // doesn't contain any expression and there is nothing to interpret. + if (execution_policy != eExecutionPolicyTopLevel && + (process == nullptr || !process->CanJIT())) execution_policy = eExecutionPolicyNever; // We need to set the expression execution thread here, turns out parse can @@ -297,19 +302,19 @@ UserExpression::Evaluate(ExecutionContext &exe_ctx, } if (!parse_success) { - if (!fixed_expression->empty() && target->GetEnableNotifyAboutFixIts()) { - error.SetExpressionErrorWithFormat( - execution_results, - "expression failed to parse, fixed expression suggested:\n %s", - fixed_expression->c_str()); - } else { - if (!diagnostic_manager.Diagnostics().size()) - error.SetExpressionError(execution_results, - "expression failed to parse, unknown error"); + std::string msg; + { + llvm::raw_string_ostream os(msg); + os << "expression failed to parse:\n"; + if (!diagnostic_manager.Diagnostics().empty()) + os << diagnostic_manager.GetString(); else - error.SetExpressionError(execution_results, - diagnostic_manager.GetString().c_str()); + os << "unknown error"; + if (target->GetEnableNotifyAboutFixIts() && fixed_expression && + !fixed_expression->empty()) + os << "\nfixed expression suggested:\n " << *fixed_expression; } + error.SetExpressionError(execution_results, msg.c_str()); } } @@ -362,7 +367,7 @@ UserExpression::Evaluate(ExecutionContext &exe_ctx, LLDB_LOG(log, "== [UserExpression::Evaluate] Execution completed " - "normally with result %s ==", + "normally with result {0} ==", result_valobj_sp->GetValueAsCString()); } else { LLDB_LOG(log, "== [UserExpression::Evaluate] Execution completed " diff --git a/contrib/llvm-project/lldb/source/Expression/UtilityFunction.cpp b/contrib/llvm-project/lldb/source/Expression/UtilityFunction.cpp index 128db0ccbc3e..d7a89a8e1446 100644 --- a/contrib/llvm-project/lldb/source/Expression/UtilityFunction.cpp +++ b/contrib/llvm-project/lldb/source/Expression/UtilityFunction.cpp @@ -8,7 +8,7 @@ #include "lldb/Host/Config.h" -#include <stdio.h> +#include <cstdio> #if HAVE_SYS_TYPES_H #include <sys/types.h> #endif @@ -41,7 +41,8 @@ char UtilityFunction::ID; /// \param[in] name /// The name of the function, as used in the text. UtilityFunction::UtilityFunction(ExecutionContextScope &exe_scope, - std::string text, std::string name) + std::string text, std::string name, + bool enable_debugging) : Expression(exe_scope), m_execution_unit_sp(), m_jit_module_wp(), m_function_text(std::move(text)), m_function_name(std::move(name)) {} diff --git a/contrib/llvm-project/lldb/source/Host/common/Editline.cpp b/contrib/llvm-project/lldb/source/Host/common/Editline.cpp index 026a05da45b2..a5598c387b8c 100644 --- a/contrib/llvm-project/lldb/source/Host/common/Editline.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/Editline.cpp @@ -6,11 +6,12 @@ // //===----------------------------------------------------------------------===// +#include <climits> #include <iomanip> -#include <limits.h> -#include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/Editline.h" + +#include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Utility/CompletionRequest.h" @@ -152,6 +153,11 @@ std::vector<EditLineStringType> SplitLines(const EditLineStringType &input) { result.push_back(input.substr(start, end - start)); start = end + 1; } + // Treat an empty history session as a single command of zero-length instead + // of returning an empty vector. + if (result.empty()) { + result.emplace_back(); + } return result; } @@ -641,8 +647,7 @@ unsigned char Editline::BreakLineCommand(int ch) { lines.AppendString(new_line_fragment); #endif - int indent_correction = m_fix_indentation_callback( - this, lines, 0, m_fix_indentation_callback_baton); + int indent_correction = m_fix_indentation_callback(this, lines, 0); new_line_fragment = FixIndentation(new_line_fragment, indent_correction); m_revert_cursor_index = GetIndentation(new_line_fragment); } @@ -677,8 +682,7 @@ unsigned char Editline::EndOrAddLineCommand(int ch) { info->cursor == info->lastchar) { if (m_is_input_complete_callback) { auto lines = GetInputAsStringList(); - if (!m_is_input_complete_callback(this, lines, - m_is_input_complete_callback_baton)) { + if (!m_is_input_complete_callback(this, lines)) { return BreakLineCommand(ch); } @@ -811,8 +815,7 @@ unsigned char Editline::NextLineCommand(int ch) { if (m_fix_indentation_callback) { StringList lines = GetInputAsStringList(); lines.AppendString(""); - indentation = m_fix_indentation_callback( - this, lines, 0, m_fix_indentation_callback_baton); + indentation = m_fix_indentation_callback(this, lines, 0); } m_input_lines.insert( m_input_lines.end(), @@ -857,8 +860,8 @@ unsigned char Editline::FixIndentationCommand(int ch) { // Save the edits and determine the correct indentation level SaveEditedLine(); StringList lines = GetInputAsStringList(m_current_line_index + 1); - int indent_correction = m_fix_indentation_callback( - this, lines, cursor_position, m_fix_indentation_callback_baton); + int indent_correction = + m_fix_indentation_callback(this, lines, cursor_position); // If it is already correct no special work is needed if (indent_correction == 0) @@ -977,7 +980,7 @@ DisplayCompletions(::EditLine *editline, FILE *output_file, } unsigned char Editline::TabCommand(int ch) { - if (m_completion_callback == nullptr) + if (!m_completion_callback) return CC_ERROR; const LineInfo *line_info = el_line(m_editline); @@ -988,7 +991,7 @@ unsigned char Editline::TabCommand(int ch) { CompletionResult result; CompletionRequest request(line, cursor_index, result); - m_completion_callback(request, m_completion_callback_baton); + m_completion_callback(request); llvm::ArrayRef<CompletionResult::Completion> results = result.GetResults(); @@ -1047,12 +1050,15 @@ unsigned char Editline::TabCommand(int ch) { } unsigned char Editline::ApplyAutosuggestCommand(int ch) { + if (!m_suggestion_callback) { + return CC_REDISPLAY; + } + const LineInfo *line_info = el_line(m_editline); llvm::StringRef line(line_info->buffer, line_info->lastchar - line_info->buffer); - if (llvm::Optional<std::string> to_add = - m_suggestion_callback(line, m_suggestion_callback_baton)) + if (llvm::Optional<std::string> to_add = m_suggestion_callback(line)) el_insertstr(m_editline, to_add->c_str()); return CC_REDISPLAY; @@ -1061,12 +1067,16 @@ unsigned char Editline::ApplyAutosuggestCommand(int ch) { unsigned char Editline::TypedCharacter(int ch) { std::string typed = std::string(1, ch); el_insertstr(m_editline, typed.c_str()); + + if (!m_suggestion_callback) { + return CC_REDISPLAY; + } + const LineInfo *line_info = el_line(m_editline); llvm::StringRef line(line_info->buffer, line_info->lastchar - line_info->buffer); - if (llvm::Optional<std::string> to_add = - m_suggestion_callback(line, m_suggestion_callback_baton)) { + if (llvm::Optional<std::string> to_add = m_suggestion_callback(line)) { std::string to_add_color = ANSI_FAINT + to_add.getValue() + ANSI_UNFAINT; fputs(typed.c_str(), m_output_file); fputs(to_add_color.c_str(), m_output_file); @@ -1092,6 +1102,21 @@ unsigned char Editline::TypedCharacter(int ch) { return CC_REDISPLAY; } +void Editline::AddFunctionToEditLine(const EditLineCharType *command, + const EditLineCharType *helptext, + EditlineCommandCallbackType callbackFn) { + el_wset(m_editline, EL_ADDFN, command, helptext, callbackFn); +} + +void Editline::SetEditLinePromptCallback( + EditlinePromptCallbackType callbackFn) { + el_set(m_editline, EL_PROMPT, callbackFn); +} + +void Editline::SetGetCharacterFunction(EditlineGetCharCallbackType callbackFn) { + el_wset(m_editline, EL_GETCFN, callbackFn); +} + void Editline::ConfigureEditor(bool multiline) { if (m_editline && m_multiline_enabled == multiline) return; @@ -1118,74 +1143,83 @@ void Editline::ConfigureEditor(bool multiline) { el_set(m_editline, EL_CLIENTDATA, this); el_set(m_editline, EL_SIGNAL, 0); el_set(m_editline, EL_EDITOR, "emacs"); - el_set(m_editline, EL_PROMPT, - (EditlinePromptCallbackType)([](EditLine *editline) { - return Editline::InstanceFor(editline)->Prompt(); - })); - el_wset(m_editline, EL_GETCFN, (EditlineGetCharCallbackType)([]( - EditLine *editline, EditLineGetCharType *c) { - return Editline::InstanceFor(editline)->GetCharacter(c); - })); + SetGetCharacterFunction([](EditLine *editline, EditLineGetCharType *c) { + return Editline::InstanceFor(editline)->GetCharacter(c); + }); + + SetEditLinePromptCallback([](EditLine *editline) { + return Editline::InstanceFor(editline)->Prompt(); + }); // Commands used for multiline support, registered whether or not they're // used - el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-break-line"), - EditLineConstString("Insert a line break"), - (EditlineCommandCallbackType)([](EditLine *editline, int ch) { - return Editline::InstanceFor(editline)->BreakLineCommand(ch); - })); - el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-end-or-add-line"), - EditLineConstString("End editing or continue when incomplete"), - (EditlineCommandCallbackType)([](EditLine *editline, int ch) { - return Editline::InstanceFor(editline)->EndOrAddLineCommand(ch); - })); - el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-delete-next-char"), - EditLineConstString("Delete next character"), - (EditlineCommandCallbackType)([](EditLine *editline, int ch) { - return Editline::InstanceFor(editline)->DeleteNextCharCommand(ch); - })); - el_wset( - m_editline, EL_ADDFN, EditLineConstString("lldb-delete-previous-char"), + AddFunctionToEditLine( + EditLineConstString("lldb-break-line"), + EditLineConstString("Insert a line break"), + [](EditLine *editline, int ch) { + return Editline::InstanceFor(editline)->BreakLineCommand(ch); + }); + + AddFunctionToEditLine( + EditLineConstString("lldb-end-or-add-line"), + EditLineConstString("End editing or continue when incomplete"), + [](EditLine *editline, int ch) { + return Editline::InstanceFor(editline)->EndOrAddLineCommand(ch); + }); + AddFunctionToEditLine( + EditLineConstString("lldb-delete-next-char"), + EditLineConstString("Delete next character"), + [](EditLine *editline, int ch) { + return Editline::InstanceFor(editline)->DeleteNextCharCommand(ch); + }); + AddFunctionToEditLine( + EditLineConstString("lldb-delete-previous-char"), EditLineConstString("Delete previous character"), - (EditlineCommandCallbackType)([](EditLine *editline, int ch) { + [](EditLine *editline, int ch) { return Editline::InstanceFor(editline)->DeletePreviousCharCommand(ch); - })); - el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-previous-line"), - EditLineConstString("Move to previous line"), - (EditlineCommandCallbackType)([](EditLine *editline, int ch) { - return Editline::InstanceFor(editline)->PreviousLineCommand(ch); - })); - el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-next-line"), - EditLineConstString("Move to next line"), - (EditlineCommandCallbackType)([](EditLine *editline, int ch) { - return Editline::InstanceFor(editline)->NextLineCommand(ch); - })); - el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-previous-history"), - EditLineConstString("Move to previous history"), - (EditlineCommandCallbackType)([](EditLine *editline, int ch) { - return Editline::InstanceFor(editline)->PreviousHistoryCommand(ch); - })); - el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-next-history"), - EditLineConstString("Move to next history"), - (EditlineCommandCallbackType)([](EditLine *editline, int ch) { - return Editline::InstanceFor(editline)->NextHistoryCommand(ch); - })); - el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-buffer-start"), - EditLineConstString("Move to start of buffer"), - (EditlineCommandCallbackType)([](EditLine *editline, int ch) { - return Editline::InstanceFor(editline)->BufferStartCommand(ch); - })); - el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-buffer-end"), - EditLineConstString("Move to end of buffer"), - (EditlineCommandCallbackType)([](EditLine *editline, int ch) { - return Editline::InstanceFor(editline)->BufferEndCommand(ch); - })); - el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-fix-indentation"), - EditLineConstString("Fix line indentation"), - (EditlineCommandCallbackType)([](EditLine *editline, int ch) { - return Editline::InstanceFor(editline)->FixIndentationCommand(ch); - })); + }); + AddFunctionToEditLine( + EditLineConstString("lldb-previous-line"), + EditLineConstString("Move to previous line"), + [](EditLine *editline, int ch) { + return Editline::InstanceFor(editline)->PreviousLineCommand(ch); + }); + AddFunctionToEditLine( + EditLineConstString("lldb-next-line"), + EditLineConstString("Move to next line"), [](EditLine *editline, int ch) { + return Editline::InstanceFor(editline)->NextLineCommand(ch); + }); + AddFunctionToEditLine( + EditLineConstString("lldb-previous-history"), + EditLineConstString("Move to previous history"), + [](EditLine *editline, int ch) { + return Editline::InstanceFor(editline)->PreviousHistoryCommand(ch); + }); + AddFunctionToEditLine( + EditLineConstString("lldb-next-history"), + EditLineConstString("Move to next history"), + [](EditLine *editline, int ch) { + return Editline::InstanceFor(editline)->NextHistoryCommand(ch); + }); + AddFunctionToEditLine( + EditLineConstString("lldb-buffer-start"), + EditLineConstString("Move to start of buffer"), + [](EditLine *editline, int ch) { + return Editline::InstanceFor(editline)->BufferStartCommand(ch); + }); + AddFunctionToEditLine( + EditLineConstString("lldb-buffer-end"), + EditLineConstString("Move to end of buffer"), + [](EditLine *editline, int ch) { + return Editline::InstanceFor(editline)->BufferEndCommand(ch); + }); + AddFunctionToEditLine( + EditLineConstString("lldb-fix-indentation"), + EditLineConstString("Fix line indentation"), + [](EditLine *editline, int ch) { + return Editline::InstanceFor(editline)->FixIndentationCommand(ch); + }); // Register the complete callback under two names for compatibility with // older clients using custom .editrc files (largely because libedit has a @@ -1196,10 +1230,12 @@ void Editline::ConfigureEditor(bool multiline) { int ch) { return Editline::InstanceFor(editline)->TabCommand(ch); }; - el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-complete"), - EditLineConstString("Invoke completion"), complete_callback); - el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb_complete"), - EditLineConstString("Invoke completion"), complete_callback); + AddFunctionToEditLine(EditLineConstString("lldb-complete"), + EditLineConstString("Invoke completion"), + complete_callback); + AddFunctionToEditLine(EditLineConstString("lldb_complete"), + EditLineConstString("Invoke completion"), + complete_callback); // General bindings we don't mind being overridden if (!multiline) { @@ -1207,21 +1243,22 @@ void Editline::ConfigureEditor(bool multiline) { NULL); // Cycle through backwards search, entering string if (m_suggestion_callback) { - el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-apply-complete"), - EditLineConstString("Adopt autocompletion"), - (EditlineCommandCallbackType)([](EditLine *editline, int ch) { - return Editline::InstanceFor(editline)->ApplyAutosuggestCommand( - ch); - })); + AddFunctionToEditLine( + EditLineConstString("lldb-apply-complete"), + EditLineConstString("Adopt autocompletion"), + [](EditLine *editline, int ch) { + return Editline::InstanceFor(editline)->ApplyAutosuggestCommand(ch); + }); el_set(m_editline, EL_BIND, "^f", "lldb-apply-complete", NULL); // Apply a part that is suggested automatically - el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-typed-character"), - EditLineConstString("Typed character"), - (EditlineCommandCallbackType)([](EditLine *editline, int ch) { - return Editline::InstanceFor(editline)->TypedCharacter(ch); - })); + AddFunctionToEditLine( + EditLineConstString("lldb-typed-character"), + EditLineConstString("Typed character"), + [](EditLine *editline, int ch) { + return Editline::InstanceFor(editline)->TypedCharacter(ch); + }); char bind_key[2] = {0, 0}; llvm::StringRef ascii_chars = @@ -1256,11 +1293,12 @@ void Editline::ConfigureEditor(bool multiline) { el_source(m_editline, nullptr); // Register an internal binding that external developers shouldn't use - el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-revert-line"), - EditLineConstString("Revert line to saved state"), - (EditlineCommandCallbackType)([](EditLine *editline, int ch) { - return Editline::InstanceFor(editline)->RevertLineCommand(ch); - })); + AddFunctionToEditLine( + EditLineConstString("lldb-revert-line"), + EditLineConstString("Revert line to saved state"), + [](EditLine *editline, int ch) { + return Editline::InstanceFor(editline)->RevertLineCommand(ch); + }); // Register keys that perform auto-indent correction if (m_fix_indentation_callback && m_fix_indentation_callback_chars) { @@ -1447,33 +1485,6 @@ bool Editline::Cancel() { return result; } -void Editline::SetSuggestionCallback(SuggestionCallbackType callback, - void *baton) { - m_suggestion_callback = callback; - m_suggestion_callback_baton = baton; -} - -void Editline::SetAutoCompleteCallback(CompleteCallbackType callback, - void *baton) { - m_completion_callback = callback; - m_completion_callback_baton = baton; -} - -void Editline::SetIsInputCompleteCallback(IsInputCompleteCallbackType callback, - void *baton) { - m_is_input_complete_callback = callback; - m_is_input_complete_callback_baton = baton; -} - -bool Editline::SetFixIndentationCallback(FixIndentationCallbackType callback, - void *baton, - const char *indent_chars) { - m_fix_indentation_callback = callback; - m_fix_indentation_callback_baton = baton; - m_fix_indentation_callback_chars = indent_chars; - return false; -} - bool Editline::GetLine(std::string &line, bool &interrupted) { ConfigureEditor(false); m_input_lines = std::vector<EditLineStringType>(); diff --git a/contrib/llvm-project/lldb/source/Host/common/File.cpp b/contrib/llvm-project/lldb/source/Host/common/File.cpp index a5b970907e64..e302e0a0de09 100644 --- a/contrib/llvm-project/lldb/source/Host/common/File.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/File.cpp @@ -8,11 +8,11 @@ #include "lldb/Host/File.h" -#include <errno.h> +#include <cerrno> +#include <climits> +#include <cstdarg> +#include <cstdio> #include <fcntl.h> -#include <limits.h> -#include <stdarg.h> -#include <stdio.h> #ifdef _WIN32 #include "lldb/Host/windows/windows.h" diff --git a/contrib/llvm-project/lldb/source/Host/common/FileAction.cpp b/contrib/llvm-project/lldb/source/Host/common/FileAction.cpp index 8b4e7f4c2208..e399c7ec47cd 100644 --- a/contrib/llvm-project/lldb/source/Host/common/FileAction.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/FileAction.cpp @@ -16,8 +16,7 @@ using namespace lldb_private; // FileAction member functions -FileAction::FileAction() - : m_action(eFileActionNone), m_fd(-1), m_arg(-1), m_file_spec() {} +FileAction::FileAction() : m_file_spec() {} void FileAction::Clear() { m_action = eFileActionNone; diff --git a/contrib/llvm-project/lldb/source/Host/common/FileSystem.cpp b/contrib/llvm-project/lldb/source/Host/common/FileSystem.cpp index 9fa8854d950e..a2c3b3556a6c 100644 --- a/contrib/llvm-project/lldb/source/Host/common/FileSystem.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/FileSystem.cpp @@ -19,11 +19,11 @@ #include "llvm/Support/Program.h" #include "llvm/Support/Threading.h" -#include <errno.h> +#include <cerrno> +#include <climits> +#include <cstdarg> +#include <cstdio> #include <fcntl.h> -#include <limits.h> -#include <stdarg.h> -#include <stdio.h> #ifdef _WIN32 #include "lldb/Host/windows/windows.h" @@ -307,7 +307,7 @@ FileSystem::CreateDataBuffer(const llvm::Twine &path, uint64_t size, std::unique_ptr<llvm::WritableMemoryBuffer> buffer; if (size == 0) { auto buffer_or_error = - llvm::WritableMemoryBuffer::getFile(*external_path, -1, is_volatile); + llvm::WritableMemoryBuffer::getFile(*external_path, is_volatile); if (!buffer_or_error) return nullptr; buffer = std::move(*buffer_or_error); @@ -478,20 +478,18 @@ ErrorOr<std::string> FileSystem::GetExternalPath(const llvm::Twine &path) { return path.str(); // If VFS mapped we know the underlying FS is a RedirectingFileSystem. - ErrorOr<vfs::RedirectingFileSystem::Entry *> E = + ErrorOr<vfs::RedirectingFileSystem::LookupResult> Result = static_cast<vfs::RedirectingFileSystem &>(*m_fs).lookupPath(path.str()); - if (!E) { - if (E.getError() == llvm::errc::no_such_file_or_directory) { + if (!Result) { + if (Result.getError() == llvm::errc::no_such_file_or_directory) { return path.str(); } - return E.getError(); + return Result.getError(); } - auto *F = dyn_cast<vfs::RedirectingFileSystem::RedirectingFileEntry>(*E); - if (!F) - return make_error_code(llvm::errc::not_supported); - - return F->getExternalContentsPath().str(); + if (Optional<StringRef> ExtRedirect = Result->getExternalRedirect()) + return std::string(*ExtRedirect); + return make_error_code(llvm::errc::not_supported); } ErrorOr<std::string> FileSystem::GetExternalPath(const FileSpec &file_spec) { diff --git a/contrib/llvm-project/lldb/source/Host/common/GetOptInc.cpp b/contrib/llvm-project/lldb/source/Host/common/GetOptInc.cpp index 62ce7428e8cc..c2044b687322 100644 --- a/contrib/llvm-project/lldb/source/Host/common/GetOptInc.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/GetOptInc.cpp @@ -12,9 +12,9 @@ defined(REPLACE_GETOPT_LONG_ONLY) // getopt.cpp -#include <errno.h> -#include <stdlib.h> -#include <string.h> +#include <cerrno> +#include <cstdlib> +#include <cstring> #if defined(REPLACE_GETOPT) int opterr = 1; /* if error message should be printed */ diff --git a/contrib/llvm-project/lldb/source/Host/common/Host.cpp b/contrib/llvm-project/lldb/source/Host/common/Host.cpp index 99316660908e..d14ebe99fd15 100644 --- a/contrib/llvm-project/lldb/source/Host/common/Host.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/Host.cpp @@ -7,9 +7,9 @@ //===----------------------------------------------------------------------===// // C includes -#include <errno.h> -#include <limits.h> -#include <stdlib.h> +#include <cerrno> +#include <climits> +#include <cstdlib> #include <sys/types.h> #ifndef _WIN32 #include <dlfcn.h> @@ -442,14 +442,12 @@ bool Host::FindProcessThreads(const lldb::pid_t pid, TidMap &tids_to_attach) { #endif struct ShellInfo { - ShellInfo() - : process_reaped(false), pid(LLDB_INVALID_PROCESS_ID), signo(-1), - status(-1) {} + ShellInfo() : process_reaped(false) {} lldb_private::Predicate<bool> process_reaped; - lldb::pid_t pid; - int signo; - int status; + lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; + int signo = -1; + int status = -1; }; static bool diff --git a/contrib/llvm-project/lldb/source/Host/common/HostInfoBase.cpp b/contrib/llvm-project/lldb/source/Host/common/HostInfoBase.cpp index 333137a7fd25..a6239a3208bc 100644 --- a/contrib/llvm-project/lldb/source/Host/common/HostInfoBase.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/HostInfoBase.cpp @@ -31,12 +31,7 @@ using namespace lldb; using namespace lldb_private; namespace { -// The HostInfoBaseFields is a work around for windows not supporting static -// variables correctly in a thread safe way. Really each of the variables in -// HostInfoBaseFields should live in the functions in which they are used and -// each one should be static, but the work around is in place to avoid this -// restriction. Ick. - +/// Contains the state of the HostInfoBase plugin. struct HostInfoBaseFields { ~HostInfoBaseFields() { if (FileSystem::Instance().Exists(m_lldb_process_tmp_dir)) { @@ -71,13 +66,18 @@ struct HostInfoBaseFields { llvm::once_flag m_lldb_global_tmp_dir_once; FileSpec m_lldb_global_tmp_dir; }; +} // namespace -HostInfoBaseFields *g_fields = nullptr; -} +static HostInfoBaseFields *g_fields = nullptr; +static HostInfoBase::SharedLibraryDirectoryHelper *g_shlib_dir_helper = nullptr; -void HostInfoBase::Initialize() { g_fields = new HostInfoBaseFields(); } +void HostInfoBase::Initialize(SharedLibraryDirectoryHelper *helper) { + g_shlib_dir_helper = helper; + g_fields = new HostInfoBaseFields(); +} void HostInfoBase::Terminate() { + g_shlib_dir_helper = nullptr; delete g_fields; g_fields = nullptr; } @@ -249,9 +249,8 @@ bool HostInfoBase::ComputeSharedLibraryDirectory(FileSpec &file_spec) { reinterpret_cast<void *>( HostInfoBase::ComputeSharedLibraryDirectory))); - // This is necessary because when running the testsuite the shlib might be a - // symbolic link inside the Python resource dir. - FileSystem::Instance().ResolveSymbolicLink(lldb_file_spec, lldb_file_spec); + if (g_shlib_dir_helper) + g_shlib_dir_helper(lldb_file_spec); // Remove the filename so that this FileSpec only represents the directory. file_spec.GetDirectory() = lldb_file_spec.GetDirectory(); diff --git a/contrib/llvm-project/lldb/source/Host/common/HostNativeThreadBase.cpp b/contrib/llvm-project/lldb/source/Host/common/HostNativeThreadBase.cpp index a79431f61d88..b15160b143ca 100644 --- a/contrib/llvm-project/lldb/source/Host/common/HostNativeThreadBase.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/HostNativeThreadBase.cpp @@ -17,9 +17,6 @@ using namespace lldb; using namespace lldb_private; -HostNativeThreadBase::HostNativeThreadBase() - : m_thread(LLDB_INVALID_HOST_THREAD), m_result(0) {} - HostNativeThreadBase::HostNativeThreadBase(thread_t thread) : m_thread(thread), m_result(0) {} diff --git a/contrib/llvm-project/lldb/source/Host/common/HostProcess.cpp b/contrib/llvm-project/lldb/source/Host/common/HostProcess.cpp index 256a73bb6716..06dd192013ba 100644 --- a/contrib/llvm-project/lldb/source/Host/common/HostProcess.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/HostProcess.cpp @@ -18,7 +18,7 @@ HostProcess::HostProcess() : m_native_process(new HostNativeProcess) {} HostProcess::HostProcess(lldb::process_t process) : m_native_process(new HostNativeProcess(process)) {} -HostProcess::~HostProcess() {} +HostProcess::~HostProcess() = default; Status HostProcess::Terminate() { return m_native_process->Terminate(); } diff --git a/contrib/llvm-project/lldb/source/Host/common/MainLoop.cpp b/contrib/llvm-project/lldb/source/Host/common/MainLoop.cpp index 02cabbc93550..d36587ce2346 100644 --- a/contrib/llvm-project/lldb/source/Host/common/MainLoop.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/MainLoop.cpp @@ -16,7 +16,7 @@ #include <cassert> #include <cerrno> #include <csignal> -#include <time.h> +#include <ctime> #include <vector> // Multiplexing is implemented using kqueue on systems that support it (BSD @@ -302,13 +302,15 @@ MainLoop::RegisterSignal(int signo, const Callback &callback, Status &error) { error.SetErrorString("Signal polling is not supported on this platform."); return nullptr; #else - if (m_signals.find(signo) != m_signals.end()) { - error.SetErrorStringWithFormat("Signal %d already monitored.", signo); - return nullptr; + auto signal_it = m_signals.find(signo); + if (signal_it != m_signals.end()) { + auto callback_it = signal_it->second.callbacks.insert( + signal_it->second.callbacks.end(), callback); + return SignalHandleUP(new SignalHandle(*this, signo, callback_it)); } SignalInfo info; - info.callback = callback; + info.callbacks.push_back(callback); struct sigaction new_action; new_action.sa_sigaction = &SignalHandler; new_action.sa_flags = SA_SIGINFO; @@ -338,9 +340,10 @@ MainLoop::RegisterSignal(int signo, const Callback &callback, Status &error) { &new_action.sa_mask, &old_set); assert(ret == 0 && "pthread_sigmask failed"); info.was_blocked = sigismember(&old_set, signo); - m_signals.insert({signo, info}); + auto insert_ret = m_signals.insert({signo, info}); - return SignalHandleUP(new SignalHandle(*this, signo)); + return SignalHandleUP(new SignalHandle( + *this, signo, insert_ret.first->second.callbacks.begin())); #endif } @@ -350,13 +353,19 @@ void MainLoop::UnregisterReadObject(IOObject::WaitableHandle handle) { assert(erased); } -void MainLoop::UnregisterSignal(int signo) { +void MainLoop::UnregisterSignal(int signo, + std::list<Callback>::iterator callback_it) { #if SIGNAL_POLLING_UNSUPPORTED Status("Signal polling is not supported on this platform."); #else auto it = m_signals.find(signo); assert(it != m_signals.end()); + it->second.callbacks.erase(callback_it); + // Do not remove the signal handler unless all callbacks have been erased. + if (!it->second.callbacks.empty()) + return; + sigaction(signo, &it->second.old_action, nullptr); sigset_t set; @@ -398,8 +407,14 @@ Status MainLoop::Run() { void MainLoop::ProcessSignal(int signo) { auto it = m_signals.find(signo); - if (it != m_signals.end()) - it->second.callback(*this); // Do the work + if (it != m_signals.end()) { + // The callback may actually register/unregister signal handlers, + // so we need to create a copy first. + llvm::SmallVector<Callback, 4> callbacks_to_run{ + it->second.callbacks.begin(), it->second.callbacks.end()}; + for (auto &x : callbacks_to_run) + x(*this); // Do the work + } } void MainLoop::ProcessReadObject(IOObject::WaitableHandle handle) { diff --git a/contrib/llvm-project/lldb/source/Host/common/NativeProcessProtocol.cpp b/contrib/llvm-project/lldb/source/Host/common/NativeProcessProtocol.cpp index 070fda664678..ea80a05430f7 100644 --- a/contrib/llvm-project/lldb/source/Host/common/NativeProcessProtocol.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/NativeProcessProtocol.cpp @@ -25,10 +25,8 @@ using namespace lldb_private; NativeProcessProtocol::NativeProcessProtocol(lldb::pid_t pid, int terminal_fd, NativeDelegate &delegate) - : m_pid(pid), m_terminal_fd(terminal_fd) { - bool registered = RegisterNativeDelegate(delegate); - assert(registered); - (void)registered; + : m_pid(pid), m_delegate(delegate), m_terminal_fd(terminal_fd) { + delegate.InitializeDelegate(this); } lldb_private::Status NativeProcessProtocol::Interrupt() { @@ -54,6 +52,19 @@ NativeProcessProtocol::GetMemoryRegionInfo(lldb::addr_t load_addr, return Status("not implemented"); } +lldb_private::Status +NativeProcessProtocol::ReadMemoryTags(int32_t type, lldb::addr_t addr, + size_t len, std::vector<uint8_t> &tags) { + return Status("not implemented"); +} + +lldb_private::Status +NativeProcessProtocol::WriteMemoryTags(int32_t type, lldb::addr_t addr, + size_t len, + const std::vector<uint8_t> &tags) { + return Status("not implemented"); +} + llvm::Optional<WaitStatus> NativeProcessProtocol::GetExitStatus() { if (m_state == lldb::eStateExited) return m_exit_status; @@ -295,64 +306,21 @@ Status NativeProcessProtocol::RemoveHardwareBreakpoint(lldb::addr_t addr) { return error; } -bool NativeProcessProtocol::RegisterNativeDelegate( - NativeDelegate &native_delegate) { - std::lock_guard<std::recursive_mutex> guard(m_delegates_mutex); - if (llvm::is_contained(m_delegates, &native_delegate)) - return false; - - m_delegates.push_back(&native_delegate); - native_delegate.InitializeDelegate(this); - return true; -} - -bool NativeProcessProtocol::UnregisterNativeDelegate( - NativeDelegate &native_delegate) { - std::lock_guard<std::recursive_mutex> guard(m_delegates_mutex); - - const auto initial_size = m_delegates.size(); - m_delegates.erase( - remove(m_delegates.begin(), m_delegates.end(), &native_delegate), - m_delegates.end()); - - // We removed the delegate if the count of delegates shrank after removing - // all copies of the given native_delegate from the vector. - return m_delegates.size() < initial_size; -} - void NativeProcessProtocol::SynchronouslyNotifyProcessStateChanged( lldb::StateType state) { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); - std::lock_guard<std::recursive_mutex> guard(m_delegates_mutex); - for (auto native_delegate : m_delegates) - native_delegate->ProcessStateChanged(this, state); + m_delegate.ProcessStateChanged(this, state); - if (log) { - if (!m_delegates.empty()) { - LLDB_LOGF(log, - "NativeProcessProtocol::%s: sent state notification [%s] " - "from process %" PRIu64, - __FUNCTION__, lldb_private::StateAsCString(state), GetID()); - } else { - LLDB_LOGF(log, - "NativeProcessProtocol::%s: would send state notification " - "[%s] from process %" PRIu64 ", but no delegates", - __FUNCTION__, lldb_private::StateAsCString(state), GetID()); - } - } + LLDB_LOG(log, "sent state notification [{0}] from process {1}", state, + GetID()); } void NativeProcessProtocol::NotifyDidExec() { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); - LLDB_LOGF(log, "NativeProcessProtocol::%s - preparing to call delegates", - __FUNCTION__); + LLDB_LOG(log, "process {0} exec()ed", GetID()); - { - std::lock_guard<std::recursive_mutex> guard(m_delegates_mutex); - for (auto native_delegate : m_delegates) - native_delegate->DidExec(this); - } + m_delegate.DidExec(this); } Status NativeProcessProtocol::SetSoftwareBreakpoint(lldb::addr_t addr, diff --git a/contrib/llvm-project/lldb/source/Host/common/NativeRegisterContext.cpp b/contrib/llvm-project/lldb/source/Host/common/NativeRegisterContext.cpp index 9bb877fff878..04d10aba4e63 100644 --- a/contrib/llvm-project/lldb/source/Host/common/NativeRegisterContext.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/NativeRegisterContext.cpp @@ -22,7 +22,7 @@ NativeRegisterContext::NativeRegisterContext(NativeThreadProtocol &thread) : m_thread(thread) {} // Destructor -NativeRegisterContext::~NativeRegisterContext() {} +NativeRegisterContext::~NativeRegisterContext() = default; // FIXME revisit invalidation, process stop ids, etc. Right now we don't // support caching in NativeRegisterContext. We can do this later by utilizing @@ -60,8 +60,8 @@ NativeRegisterContext::GetRegisterInfoByName(llvm::StringRef reg_name, for (uint32_t reg = start_idx; reg < num_registers; ++reg) { const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg); - if (reg_name.equals_lower(reg_info->name) || - reg_name.equals_lower(reg_info->alt_name)) + if (reg_name.equals_insensitive(reg_info->name) || + reg_name.equals_insensitive(reg_info->alt_name)) return reg_info; } return nullptr; diff --git a/contrib/llvm-project/lldb/source/Host/common/ProcessLaunchInfo.cpp b/contrib/llvm-project/lldb/source/Host/common/ProcessLaunchInfo.cpp index 1b4b2c6c3ac2..8d281b80e8f0 100644 --- a/contrib/llvm-project/lldb/source/Host/common/ProcessLaunchInfo.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/ProcessLaunchInfo.cpp @@ -20,7 +20,7 @@ #include "llvm/Support/FileSystem.h" #if !defined(_WIN32) -#include <limits.h> +#include <climits> #endif using namespace lldb; @@ -30,9 +30,9 @@ using namespace lldb_private; ProcessLaunchInfo::ProcessLaunchInfo() : ProcessInfo(), m_working_dir(), m_plugin_name(), m_flags(0), - m_file_actions(), m_pty(new PseudoTerminal), m_resume_count(0), - m_monitor_callback(nullptr), m_monitor_callback_baton(nullptr), - m_monitor_signals(false), m_listener_sp(), m_hijack_listener_sp() {} + m_file_actions(), m_pty(new PseudoTerminal), m_monitor_callback(nullptr), + m_listener_sp(), m_hijack_listener_sp(), m_scripted_process_class_name(), + m_scripted_process_dictionary_sp() {} ProcessLaunchInfo::ProcessLaunchInfo(const FileSpec &stdin_file_spec, const FileSpec &stdout_file_spec, @@ -42,7 +42,8 @@ ProcessLaunchInfo::ProcessLaunchInfo(const FileSpec &stdin_file_spec, : ProcessInfo(), m_working_dir(), m_plugin_name(), m_flags(launch_flags), m_file_actions(), m_pty(new PseudoTerminal), m_resume_count(0), m_monitor_callback(nullptr), m_monitor_callback_baton(nullptr), - m_monitor_signals(false), m_listener_sp(), m_hijack_listener_sp() { + m_monitor_signals(false), m_listener_sp(), m_hijack_listener_sp(), + m_scripted_process_class_name(), m_scripted_process_dictionary_sp() { if (stdin_file_spec) { FileAction file_action; const bool read = true; @@ -171,6 +172,8 @@ void ProcessLaunchInfo::Clear() { m_resume_count = 0; m_listener_sp.reset(); m_hijack_listener_sp.reset(); + m_scripted_process_class_name.clear(); + m_scripted_process_dictionary_sp.reset(); } void ProcessLaunchInfo::SetMonitorProcessCallback( diff --git a/contrib/llvm-project/lldb/source/Host/common/ProcessRunLock.cpp b/contrib/llvm-project/lldb/source/Host/common/ProcessRunLock.cpp index 3b6f033d33ab..aee15779d919 100644 --- a/contrib/llvm-project/lldb/source/Host/common/ProcessRunLock.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/ProcessRunLock.cpp @@ -11,7 +11,7 @@ namespace lldb_private { -ProcessRunLock::ProcessRunLock() : m_running(false) { +ProcessRunLock::ProcessRunLock() { int err = ::pthread_rwlock_init(&m_rwlock, nullptr); (void)err; } diff --git a/contrib/llvm-project/lldb/source/Host/common/PseudoTerminal.cpp b/contrib/llvm-project/lldb/source/Host/common/PseudoTerminal.cpp index de76e8ab4f68..dce4c5185c7b 100644 --- a/contrib/llvm-project/lldb/source/Host/common/PseudoTerminal.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/PseudoTerminal.cpp @@ -11,11 +11,11 @@ #include "llvm/Support/Errc.h" #include "llvm/Support/Errno.h" #include <cassert> -#include <limits.h> +#include <climits> +#include <cstdio> +#include <cstdlib> +#include <cstring> #include <mutex> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> #if defined(TIOCSCTTY) #include <sys/ioctl.h> #endif @@ -29,8 +29,7 @@ int posix_openpt(int flags); using namespace lldb_private; // PseudoTerminal constructor -PseudoTerminal::PseudoTerminal() - : m_primary_fd(invalid_fd), m_secondary_fd(invalid_fd) {} +PseudoTerminal::PseudoTerminal() = default; // Destructor // diff --git a/contrib/llvm-project/lldb/source/Host/common/Socket.cpp b/contrib/llvm-project/lldb/source/Host/common/Socket.cpp index 4bcf34a6b456..d1c327dcb790 100644 --- a/contrib/llvm-project/lldb/source/Host/common/Socket.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/Socket.cpp @@ -41,9 +41,9 @@ #ifdef __ANDROID__ #include <arpa/inet.h> #include <asm-generic/errno-base.h> -#include <errno.h> -#include <linux/tcp.h> +#include <cerrno> #include <fcntl.h> +#include <linux/tcp.h> #include <sys/syscall.h> #include <unistd.h> #endif // __ANDROID__ diff --git a/contrib/llvm-project/lldb/source/Host/common/SocketAddress.cpp b/contrib/llvm-project/lldb/source/Host/common/SocketAddress.cpp index e98944d6cdc8..3f47d32d4652 100644 --- a/contrib/llvm-project/lldb/source/Host/common/SocketAddress.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/SocketAddress.cpp @@ -17,15 +17,15 @@ #endif #include "lldb/Host/SocketAddress.h" -#include <stddef.h> -#include <stdio.h> +#include <cstddef> +#include <cstdio> #if !defined(_WIN32) #include <arpa/inet.h> #endif -#include <assert.h> -#include <string.h> +#include <cassert> +#include <cstring> #include "lldb/Host/PosixApi.h" @@ -93,7 +93,7 @@ SocketAddress::SocketAddress(const struct addrinfo *addr_info) { } // Destructor -SocketAddress::~SocketAddress() {} +SocketAddress::~SocketAddress() = default; void SocketAddress::Clear() { memset(&m_socket_addr, 0, sizeof(m_socket_addr)); diff --git a/contrib/llvm-project/lldb/source/Host/common/StringConvert.cpp b/contrib/llvm-project/lldb/source/Host/common/StringConvert.cpp index e5f05e628c7c..b4eb92755367 100644 --- a/contrib/llvm-project/lldb/source/Host/common/StringConvert.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/StringConvert.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include <stdlib.h> +#include <cstdlib> #include "lldb/Host/StringConvert.h" diff --git a/contrib/llvm-project/lldb/source/Host/common/Terminal.cpp b/contrib/llvm-project/lldb/source/Host/common/Terminal.cpp index 9990dbf74356..2301abe9afb1 100644 --- a/contrib/llvm-project/lldb/source/Host/common/Terminal.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/Terminal.cpp @@ -12,8 +12,8 @@ #include "lldb/Host/PosixApi.h" #include "llvm/ADT/STLExtras.h" +#include <csignal> #include <fcntl.h> -#include <signal.h> #if LLDB_ENABLE_TERMIOS #include <termios.h> @@ -83,15 +83,16 @@ bool Terminal::SetCanonical(bool enabled) { // Default constructor TerminalState::TerminalState() - : m_tty(), m_tflags(-1), + : m_tty() #if LLDB_ENABLE_TERMIOS - m_termios_up(), + , + m_termios_up() #endif - m_process_group(-1) { +{ } // Destructor -TerminalState::~TerminalState() {} +TerminalState::~TerminalState() = default; void TerminalState::Clear() { m_tty.Clear(); @@ -189,10 +190,10 @@ bool TerminalState::ProcessGroupIsValid() const { } // Constructor -TerminalStateSwitcher::TerminalStateSwitcher() : m_currentState(UINT32_MAX) {} +TerminalStateSwitcher::TerminalStateSwitcher() = default; // Destructor -TerminalStateSwitcher::~TerminalStateSwitcher() {} +TerminalStateSwitcher::~TerminalStateSwitcher() = default; // Returns the number of states that this switcher contains uint32_t TerminalStateSwitcher::GetNumberOfStates() const { diff --git a/contrib/llvm-project/lldb/source/Host/common/XML.cpp b/contrib/llvm-project/lldb/source/Host/common/XML.cpp index 456c879b0148..c3225d3f4433 100644 --- a/contrib/llvm-project/lldb/source/Host/common/XML.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/XML.cpp @@ -17,7 +17,7 @@ using namespace lldb_private; #pragma mark-- XMLDocument -XMLDocument::XMLDocument() : m_document(nullptr) {} +XMLDocument::XMLDocument() = default; XMLDocument::~XMLDocument() { Clear(); } @@ -91,11 +91,11 @@ bool XMLDocument::XMLEnabled() { #pragma mark-- XMLNode -XMLNode::XMLNode() : m_node(nullptr) {} +XMLNode::XMLNode() = default; XMLNode::XMLNode(XMLNodeImpl node) : m_node(node) {} -XMLNode::~XMLNode() {} +XMLNode::~XMLNode() = default; void XMLNode::Clear() { m_node = nullptr; } @@ -398,7 +398,7 @@ ApplePropertyList::ApplePropertyList(const char *path) ParseFile(path); } -ApplePropertyList::~ApplePropertyList() {} +ApplePropertyList::~ApplePropertyList() = default; llvm::StringRef ApplePropertyList::GetErrors() const { return m_xml_doc.GetErrors(); diff --git a/contrib/llvm-project/lldb/source/Host/freebsd/Host.cpp b/contrib/llvm-project/lldb/source/Host/freebsd/Host.cpp index c0cc74a5f6cc..f93581651273 100644 --- a/contrib/llvm-project/lldb/source/Host/freebsd/Host.cpp +++ b/contrib/llvm-project/lldb/source/Host/freebsd/Host.cpp @@ -16,9 +16,9 @@ #include <machine/elf.h> +#include <cstdio> #include <dlfcn.h> #include <execinfo.h> -#include <stdio.h> #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" diff --git a/contrib/llvm-project/lldb/source/Host/freebsd/HostInfoFreeBSD.cpp b/contrib/llvm-project/lldb/source/Host/freebsd/HostInfoFreeBSD.cpp index 2db97dbcd74c..1b9e3ccaf181 100644 --- a/contrib/llvm-project/lldb/source/Host/freebsd/HostInfoFreeBSD.cpp +++ b/contrib/llvm-project/lldb/source/Host/freebsd/HostInfoFreeBSD.cpp @@ -8,8 +8,8 @@ #include "lldb/Host/freebsd/HostInfoFreeBSD.h" -#include <stdio.h> -#include <string.h> +#include <cstdio> +#include <cstring> #include <sys/sysctl.h> #include <sys/types.h> #include <sys/utsname.h> diff --git a/contrib/llvm-project/lldb/source/Host/netbsd/HostInfoNetBSD.cpp b/contrib/llvm-project/lldb/source/Host/netbsd/HostInfoNetBSD.cpp index cc01ec35a5bc..bddd46cec3ee 100644 --- a/contrib/llvm-project/lldb/source/Host/netbsd/HostInfoNetBSD.cpp +++ b/contrib/llvm-project/lldb/source/Host/netbsd/HostInfoNetBSD.cpp @@ -8,11 +8,11 @@ #include "lldb/Host/netbsd/HostInfoNetBSD.h" -#include <inttypes.h> -#include <limits.h> +#include <cinttypes> +#include <climits> +#include <cstdio> +#include <cstring> #include <pthread.h> -#include <stdio.h> -#include <string.h> #include <sys/sysctl.h> #include <sys/types.h> #include <sys/utsname.h> diff --git a/contrib/llvm-project/lldb/source/Host/netbsd/HostNetBSD.cpp b/contrib/llvm-project/lldb/source/Host/netbsd/HostNetBSD.cpp index 1945f9f9052f..af31a11a20a0 100644 --- a/contrib/llvm-project/lldb/source/Host/netbsd/HostNetBSD.cpp +++ b/contrib/llvm-project/lldb/source/Host/netbsd/HostNetBSD.cpp @@ -6,14 +6,14 @@ // //===----------------------------------------------------------------------===// +#include <cstdio> #include <dlfcn.h> #include <execinfo.h> -#include <stdio.h> #include <sys/proc.h> #include <sys/sysctl.h> #include <sys/types.h> -#include <limits.h> +#include <climits> #include <kvm.h> #include <sys/exec.h> diff --git a/contrib/llvm-project/lldb/source/Host/openbsd/Host.cpp b/contrib/llvm-project/lldb/source/Host/openbsd/Host.cpp index 4ce549522908..799a61adbf26 100644 --- a/contrib/llvm-project/lldb/source/Host/openbsd/Host.cpp +++ b/contrib/llvm-project/lldb/source/Host/openbsd/Host.cpp @@ -15,7 +15,7 @@ #include <sys/sysctl.h> #include <sys/user.h> -#include <stdio.h> +#include <cstdio> #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" diff --git a/contrib/llvm-project/lldb/source/Host/openbsd/HostInfoOpenBSD.cpp b/contrib/llvm-project/lldb/source/Host/openbsd/HostInfoOpenBSD.cpp index 58836333b63c..9617375babe1 100644 --- a/contrib/llvm-project/lldb/source/Host/openbsd/HostInfoOpenBSD.cpp +++ b/contrib/llvm-project/lldb/source/Host/openbsd/HostInfoOpenBSD.cpp @@ -8,8 +8,8 @@ #include "lldb/Host/openbsd/HostInfoOpenBSD.h" -#include <stdio.h> -#include <string.h> +#include <cstdio> +#include <cstring> #include <sys/sysctl.h> #include <sys/types.h> #include <sys/utsname.h> diff --git a/contrib/llvm-project/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp b/contrib/llvm-project/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp index 3a547ce128d8..2f4cc960f02d 100644 --- a/contrib/llvm-project/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp +++ b/contrib/llvm-project/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp @@ -20,10 +20,10 @@ #include "lldb/Utility/SelectHelper.h" #include "lldb/Utility/Timeout.h" -#include <errno.h> +#include <cerrno> +#include <cstdlib> +#include <cstring> #include <fcntl.h> -#include <stdlib.h> -#include <string.h> #include <sys/types.h> #if LLDB_ENABLE_POSIX @@ -76,7 +76,7 @@ llvm::Optional<llvm::StringRef> GetURLAddress(llvm::StringRef url, ConnectionFileDescriptor::ConnectionFileDescriptor(bool child_processes_inherit) : Connection(), m_pipe(), m_mutex(), m_shutting_down(false), - m_waiting_for_accept(false), + m_child_processes_inherit(child_processes_inherit) { Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT)); diff --git a/contrib/llvm-project/lldb/source/Host/posix/DomainSocket.cpp b/contrib/llvm-project/lldb/source/Host/posix/DomainSocket.cpp index 5a396906fdf6..7322b15200b4 100644 --- a/contrib/llvm-project/lldb/source/Host/posix/DomainSocket.cpp +++ b/contrib/llvm-project/lldb/source/Host/posix/DomainSocket.cpp @@ -11,7 +11,7 @@ #include "llvm/Support/Errno.h" #include "llvm/Support/FileSystem.h" -#include <stddef.h> +#include <cstddef> #include <sys/socket.h> #include <sys/un.h> diff --git a/contrib/llvm-project/lldb/source/Host/posix/HostInfoPosix.cpp b/contrib/llvm-project/lldb/source/Host/posix/HostInfoPosix.cpp index 7e110f07d7cf..b633acf6fec6 100644 --- a/contrib/llvm-project/lldb/source/Host/posix/HostInfoPosix.cpp +++ b/contrib/llvm-project/lldb/source/Host/posix/HostInfoPosix.cpp @@ -15,11 +15,11 @@ #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" +#include <climits> +#include <cstdlib> #include <grp.h> -#include <limits.h> #include <mutex> #include <pwd.h> -#include <stdlib.h> #include <sys/types.h> #include <unistd.h> diff --git a/contrib/llvm-project/lldb/source/Host/posix/HostProcessPosix.cpp b/contrib/llvm-project/lldb/source/Host/posix/HostProcessPosix.cpp index 69a049bcf7a2..f0142ec946b7 100644 --- a/contrib/llvm-project/lldb/source/Host/posix/HostProcessPosix.cpp +++ b/contrib/llvm-project/lldb/source/Host/posix/HostProcessPosix.cpp @@ -12,8 +12,8 @@ #include "llvm/ADT/STLExtras.h" +#include <climits> #include <csignal> -#include <limits.h> #include <unistd.h> using namespace lldb_private; @@ -28,7 +28,7 @@ HostProcessPosix::HostProcessPosix() HostProcessPosix::HostProcessPosix(lldb::process_t process) : HostNativeProcessBase(process) {} -HostProcessPosix::~HostProcessPosix() {} +HostProcessPosix::~HostProcessPosix() = default; Status HostProcessPosix::Signal(int signo) const { if (m_process == kInvalidPosixProcess) { diff --git a/contrib/llvm-project/lldb/source/Host/posix/HostThreadPosix.cpp b/contrib/llvm-project/lldb/source/Host/posix/HostThreadPosix.cpp index 31c7c7f8e2f3..4250e07e51cc 100644 --- a/contrib/llvm-project/lldb/source/Host/posix/HostThreadPosix.cpp +++ b/contrib/llvm-project/lldb/source/Host/posix/HostThreadPosix.cpp @@ -9,18 +9,18 @@ #include "lldb/Host/posix/HostThreadPosix.h" #include "lldb/Utility/Status.h" -#include <errno.h> +#include <cerrno> #include <pthread.h> using namespace lldb; using namespace lldb_private; -HostThreadPosix::HostThreadPosix() {} +HostThreadPosix::HostThreadPosix() = default; HostThreadPosix::HostThreadPosix(lldb::thread_t thread) : HostNativeThreadBase(thread) {} -HostThreadPosix::~HostThreadPosix() {} +HostThreadPosix::~HostThreadPosix() = default; Status HostThreadPosix::Join(lldb::thread_result_t *result) { Status error; diff --git a/contrib/llvm-project/lldb/source/Host/posix/PipePosix.cpp b/contrib/llvm-project/lldb/source/Host/posix/PipePosix.cpp index 7cd05a1ad2eb..a8cce573f12a 100644 --- a/contrib/llvm-project/lldb/source/Host/posix/PipePosix.cpp +++ b/contrib/llvm-project/lldb/source/Host/posix/PipePosix.cpp @@ -12,19 +12,12 @@ #include "llvm/ADT/SmallString.h" #include "llvm/Support/Errno.h" #include "llvm/Support/FileSystem.h" - -#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8)) -#ifndef _GLIBCXX_USE_NANOSLEEP -#define _GLIBCXX_USE_NANOSLEEP -#endif -#endif - #include <functional> #include <thread> -#include <errno.h> +#include <cerrno> +#include <climits> #include <fcntl.h> -#include <limits.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> diff --git a/contrib/llvm-project/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp b/contrib/llvm-project/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp index 35482341d3e6..25dcf1e592c5 100644 --- a/contrib/llvm-project/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp +++ b/contrib/llvm-project/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp @@ -15,7 +15,7 @@ #include "lldb/Utility/Log.h" #include "llvm/Support/Errno.h" -#include <limits.h> +#include <climits> #include <sys/ptrace.h> #include <sys/wait.h> #include <unistd.h> diff --git a/contrib/llvm-project/lldb/source/Initialization/SystemInitializer.cpp b/contrib/llvm-project/lldb/source/Initialization/SystemInitializer.cpp index fc460c32650d..823a905ebc4b 100644 --- a/contrib/llvm-project/lldb/source/Initialization/SystemInitializer.cpp +++ b/contrib/llvm-project/lldb/source/Initialization/SystemInitializer.cpp @@ -10,6 +10,6 @@ using namespace lldb_private; -SystemInitializer::SystemInitializer() {} +SystemInitializer::SystemInitializer() = default; -SystemInitializer::~SystemInitializer() {} +SystemInitializer::~SystemInitializer() = default; diff --git a/contrib/llvm-project/lldb/source/Initialization/SystemInitializerCommon.cpp b/contrib/llvm-project/lldb/source/Initialization/SystemInitializerCommon.cpp index d9f69f57703c..84c5a472332a 100644 --- a/contrib/llvm-project/lldb/source/Initialization/SystemInitializerCommon.cpp +++ b/contrib/llvm-project/lldb/source/Initialization/SystemInitializerCommon.cpp @@ -11,7 +11,6 @@ #include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" -#include "lldb/Host/HostInfo.h" #include "lldb/Host/Socket.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/ReproducerProvider.h" @@ -35,9 +34,11 @@ using namespace lldb_private; using namespace lldb_private::repro; -SystemInitializerCommon::SystemInitializerCommon() {} +SystemInitializerCommon::SystemInitializerCommon( + HostInfo::SharedLibraryDirectoryHelper *helper) + : m_shlib_dir_helper(helper) {} -SystemInitializerCommon::~SystemInitializerCommon() {} +SystemInitializerCommon::~SystemInitializerCommon() = default; /// Initialize the FileSystem based on the current reproducer mode. static llvm::Error InitializeFileSystem() { @@ -95,7 +96,7 @@ llvm::Error SystemInitializerCommon::Initialize() { #if defined(_WIN32) const char *disable_crash_dialog_var = getenv("LLDB_DISABLE_CRASH_DIALOG"); if (disable_crash_dialog_var && - llvm::StringRef(disable_crash_dialog_var).equals_lower("true")) { + llvm::StringRef(disable_crash_dialog_var).equals_insensitive("true")) { // This will prevent Windows from displaying a dialog box requiring user // interaction when // LLDB crashes. This is mostly useful when automating LLDB, for example @@ -125,7 +126,7 @@ llvm::Error SystemInitializerCommon::Initialize() { return e; Log::Initialize(); - HostInfo::Initialize(); + HostInfo::Initialize(m_shlib_dir_helper); llvm::Error error = Socket::Initialize(); if (error) diff --git a/contrib/llvm-project/lldb/source/Initialization/SystemLifetimeManager.cpp b/contrib/llvm-project/lldb/source/Initialization/SystemLifetimeManager.cpp index 00ab3198c363..f9de41a67535 100644 --- a/contrib/llvm-project/lldb/source/Initialization/SystemLifetimeManager.cpp +++ b/contrib/llvm-project/lldb/source/Initialization/SystemLifetimeManager.cpp @@ -15,8 +15,7 @@ using namespace lldb_private; -SystemLifetimeManager::SystemLifetimeManager() - : m_mutex(), m_initialized(false) {} +SystemLifetimeManager::SystemLifetimeManager() : m_mutex() {} SystemLifetimeManager::~SystemLifetimeManager() { assert(!m_initialized && diff --git a/contrib/llvm-project/lldb/source/Interpreter/CommandAlias.cpp b/contrib/llvm-project/lldb/source/Interpreter/CommandAlias.cpp index a5e033937210..d55b3fdd44fa 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/CommandAlias.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/CommandAlias.cpp @@ -47,7 +47,6 @@ static bool ProcessAliasOptionsArgs(lldb::CommandObjectSP &cmd_obj_sp, if (!args_or) { result.AppendError(toString(args_or.takeError())); result.AppendError("Unable to create requested alias.\n"); - result.SetStatus(eReturnStatusFailed); return false; } args = std::move(*args_or); @@ -80,7 +79,7 @@ CommandAlias::CommandAlias(CommandInterpreter &interpreter, llvm::StringRef help, llvm::StringRef syntax, uint32_t flags) : CommandObject(interpreter, name, help, syntax, flags), - m_underlying_command_sp(), m_option_string(std::string(options_args)), + m_option_string(std::string(options_args)), m_option_args_sp(new OptionArgVector), m_is_dashdash_alias(eLazyBoolCalculate), m_did_set_help(false), m_did_set_help_long(false) { diff --git a/contrib/llvm-project/lldb/source/Interpreter/CommandHistory.cpp b/contrib/llvm-project/lldb/source/Interpreter/CommandHistory.cpp index 9c7919ecc41f..8f399840b802 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/CommandHistory.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/CommandHistory.cpp @@ -6,17 +6,13 @@ // //===----------------------------------------------------------------------===// -#include <inttypes.h> +#include <cinttypes> #include "lldb/Interpreter/CommandHistory.h" using namespace lldb; using namespace lldb_private; -CommandHistory::CommandHistory() : m_mutex(), m_history() {} - -CommandHistory::~CommandHistory() {} - size_t CommandHistory::GetSize() const { std::lock_guard<std::recursive_mutex> guard(m_mutex); return m_history.size(); diff --git a/contrib/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp b/contrib/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp index fb503fe0afb0..00e9ccb762c3 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp @@ -6,9 +6,9 @@ // //===----------------------------------------------------------------------===// +#include <cstdlib> #include <limits> #include <memory> -#include <stdlib.h> #include <string> #include <vector> @@ -76,6 +76,7 @@ #include "lldb/Target/UnixSignals.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/FormatAdapters.h" #include "llvm/Support/Path.h" @@ -121,9 +122,8 @@ CommandInterpreter::CommandInterpreter(Debugger &debugger, IOHandlerDelegate(IOHandlerDelegate::Completion::LLDBCommand), m_debugger(debugger), m_synchronous_execution(true), m_skip_lldbinit_files(false), m_skip_app_init_files(false), - m_command_io_handler_sp(), m_comment_char('#'), - m_batch_command_mode(false), m_truncation_warning(eNoTruncation), - m_command_source_depth(0), m_result(), m_transcript_stream() { + m_comment_char('#'), m_batch_command_mode(false), + m_truncation_warning(eNoTruncation), m_command_source_depth(0) { SetEventName(eBroadcastBitThreadShouldExit, "thread-should-exit"); SetEventName(eBroadcastBitResetPrompt, "reset-prompt"); SetEventName(eBroadcastBitQuitCommandReceived, "quit"); @@ -160,6 +160,16 @@ void CommandInterpreter::SetSaveSessionOnQuit(bool enable) { m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, enable); } +FileSpec CommandInterpreter::GetSaveSessionDirectory() const { + const uint32_t idx = ePropertySaveSessionDirectory; + return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx); +} + +void CommandInterpreter::SetSaveSessionDirectory(llvm::StringRef path) { + const uint32_t idx = ePropertySaveSessionDirectory; + m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, path); +} + bool CommandInterpreter::GetEchoCommands() const { const uint32_t idx = ePropertyEchoCommands; return m_collection_sp->GetPropertyAtIndexAsBoolean( @@ -223,6 +233,12 @@ bool CommandInterpreter::GetSpaceReplPrompts() const { nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0); } +bool CommandInterpreter::GetRepeatPreviousCommand() const { + const uint32_t idx = ePropertyRepeatPreviousCommand; + return m_collection_sp->GetPropertyAtIndexAsBoolean( + nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0); +} + void CommandInterpreter::Initialize() { LLDB_SCOPED_TIMER(); @@ -416,17 +432,14 @@ void CommandInterpreter::Initialize() { cmd_obj_sp = GetCommandSPExact("process launch"); if (cmd_obj_sp) { alias_arguments_vector_sp = std::make_shared<OptionArgVector>(); -#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) +#if defined(__APPLE__) +#if defined(TARGET_OS_IPHONE) AddAlias("r", cmd_obj_sp, "--"); AddAlias("run", cmd_obj_sp, "--"); #else -#if defined(__APPLE__) - std::string shell_option; - shell_option.append("--shell-expand-args"); - shell_option.append(" true"); - shell_option.append(" --"); AddAlias("r", cmd_obj_sp, "--shell-expand-args true --"); AddAlias("run", cmd_obj_sp, "--shell-expand-args true --"); +#endif #else StreamString defaultshell; defaultshell.Printf("--shell=%s --", @@ -434,7 +447,6 @@ void CommandInterpreter::Initialize() { AddAlias("r", cmd_obj_sp, defaultshell.GetString()); AddAlias("run", cmd_obj_sp, defaultshell.GetString()); #endif -#endif } cmd_obj_sp = GetCommandSPExact("target symbols add"); @@ -1463,7 +1475,6 @@ CommandObject *CommandInterpreter::BuildAliasResult( "need at least %d arguments to use " "this alias.\n", index); - result.SetStatus(eReturnStatusFailed); return nullptr; } else { size_t strpos = raw_input_string.find(cmd_args.GetArgumentAtIndex(index)); @@ -1631,12 +1642,18 @@ Status CommandInterpreter::PreprocessCommand(std::string &command) { bool CommandInterpreter::HandleCommand(const char *command_line, LazyBool lazy_add_to_history, - CommandReturnObject &result, - ExecutionContext *override_context, - bool repeat_on_empty_command, - bool no_context_switching) + const ExecutionContext &override_context, + CommandReturnObject &result) { + + OverrideExecutionContext(override_context); + bool status = HandleCommand(command_line, lazy_add_to_history, result); + RestoreExecutionContext(); + return status; +} -{ +bool CommandInterpreter::HandleCommand(const char *command_line, + LazyBool lazy_add_to_history, + CommandReturnObject &result) { std::string command_string(command_line); std::string original_command_string(command_line); @@ -1648,12 +1665,8 @@ bool CommandInterpreter::HandleCommand(const char *command_line, LLDB_LOGF(log, "Processing command: %s", command_line); LLDB_SCOPED_TIMERF("Processing command: %s.", command_line); - if (!no_context_switching) - UpdateExecutionContext(override_context); - if (WasInterrupted()) { result.AppendError("interrupted"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1689,33 +1702,31 @@ bool CommandInterpreter::HandleCommand(const char *command_line, } else { result.AppendErrorWithFormat("Could not find entry: %s in history", command_string.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } } } if (empty_command) { - if (repeat_on_empty_command) { - if (m_command_history.IsEmpty()) { - result.AppendError("empty command"); - result.SetStatus(eReturnStatusFailed); - return false; - } else { - command_line = m_repeat_command.c_str(); - command_string = command_line; - original_command_string = command_line; - if (m_repeat_command.empty()) { - result.AppendError("No auto repeat."); - result.SetStatus(eReturnStatusFailed); - return false; - } - } - add_to_history = false; - } else { + if (!GetRepeatPreviousCommand()) { result.SetStatus(eReturnStatusSuccessFinishNoResult); return true; } + + if (m_command_history.IsEmpty()) { + result.AppendError("empty command"); + return false; + } + + command_line = m_repeat_command.c_str(); + command_string = command_line; + original_command_string = command_line; + if (m_repeat_command.empty()) { + result.AppendError("No auto repeat."); + return false; + } + + add_to_history = false; } else if (comment_command) { result.SetStatus(eReturnStatusSuccessFinishNoResult); return true; @@ -1725,7 +1736,6 @@ bool CommandInterpreter::HandleCommand(const char *command_line, if (error.Fail()) { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1852,8 +1862,6 @@ void CommandInterpreter::HandleCompletionMatches(CompletionRequest &request) { void CommandInterpreter::HandleCompletion(CompletionRequest &request) { - UpdateExecutionContext(nullptr); - // Don't complete comments, and if the line we are completing is just the // history repeat character, substitute the appropriate history line. llvm::StringRef first_arg = request.GetParsedLine().GetArgumentAtIndex(0); @@ -1885,8 +1893,6 @@ CommandInterpreter::GetAutoSuggestionForCommand(llvm::StringRef line) { return llvm::None; } -CommandInterpreter::~CommandInterpreter() {} - void CommandInterpreter::UpdatePrompt(llvm::StringRef new_prompt) { EventSP prompt_change_event_sp( new Event(eBroadcastBitResetPrompt, new EventDataBytes(new_prompt))); @@ -1997,7 +2003,6 @@ void CommandInterpreter::BuildAliasCommandArgs(CommandObject *alias_cmd_obj, "need at least %d arguments to use " "this alias.\n", index); - result.SetStatus(eReturnStatusFailed); return; } else { // Find and remove cmd_args.GetArgumentAtIndex(i) from raw_input_string @@ -2128,13 +2133,12 @@ void CommandInterpreter::SourceInitFile(FileSpec file, // broadcasting of the commands back to any appropriate listener (see // CommandObjectSource::Execute for more details). const bool saved_batch = SetBatchCommandMode(true); - ExecutionContext *ctx = nullptr; CommandInterpreterRunOptions options; options.SetSilent(true); options.SetPrintErrors(true); options.SetStopOnError(false); options.SetStopOnContinue(true); - HandleCommandsFromFile(file, ctx, options, result); + HandleCommandsFromFile(file, options, result); SetBatchCommandMode(saved_batch); } @@ -2168,7 +2172,6 @@ void CommandInterpreter::SourceInitFileCwd(CommandReturnObject &result) { result.SetStatus(eReturnStatusSuccessFinishNoResult); } else { result.AppendError(InitFileWarning); - result.SetStatus(eReturnStatusFailed); } } } @@ -2225,7 +2228,8 @@ PlatformSP CommandInterpreter::GetPlatform(bool prefer_target_platform) { } bool CommandInterpreter::DidProcessStopAbnormally() const { - TargetSP target_sp = m_debugger.GetTargetList().GetSelectedTarget(); + auto exe_ctx = GetExecutionContext(); + TargetSP target_sp = exe_ctx.GetTargetSP(); if (!target_sp) return false; @@ -2242,7 +2246,9 @@ bool CommandInterpreter::DidProcessStopAbnormally() const { return false; const StopReason reason = stop_info->GetStopReason(); - if (reason == eStopReasonException || reason == eStopReasonInstrumentation) + if (reason == eStopReasonException || + reason == eStopReasonInstrumentation || + reason == eStopReasonProcessorTrace) return true; if (reason == eStopReasonSignal) { @@ -2263,9 +2269,19 @@ bool CommandInterpreter::DidProcessStopAbnormally() const { return false; } +void +CommandInterpreter::HandleCommands(const StringList &commands, + const ExecutionContext &override_context, + const CommandInterpreterRunOptions &options, + CommandReturnObject &result) { + + OverrideExecutionContext(override_context); + HandleCommands(commands, options, result); + RestoreExecutionContext(); +} + void CommandInterpreter::HandleCommands(const StringList &commands, - ExecutionContext *override_context, - CommandInterpreterRunOptions &options, + const CommandInterpreterRunOptions &options, CommandReturnObject &result) { size_t num_lines = commands.GetSize(); @@ -2275,13 +2291,6 @@ void CommandInterpreter::HandleCommands(const StringList &commands, bool old_async_execution = m_debugger.GetAsyncExecution(); - // If we've been given an execution context, set it at the start, but don't - // keep resetting it or we will cause series of commands that change the - // context, then do an operation that relies on that context to fail. - - if (override_context != nullptr) - UpdateExecutionContext(override_context); - if (!options.GetStopOnContinue()) { m_debugger.SetAsyncExecution(false); } @@ -2299,20 +2308,14 @@ void CommandInterpreter::HandleCommands(const StringList &commands, CommandReturnObject tmp_result(m_debugger.GetUseColor()); tmp_result.SetInteractive(result.GetInteractive()); - - // If override_context is not NULL, pass no_context_switching = true for - // HandleCommand() since we updated our context already. + tmp_result.SetSuppressImmediateOutput(true); // We might call into a regex or alias command, in which case the // add_to_history will get lost. This m_command_source_depth dingus is the // way we turn off adding to the history in that case, so set it up here. if (!options.GetAddToHistory()) m_command_source_depth++; - bool success = - HandleCommand(cmd, options.m_add_to_history, tmp_result, - nullptr, /* override_context */ - true, /* repeat_on_empty_command */ - override_context != nullptr /* no_context_switching */); + bool success = HandleCommand(cmd, options.m_add_to_history, tmp_result); if (!options.GetAddToHistory()) m_command_source_depth--; @@ -2330,7 +2333,6 @@ void CommandInterpreter::HandleCommands(const StringList &commands, "Aborting reading of commands after command #%" PRIu64 ": '%s' failed with %s", (uint64_t)idx, cmd, error_msg.str().c_str()); - result.SetStatus(eReturnStatusFailed); m_debugger.SetAsyncExecution(old_async_execution); return; } else if (options.GetPrintResults()) { @@ -2413,13 +2415,19 @@ enum { }; void CommandInterpreter::HandleCommandsFromFile( - FileSpec &cmd_file, ExecutionContext *context, - CommandInterpreterRunOptions &options, CommandReturnObject &result) { + FileSpec &cmd_file, const ExecutionContext &context, + const CommandInterpreterRunOptions &options, CommandReturnObject &result) { + OverrideExecutionContext(context); + HandleCommandsFromFile(cmd_file, options, result); + RestoreExecutionContext(); +} + +void CommandInterpreter::HandleCommandsFromFile(FileSpec &cmd_file, + const CommandInterpreterRunOptions &options, CommandReturnObject &result) { if (!FileSystem::Instance().Exists(cmd_file)) { result.AppendErrorWithFormat( "Error reading commands from file %s - file not found.\n", cmd_file.GetFilename().AsCString("<Unknown>")); - result.SetStatus(eReturnStatusFailed); return; } @@ -2431,7 +2439,6 @@ void CommandInterpreter::HandleCommandsFromFile( result.AppendErrorWithFormatv( "error: an error occurred read file '{0}': {1}\n", cmd_file_path, llvm::fmt_consume(input_file_up.takeError())); - result.SetStatus(eReturnStatusFailed); return; } FileSP input_file_sp = FileSP(std::move(input_file_up.get())); @@ -2678,7 +2685,7 @@ void CommandInterpreter::FindCommandsForApropos( const bool search_long_help = false; const bool search_syntax = false; const bool search_options = false; - if (command_name.contains_lower(search_word) || + if (command_name.contains_insensitive(search_word) || cmd_obj->HelpTextContainsWord(search_word, search_short_help, search_long_help, search_syntax, search_options)) { @@ -2715,23 +2722,24 @@ void CommandInterpreter::FindCommandsForApropos(llvm::StringRef search_word, m_alias_dict); } -void CommandInterpreter::UpdateExecutionContext( - ExecutionContext *override_context) { - if (override_context != nullptr) { - m_exe_ctx_ref = *override_context; - } else { - const bool adopt_selected = true; - m_exe_ctx_ref.SetTargetPtr(m_debugger.GetSelectedTarget().get(), - adopt_selected); - } +ExecutionContext CommandInterpreter::GetExecutionContext() const { + return !m_overriden_exe_contexts.empty() + ? m_overriden_exe_contexts.top() + : m_debugger.GetSelectedExecutionContext(); } -void CommandInterpreter::GetProcessOutput() { - TargetSP target_sp(m_debugger.GetTargetList().GetSelectedTarget()); - if (!target_sp) - return; +void CommandInterpreter::OverrideExecutionContext( + const ExecutionContext &override_context) { + m_overriden_exe_contexts.push(override_context); +} + +void CommandInterpreter::RestoreExecutionContext() { + if (!m_overriden_exe_contexts.empty()) + m_overriden_exe_contexts.pop(); +} - if (ProcessSP process_sp = target_sp->GetProcessSP()) +void CommandInterpreter::GetProcessOutput() { + if (ProcessSP process_sp = GetExecutionContext().GetProcessSP()) m_debugger.FlushProcessOutput(*process_sp, /*flush_stdout*/ true, /*flush_stderr*/ true); } @@ -2831,6 +2839,11 @@ void CommandInterpreter::IOHandlerInputComplete(IOHandler &io_handler, StartHandlingCommand(); + OverrideExecutionContext(m_debugger.GetSelectedExecutionContext()); + auto finalize = llvm::make_scope_exit([this]() { + RestoreExecutionContext(); + }); + lldb_private::CommandReturnObject result(m_debugger.GetUseColor()); HandleCommand(line.c_str(), eLazyBoolCalculate, result); @@ -2922,9 +2935,15 @@ bool CommandInterpreter::SaveTranscript( std::string now = llvm::to_string(std::chrono::system_clock::now()); std::replace(now.begin(), now.end(), ' ', '_'); const std::string file_name = "lldb_session_" + now + ".log"; - FileSpec tmp = HostInfo::GetGlobalTempDir(); - tmp.AppendPathComponent(file_name); - output_file = tmp.GetPath(); + + FileSpec save_location = GetSaveSessionDirectory(); + + if (!save_location) + save_location = HostInfo::GetGlobalTempDir(); + + FileSystem::Instance().Resolve(save_location); + save_location.AppendPathComponent(file_name); + output_file = save_location.GetPath(); } auto error_out = [&](llvm::StringRef error_message, std::string description) { @@ -2955,6 +2974,7 @@ bool CommandInterpreter::SaveTranscript( return error_out("Unable to write to destination file", "Bytes written do not match transcript size."); + result.SetStatus(eReturnStatusSuccessFinishNoResult); result.AppendMessageWithFormat("Session's transcripts saved to %s\n", output_file->c_str()); @@ -2973,9 +2993,9 @@ void CommandInterpreter::GetLLDBCommandsFromIOHandler( IOHandlerSP io_handler_sp( new IOHandlerEditline(debugger, IOHandler::Type::CommandList, "lldb", // Name of input reader for history - llvm::StringRef::withNullAsEmpty(prompt), // Prompt - llvm::StringRef(), // Continuation prompt - true, // Get multiple lines + llvm::StringRef(prompt), // Prompt + llvm::StringRef(), // Continuation prompt + true, // Get multiple lines debugger.GetUseColor(), 0, // Don't show line numbers delegate, // IOHandlerDelegate @@ -2993,9 +3013,9 @@ void CommandInterpreter::GetPythonCommandsFromIOHandler( IOHandlerSP io_handler_sp( new IOHandlerEditline(debugger, IOHandler::Type::PythonCode, "lldb-python", // Name of input reader for history - llvm::StringRef::withNullAsEmpty(prompt), // Prompt - llvm::StringRef(), // Continuation prompt - true, // Get multiple lines + llvm::StringRef(prompt), // Prompt + llvm::StringRef(), // Continuation prompt + true, // Get multiple lines debugger.GetUseColor(), 0, // Don't show line numbers delegate, // IOHandlerDelegate @@ -3088,7 +3108,6 @@ CommandInterpreter::ResolveCommandImpl(std::string &command_line, CommandObject *cmd_obj = nullptr; StreamString revised_command_line; bool wants_raw_input = false; - size_t actual_cmd_name_len = 0; std::string next_word; StringList matches; bool done = false; @@ -3110,12 +3129,10 @@ CommandInterpreter::ResolveCommandImpl(std::string &command_line, revised_command_line.Printf("%s", alias_result.c_str()); if (cmd_obj) { wants_raw_input = cmd_obj->WantsRawCommandString(); - actual_cmd_name_len = cmd_obj->GetCommandName().size(); } } else { if (cmd_obj) { llvm::StringRef cmd_name = cmd_obj->GetCommandName(); - actual_cmd_name_len += cmd_name.size(); revised_command_line.Printf("%s", cmd_name.str().c_str()); wants_raw_input = cmd_obj->WantsRawCommandString(); } else { @@ -3130,7 +3147,6 @@ CommandInterpreter::ResolveCommandImpl(std::string &command_line, // The subcommand's name includes the parent command's name, so // restart rather than append to the revised_command_line. llvm::StringRef sub_cmd_name = sub_cmd_obj->GetCommandName(); - actual_cmd_name_len = sub_cmd_name.size() + 1; revised_command_line.Clear(); revised_command_line.Printf("%s", sub_cmd_name.str().c_str()); cmd_obj = sub_cmd_obj; @@ -3174,7 +3190,6 @@ CommandInterpreter::ResolveCommandImpl(std::string &command_line, result.AppendErrorWithFormat("'%s' is not a valid command.\n", next_word.c_str()); } - result.SetStatus(eReturnStatusFailed); return nullptr; } @@ -3186,7 +3201,6 @@ CommandInterpreter::ResolveCommandImpl(std::string &command_line, cmd_obj->GetCommandName().str().c_str(), next_word.empty() ? "" : next_word.c_str(), next_word.empty() ? " -- " : " ", suffix.c_str()); - result.SetStatus(eReturnStatusFailed); return nullptr; } } else { @@ -3222,7 +3236,6 @@ CommandInterpreter::ResolveCommandImpl(std::string &command_line, result.AppendErrorWithFormat( "the '%s' command doesn't support the --gdb-format option\n", cmd_obj->GetCommandName().str().c_str()); - result.SetStatus(eReturnStatusFailed); return nullptr; } } @@ -3231,7 +3244,6 @@ CommandInterpreter::ResolveCommandImpl(std::string &command_line, default: result.AppendErrorWithFormat( "unknown command shorthand suffix: '%s'\n", suffix.c_str()); - result.SetStatus(eReturnStatusFailed); return nullptr; } } diff --git a/contrib/llvm-project/lldb/source/Interpreter/CommandObject.cpp b/contrib/llvm-project/lldb/source/Interpreter/CommandObject.cpp index 71adf8c39f1b..a7dcd5682701 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/CommandObject.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/CommandObject.cpp @@ -12,8 +12,8 @@ #include <sstream> #include <string> -#include <ctype.h> -#include <stdlib.h> +#include <cctype> +#include <cstdlib> #include "lldb/Core/Address.h" #include "lldb/Interpreter/Options.h" @@ -42,15 +42,12 @@ CommandObject::CommandObject(CommandInterpreter &interpreter, llvm::StringRef name, llvm::StringRef help, llvm::StringRef syntax, uint32_t flags) : m_interpreter(interpreter), m_cmd_name(std::string(name)), - m_cmd_help_short(), m_cmd_help_long(), m_cmd_syntax(), m_flags(flags), - m_arguments(), m_deprecated_command_override_callback(nullptr), + m_flags(flags), m_deprecated_command_override_callback(nullptr), m_command_override_callback(nullptr), m_command_override_baton(nullptr) { m_cmd_help_short = std::string(help); m_cmd_syntax = std::string(syntax); } -CommandObject::~CommandObject() {} - Debugger &CommandObject::GetDebugger() { return m_interpreter.GetDebugger(); } llvm::StringRef CommandObject::GetHelp() { return m_cmd_help_short; } @@ -222,7 +219,6 @@ bool CommandObject::CheckRequirements(CommandReturnObject &result) { // A process that is not running is considered paused. if (GetFlags().Test(eCommandProcessMustBeLaunched)) { result.AppendError("Process must exist."); - result.SetStatus(eReturnStatusFailed); return false; } } else { @@ -242,7 +238,6 @@ bool CommandObject::CheckRequirements(CommandReturnObject &result) { case eStateUnloaded: if (GetFlags().Test(eCommandProcessMustBeLaunched)) { result.AppendError("Process must be launched."); - result.SetStatus(eReturnStatusFailed); return false; } break; @@ -252,7 +247,6 @@ bool CommandObject::CheckRequirements(CommandReturnObject &result) { if (GetFlags().Test(eCommandProcessMustBePaused)) { result.AppendError("Process is running. Use 'process interrupt' to " "pause execution."); - result.SetStatus(eReturnStatusFailed); return false; } } @@ -262,7 +256,7 @@ bool CommandObject::CheckRequirements(CommandReturnObject &result) { if (GetFlags().Test(eCommandProcessMustBeTraced)) { Target *target = m_exe_ctx.GetTargetPtr(); if (target && !target->GetTrace()) { - result.SetError("Process is not being traced."); + result.AppendError("Process is not being traced."); return false; } } @@ -322,11 +316,11 @@ bool CommandObject::HelpTextContainsWord(llvm::StringRef search_word, llvm::StringRef long_help = GetHelpLong(); llvm::StringRef syntax_help = GetSyntax(); - if (search_short_help && short_help.contains_lower(search_word)) + if (search_short_help && short_help.contains_insensitive(search_word)) found_word = true; - else if (search_long_help && long_help.contains_lower(search_word)) + else if (search_long_help && long_help.contains_insensitive(search_word)) found_word = true; - else if (search_syntax && syntax_help.contains_lower(search_word)) + else if (search_syntax && syntax_help.contains_insensitive(search_word)) found_word = true; if (!found_word && search_options && GetOptions() != nullptr) { @@ -336,7 +330,7 @@ bool CommandObject::HelpTextContainsWord(llvm::StringRef search_word, GetCommandInterpreter().GetDebugger().GetTerminalWidth()); if (!usage_help.Empty()) { llvm::StringRef usage_text = usage_help.GetString(); - if (usage_text.contains_lower(search_word)) + if (usage_text.contains_insensitive(search_word)) found_word = true; } } @@ -354,7 +348,6 @@ bool CommandObject::ParseOptionsAndNotify(Args &args, Status error(group_options.NotifyOptionParsingFinished(&exe_ctx)); if (error.Fail()) { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } return true; @@ -1129,7 +1122,8 @@ CommandObject::ArgumentTableEntry CommandObject::g_arguments_data[] = { { eArgRawInput, "raw-input", CommandCompletions::eNoCompletion, { nullptr, false }, "Free-form text passed to a command without prior interpretation, allowing spaces without requiring quotes. To pass arguments and free form text put two dashes ' -- ' between the last argument and any raw input." }, { eArgTypeCommand, "command", CommandCompletions::eNoCompletion, { nullptr, false }, "An LLDB Command line command." }, { eArgTypeColumnNum, "column", CommandCompletions::eNoCompletion, { nullptr, false }, "Column number in a source file." }, - { eArgTypeModuleUUID, "module-uuid", CommandCompletions::eModuleUUIDCompletion, { nullptr, false }, "A module UUID value." } + { eArgTypeModuleUUID, "module-uuid", CommandCompletions::eModuleUUIDCompletion, { nullptr, false }, "A module UUID value." }, + { eArgTypeSaveCoreStyle, "corefile-style", CommandCompletions::eNoCompletion, { nullptr, false }, "The type of corefile that lldb will try to create, dependant on this target's capabilities." } // clang-format on }; diff --git a/contrib/llvm-project/lldb/source/Interpreter/CommandReturnObject.cpp b/contrib/llvm-project/lldb/source/Interpreter/CommandReturnObject.cpp index 6f3732e35078..506b0d6e7cde 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/CommandReturnObject.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/CommandReturnObject.cpp @@ -41,13 +41,11 @@ static void DumpStringToStreamWithNewline(Stream &strm, const std::string &s) { } CommandReturnObject::CommandReturnObject(bool colors) - : m_out_stream(colors), m_err_stream(colors), - m_status(eReturnStatusStarted), m_did_change_process_state(false), - m_interactive(true) {} - -CommandReturnObject::~CommandReturnObject() {} + : m_out_stream(colors), m_err_stream(colors) {} void CommandReturnObject::AppendErrorWithFormat(const char *format, ...) { + SetStatus(eReturnStatusFailed); + if (!format) return; va_list args; @@ -90,52 +88,33 @@ void CommandReturnObject::AppendWarningWithFormat(const char *format, ...) { void CommandReturnObject::AppendMessage(llvm::StringRef in_string) { if (in_string.empty()) return; - GetOutputStream() << in_string << "\n"; + GetOutputStream() << in_string.rtrim() << '\n'; } void CommandReturnObject::AppendWarning(llvm::StringRef in_string) { if (in_string.empty()) return; - warning(GetErrorStream()) << in_string << '\n'; -} - -// Similar to AppendWarning, but do not prepend 'warning: ' to message, and -// don't append "\n" to the end of it. - -void CommandReturnObject::AppendRawWarning(llvm::StringRef in_string) { - if (in_string.empty()) - return; - GetErrorStream() << in_string; + warning(GetErrorStream()) << in_string.rtrim() << '\n'; } void CommandReturnObject::AppendError(llvm::StringRef in_string) { + SetStatus(eReturnStatusFailed); if (in_string.empty()) return; - error(GetErrorStream()) << in_string << '\n'; + error(GetErrorStream()) << in_string.rtrim() << '\n'; } void CommandReturnObject::SetError(const Status &error, const char *fallback_error_cstr) { - const char *error_cstr = error.AsCString(); - if (error_cstr == nullptr) - error_cstr = fallback_error_cstr; - SetError(error_cstr); -} - -void CommandReturnObject::SetError(llvm::StringRef error_str) { - if (error_str.empty()) - return; - - AppendError(error_str); - SetStatus(eReturnStatusFailed); + AppendError(error.AsCString(fallback_error_cstr)); } // Similar to AppendError, but do not prepend 'Status: ' to message, and don't // append "\n" to the end of it. void CommandReturnObject::AppendRawError(llvm::StringRef in_string) { - if (in_string.empty()) - return; + SetStatus(eReturnStatusFailed); + assert(!in_string.empty() && "Expected a non-empty error message"); GetErrorStream() << in_string; } @@ -162,6 +141,7 @@ void CommandReturnObject::Clear() { static_cast<StreamString *>(stream_sp.get())->Clear(); m_status = eReturnStatusStarted; m_did_change_process_state = false; + m_suppress_immediate_output = false; m_interactive = true; } @@ -176,3 +156,11 @@ void CommandReturnObject::SetDidChangeProcessState(bool b) { bool CommandReturnObject::GetInteractive() const { return m_interactive; } void CommandReturnObject::SetInteractive(bool b) { m_interactive = b; } + +bool CommandReturnObject::GetSuppressImmediateOutput() const { + return m_suppress_immediate_output; +} + +void CommandReturnObject::SetSuppressImmediateOutput(bool b) { + m_suppress_immediate_output = b; +} diff --git a/contrib/llvm-project/lldb/source/Interpreter/InterpreterProperties.td b/contrib/llvm-project/lldb/source/Interpreter/InterpreterProperties.td index e5346d14a6e1..1c6f0206c489 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/InterpreterProperties.td +++ b/contrib/llvm-project/lldb/source/Interpreter/InterpreterProperties.td @@ -13,6 +13,9 @@ let Definition = "interpreter" in { Global, DefaultFalse, Desc<"If true, LLDB will save the session's transcripts before quitting.">; + def SaveSessionDirectory: Property<"save-session-directory", "FileSpec">, + DefaultStringValue<"">, + Desc<"A path where LLDB will save the session's transcripts. This is particularly useful when you can't set the session file, for example when using `save-session-on-quit`.">; def StopCmdSourceOnError: Property<"stop-command-source-on-error", "Boolean">, Global, DefaultTrue, @@ -29,4 +32,8 @@ let Definition = "interpreter" in { Global, DefaultTrue, Desc<"If true, commands will be echoed even if they are pure comment lines.">; + def RepeatPreviousCommand: Property<"repeat-previous-command", "Boolean">, + Global, + DefaultTrue, + Desc<"If true, LLDB will repeat the previous command if no command was passed to the interpreter. If false, LLDB won't repeat the previous command but only return a new prompt.">; } diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionArgParser.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionArgParser.cpp index 3dcb30e846d9..93b01abde4bb 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionArgParser.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionArgParser.cpp @@ -20,11 +20,11 @@ bool OptionArgParser::ToBoolean(llvm::StringRef ref, bool fail_value, if (success_ptr) *success_ptr = true; ref = ref.trim(); - if (ref.equals_lower("false") || ref.equals_lower("off") || - ref.equals_lower("no") || ref.equals_lower("0")) { + if (ref.equals_insensitive("false") || ref.equals_insensitive("off") || + ref.equals_insensitive("no") || ref.equals_insensitive("0")) { return false; - } else if (ref.equals_lower("true") || ref.equals_lower("on") || - ref.equals_lower("yes") || ref.equals_lower("1")) { + } else if (ref.equals_insensitive("true") || ref.equals_insensitive("on") || + ref.equals_insensitive("yes") || ref.equals_insensitive("1")) { return true; } if (success_ptr) @@ -125,13 +125,13 @@ lldb::ScriptLanguage OptionArgParser::ToScriptLanguage( if (success_ptr) *success_ptr = true; - if (s.equals_lower("python")) + if (s.equals_insensitive("python")) return eScriptLanguagePython; - if (s.equals_lower("lua")) + if (s.equals_insensitive("lua")) return eScriptLanguageLua; - if (s.equals_lower("default")) + if (s.equals_insensitive("default")) return eScriptLanguageDefault; - if (s.equals_lower("none")) + if (s.equals_insensitive("none")) return eScriptLanguageNone; if (success_ptr) diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupArchitecture.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupArchitecture.cpp index baca1c6e8068..00541b7198d2 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupArchitecture.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupArchitecture.cpp @@ -13,10 +13,6 @@ using namespace lldb; using namespace lldb_private; -OptionGroupArchitecture::OptionGroupArchitecture() : m_arch_str() {} - -OptionGroupArchitecture::~OptionGroupArchitecture() {} - static constexpr OptionDefinition g_option_table[] = { {LLDB_OPT_SET_1, false, "arch", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeArchitecture, diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupBoolean.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupBoolean.cpp index 3482e784ca0c..3f73893fca96 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupBoolean.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupBoolean.cpp @@ -33,8 +33,6 @@ OptionGroupBoolean::OptionGroupBoolean(uint32_t usage_mask, bool required, m_option_definition.usage_text = usage_text; } -OptionGroupBoolean::~OptionGroupBoolean() {} - Status OptionGroupBoolean::SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) { diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupFile.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupFile.cpp index 9d9be5b6f178..12ade1855829 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupFile.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupFile.cpp @@ -17,8 +17,7 @@ OptionGroupFile::OptionGroupFile(uint32_t usage_mask, bool required, const char *long_option, int short_option, uint32_t completion_type, lldb::CommandArgumentType argument_type, - const char *usage_text) - : m_file() { + const char *usage_text) { m_option_definition.usage_mask = usage_mask; m_option_definition.required = required; m_option_definition.long_option = long_option; @@ -31,8 +30,6 @@ OptionGroupFile::OptionGroupFile(uint32_t usage_mask, bool required, m_option_definition.usage_text = usage_text; } -OptionGroupFile::~OptionGroupFile() {} - Status OptionGroupFile::SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) { @@ -62,7 +59,7 @@ OptionGroupFileList::OptionGroupFileList( m_option_definition.usage_text = usage_text; } -OptionGroupFileList::~OptionGroupFileList() {} +OptionGroupFileList::~OptionGroupFileList() = default; Status OptionGroupFileList::SetOptionValue(uint32_t option_idx, diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupFormat.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupFormat.cpp index 0052f72b0550..1cc5e70282c1 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupFormat.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupFormat.cpp @@ -24,8 +24,6 @@ OptionGroupFormat::OptionGroupFormat(lldb::Format default_format, m_count(default_count, default_count), m_prev_gdb_format('x'), m_prev_gdb_size('w') {} -OptionGroupFormat::~OptionGroupFormat() {} - static constexpr OptionDefinition g_option_table[] = { {LLDB_OPT_SET_1, false, "format", 'f', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFormat, diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupOutputFile.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupOutputFile.cpp index 65105c3e0180..6a626bd63014 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupOutputFile.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupOutputFile.cpp @@ -13,10 +13,7 @@ using namespace lldb; using namespace lldb_private; -OptionGroupOutputFile::OptionGroupOutputFile() - : m_file(), m_append(false, false) {} - -OptionGroupOutputFile::~OptionGroupOutputFile() {} +OptionGroupOutputFile::OptionGroupOutputFile() : m_append(false, false) {} static const uint32_t SHORT_OPTION_APND = 0x61706e64; // 'apnd' diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupPythonClassWithDict.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupPythonClassWithDict.cpp index 217dab2ef63b..a01c190266dd 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupPythonClassWithDict.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupPythonClassWithDict.cpp @@ -13,12 +13,10 @@ using namespace lldb; using namespace lldb_private; -OptionGroupPythonClassWithDict::OptionGroupPythonClassWithDict - (const char *class_use, - bool is_class, - int class_option, - int key_option, - int value_option) : OptionGroup(), m_is_class(is_class) { +OptionGroupPythonClassWithDict::OptionGroupPythonClassWithDict( + const char *class_use, bool is_class, int class_option, int key_option, + int value_option, uint16_t required_options) + : m_is_class(is_class), m_required_options(required_options) { m_key_usage_text.assign("The key for a key/value pair passed to the " "implementation of a "); m_key_usage_text.append(class_use); @@ -36,7 +34,7 @@ OptionGroupPythonClassWithDict::OptionGroupPythonClassWithDict m_class_usage_text.append("."); m_option_definition[0].usage_mask = LLDB_OPT_SET_1; - m_option_definition[0].required = true; + m_option_definition[0].required = m_required_options.Test(eScriptClass); m_option_definition[0].long_option = "script-class"; m_option_definition[0].short_option = class_option; m_option_definition[0].validator = nullptr; @@ -47,7 +45,7 @@ OptionGroupPythonClassWithDict::OptionGroupPythonClassWithDict m_option_definition[0].usage_text = m_class_usage_text.data(); m_option_definition[1].usage_mask = LLDB_OPT_SET_2; - m_option_definition[1].required = false; + m_option_definition[1].required = m_required_options.Test(eDictKey); m_option_definition[1].long_option = "structured-data-key"; m_option_definition[1].short_option = key_option; m_option_definition[1].validator = nullptr; @@ -58,7 +56,7 @@ OptionGroupPythonClassWithDict::OptionGroupPythonClassWithDict m_option_definition[1].usage_text = m_key_usage_text.data(); m_option_definition[2].usage_mask = LLDB_OPT_SET_2; - m_option_definition[2].required = false; + m_option_definition[2].required = m_required_options.Test(eDictValue); m_option_definition[2].long_option = "structured-data-value"; m_option_definition[2].short_option = value_option; m_option_definition[2].validator = nullptr; @@ -69,7 +67,7 @@ OptionGroupPythonClassWithDict::OptionGroupPythonClassWithDict m_option_definition[2].usage_text = m_value_usage_text.data(); m_option_definition[3].usage_mask = LLDB_OPT_SET_3; - m_option_definition[3].required = true; + m_option_definition[3].required = m_required_options.Test(ePythonFunction); m_option_definition[3].long_option = "python-function"; m_option_definition[3].short_option = class_option; m_option_definition[3].validator = nullptr; @@ -78,11 +76,8 @@ OptionGroupPythonClassWithDict::OptionGroupPythonClassWithDict m_option_definition[3].completion_type = 0; m_option_definition[3].argument_type = eArgTypePythonFunction; m_option_definition[3].usage_text = m_class_usage_text.data(); - } -OptionGroupPythonClassWithDict::~OptionGroupPythonClassWithDict() {} - Status OptionGroupPythonClassWithDict::SetOptionValue( uint32_t option_idx, llvm::StringRef option_arg, diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupString.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupString.cpp index c9f78eb953f4..75faaac9f6dd 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupString.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupString.cpp @@ -32,8 +32,6 @@ OptionGroupString::OptionGroupString(uint32_t usage_mask, bool required, m_option_definition.usage_text = usage_text; } -OptionGroupString::~OptionGroupString() {} - Status OptionGroupString::SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) { diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupUInt64.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupUInt64.cpp index 309855d4718c..486941a7555a 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupUInt64.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupUInt64.cpp @@ -32,8 +32,6 @@ OptionGroupUInt64::OptionGroupUInt64(uint32_t usage_mask, bool required, m_option_definition.usage_text = usage_text; } -OptionGroupUInt64::~OptionGroupUInt64() {} - Status OptionGroupUInt64::SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) { diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupUUID.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupUUID.cpp index dc6f4139896f..5b4c24a0a32b 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupUUID.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupUUID.cpp @@ -13,10 +13,6 @@ using namespace lldb; using namespace lldb_private; -OptionGroupUUID::OptionGroupUUID() : m_uuid() {} - -OptionGroupUUID::~OptionGroupUUID() {} - static constexpr OptionDefinition g_option_table[] = { {LLDB_OPT_SET_1, false, "uuid", 'u', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeModuleUUID, "A module UUID value."}, diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp index e0401f8987ad..04861b539650 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp @@ -19,10 +19,6 @@ using namespace lldb; using namespace lldb_private; -OptionGroupValueObjectDisplay::OptionGroupValueObjectDisplay() {} - -OptionGroupValueObjectDisplay::~OptionGroupValueObjectDisplay() {} - static const OptionDefinition g_option_table[] = { {LLDB_OPT_SET_1, false, "dynamic-type", 'd', OptionParser::eRequiredArgument, nullptr, GetDynamicValueTypes(), 0, diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupVariable.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupVariable.cpp index 9f57dbbd073e..20a521b8e44f 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupVariable.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupVariable.cpp @@ -67,10 +67,8 @@ static Status ValidateSummaryString(const char *str, void *) { } OptionGroupVariable::OptionGroupVariable(bool show_frame_options) - : OptionGroup(), include_frame_options(show_frame_options), - summary(ValidateNamedSummary), summary_string(ValidateSummaryString) {} - -OptionGroupVariable::~OptionGroupVariable() {} + : include_frame_options(show_frame_options), summary(ValidateNamedSummary), + summary_string(ValidateSummaryString) {} Status OptionGroupVariable::SetOptionValue(uint32_t option_idx, diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupWatchpoint.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupWatchpoint.cpp index 07013b5b78fe..eb9842add28c 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupWatchpoint.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupWatchpoint.cpp @@ -74,10 +74,6 @@ bool OptionGroupWatchpoint::IsWatchSizeSupported(uint32_t watch_size) { return false; } -OptionGroupWatchpoint::OptionGroupWatchpoint() : OptionGroup() {} - -OptionGroupWatchpoint::~OptionGroupWatchpoint() {} - Status OptionGroupWatchpoint::SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValue.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValue.cpp index 0bd9a591af67..79bdf74b6fd9 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValue.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValue.cpp @@ -543,8 +543,7 @@ lldb::OptionValueSP OptionValue::CreateValueFromCStringForTypeMask( } if (value_sp) - error = value_sp->SetValueFromString( - llvm::StringRef::withNullAsEmpty(value_cstr), eVarSetOperationAssign); + error = value_sp->SetValueFromString(value_cstr, eVarSetOperationAssign); else error.SetErrorString("unsupported type mask"); return value_sp; @@ -568,6 +567,12 @@ bool OptionValue::DumpQualifiedName(Stream &strm) const { return dumped_something; } +OptionValueSP OptionValue::DeepCopy(const OptionValueSP &new_parent) const { + auto clone = Clone(); + clone->SetParent(new_parent); + return clone; +} + void OptionValue::AutoComplete(CommandInterpreter &interpreter, CompletionRequest &request) {} diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueArch.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueArch.cpp index ac78ee64a9d7..4d1e2c7869f3 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueArch.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueArch.cpp @@ -64,10 +64,6 @@ Status OptionValueArch::SetValueFromString(llvm::StringRef value, return error; } -lldb::OptionValueSP OptionValueArch::DeepCopy() const { - return OptionValueSP(new OptionValueArch(*this)); -} - void OptionValueArch::AutoComplete(CommandInterpreter &interpreter, CompletionRequest &request) { CommandCompletions::InvokeCommonCompletionCallbacks( diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueArgs.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueArgs.cpp index 9e7774a231c7..bdb5f486835a 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueArgs.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueArgs.cpp @@ -13,9 +13,9 @@ using namespace lldb; using namespace lldb_private; -size_t OptionValueArgs::GetArgs(Args &args) { +size_t OptionValueArgs::GetArgs(Args &args) const { args.Clear(); - for (auto value : m_values) { + for (const auto &value : m_values) { llvm::StringRef string_value = value->GetStringValue(); if (!string_value.empty()) args.AppendArgument(string_value); diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueArray.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueArray.cpp index 0b293ccfc248..b1545bdebf10 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueArray.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueArray.cpp @@ -303,15 +303,16 @@ Status OptionValueArray::SetArgs(const Args &args, VarSetOperationType op) { return error; } -lldb::OptionValueSP OptionValueArray::DeepCopy() const { - OptionValueArray *copied_array = - new OptionValueArray(m_type_mask, m_raw_value_dump); - lldb::OptionValueSP copied_value_sp(copied_array); - *static_cast<OptionValue *>(copied_array) = *this; - copied_array->m_callback = m_callback; - const uint32_t size = m_values.size(); - for (uint32_t i = 0; i < size; ++i) { - copied_array->AppendValue(m_values[i]->DeepCopy()); - } - return copied_value_sp; +OptionValueSP +OptionValueArray::DeepCopy(const OptionValueSP &new_parent) const { + auto copy_sp = OptionValue::DeepCopy(new_parent); + // copy_sp->GetAsArray cannot be used here as it doesn't work for derived + // types that override GetType returning a different value. + auto *array_value_ptr = static_cast<OptionValueArray *>(copy_sp.get()); + lldbassert(array_value_ptr); + + for (auto &value : array_value_ptr->m_values) + value = value->DeepCopy(copy_sp); + + return copy_sp; } diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueBoolean.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueBoolean.cpp index 24ae3f673bf9..62845c14bd13 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueBoolean.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueBoolean.cpp @@ -67,10 +67,6 @@ Status OptionValueBoolean::SetValueFromString(llvm::StringRef value_str, return error; } -lldb::OptionValueSP OptionValueBoolean::DeepCopy() const { - return OptionValueSP(new OptionValueBoolean(*this)); -} - void OptionValueBoolean::AutoComplete(CommandInterpreter &interpreter, CompletionRequest &request) { llvm::StringRef autocomplete_entries[] = {"true", "false", "on", "off", diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueChar.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueChar.cpp index af9a371f46d4..7fe72c9aa221 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueChar.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueChar.cpp @@ -57,7 +57,3 @@ Status OptionValueChar::SetValueFromString(llvm::StringRef value, } return error; } - -lldb::OptionValueSP OptionValueChar::DeepCopy() const { - return OptionValueSP(new OptionValueChar(*this)); -} diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueDictionary.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueDictionary.cpp index 79323f502d17..26fed4a987e1 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueDictionary.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueDictionary.cpp @@ -311,15 +311,16 @@ bool OptionValueDictionary::DeleteValueForKey(ConstString key) { return false; } -lldb::OptionValueSP OptionValueDictionary::DeepCopy() const { - OptionValueDictionary *copied_dict = - new OptionValueDictionary(m_type_mask, m_raw_value_dump); - lldb::OptionValueSP copied_value_sp(copied_dict); - collection::const_iterator pos, end = m_values.end(); - for (pos = m_values.begin(); pos != end; ++pos) { - StreamString strm; - strm.Printf("%s=", pos->first.GetCString()); - copied_dict->SetValueForKey(pos->first, pos->second->DeepCopy(), true); - } - return copied_value_sp; +OptionValueSP +OptionValueDictionary::DeepCopy(const OptionValueSP &new_parent) const { + auto copy_sp = OptionValue::DeepCopy(new_parent); + // copy_sp->GetAsDictionary cannot be used here as it doesn't work for derived + // types that override GetType returning a different value. + auto *dict_value_ptr = static_cast<OptionValueDictionary *>(copy_sp.get()); + lldbassert(dict_value_ptr); + + for (auto &value : dict_value_ptr->m_values) + value.second = value.second->DeepCopy(copy_sp); + + return copy_sp; } diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueEnumeration.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueEnumeration.cpp index 9a1e08d4fba0..f75519c577c5 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueEnumeration.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueEnumeration.cpp @@ -15,13 +15,10 @@ using namespace lldb_private; OptionValueEnumeration::OptionValueEnumeration( const OptionEnumValues &enumerators, enum_type value) - : OptionValue(), m_current_value(value), m_default_value(value), - m_enumerations() { + : m_current_value(value), m_default_value(value) { SetEnumerations(enumerators); } -OptionValueEnumeration::~OptionValueEnumeration() {} - void OptionValueEnumeration::DumpValue(const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) { if (dump_mask & eDumpOptionType) @@ -98,10 +95,6 @@ void OptionValueEnumeration::SetEnumerations( m_enumerations.Sort(); } -lldb::OptionValueSP OptionValueEnumeration::DeepCopy() const { - return OptionValueSP(new OptionValueEnumeration(*this)); -} - void OptionValueEnumeration::AutoComplete(CommandInterpreter &interpreter, CompletionRequest &request) { const uint32_t num_enumerators = m_enumerations.GetSize(); diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileColonLine.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileColonLine.cpp index dac557c4248a..fb0b516c8616 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileColonLine.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileColonLine.cpp @@ -21,13 +21,10 @@ using namespace lldb_private; // I set the completer to "source file" which isn't quite right, but we can // only usefully complete in the file name part of it so it should be good // enough. -OptionValueFileColonLine::OptionValueFileColonLine() - : OptionValue(), m_file_spec(), m_line_number(LLDB_INVALID_LINE_NUMBER), - m_column_number(LLDB_INVALID_COLUMN_NUMBER), - m_completion_mask(CommandCompletions::eSourceFileCompletion) {} +OptionValueFileColonLine::OptionValueFileColonLine() = default; OptionValueFileColonLine::OptionValueFileColonLine(llvm::StringRef input) - : OptionValue(), m_file_spec(), m_line_number(LLDB_INVALID_LINE_NUMBER), + : m_line_number(LLDB_INVALID_LINE_NUMBER), m_column_number(LLDB_INVALID_COLUMN_NUMBER), m_completion_mask(CommandCompletions::eSourceFileCompletion) { SetValueFromString(input, eVarSetOperationAssign); @@ -92,8 +89,8 @@ Status OptionValueFileColonLine::SetValueFromString(llvm::StringRef value, llvm::StringRef middle_piece; std::tie(file_name, middle_piece) = left_of_last_piece.rsplit(':'); - if (middle_piece.empty() || !llvm::to_integer(middle_piece, - m_line_number)) { + if (middle_piece.empty() || + !llvm::to_integer(middle_piece, m_line_number)) { // The middle piece was empty or not an integer, so there were only two // legit pieces; our original division was right. Reassign the file // name and pull out the line number: @@ -134,10 +131,6 @@ Status OptionValueFileColonLine::SetValueFromString(llvm::StringRef value, return error; } -lldb::OptionValueSP OptionValueFileColonLine::DeepCopy() const { - return OptionValueSP(new OptionValueFileColonLine(*this)); -} - void OptionValueFileColonLine::AutoComplete(CommandInterpreter &interpreter, CompletionRequest &request) { CommandCompletions::InvokeCommonCompletionCallbacks( diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileSpec.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileSpec.cpp index a03fd55d0385..3987a36b1b65 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileSpec.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileSpec.cpp @@ -18,23 +18,17 @@ using namespace lldb; using namespace lldb_private; -OptionValueFileSpec::OptionValueFileSpec(bool resolve) - : OptionValue(), m_current_value(), m_default_value(), m_data_sp(), - m_data_mod_time(), - m_completion_mask(CommandCompletions::eDiskFileCompletion), - m_resolve(resolve) {} +OptionValueFileSpec::OptionValueFileSpec(bool resolve) : m_resolve(resolve) {} OptionValueFileSpec::OptionValueFileSpec(const FileSpec &value, bool resolve) - : OptionValue(), m_current_value(value), m_default_value(value), - m_data_sp(), m_data_mod_time(), + : m_current_value(value), m_default_value(value), m_completion_mask(CommandCompletions::eDiskFileCompletion), m_resolve(resolve) {} OptionValueFileSpec::OptionValueFileSpec(const FileSpec ¤t_value, const FileSpec &default_value, bool resolve) - : OptionValue(), m_current_value(current_value), - m_default_value(default_value), m_data_sp(), m_data_mod_time(), + : m_current_value(current_value), m_default_value(default_value), m_completion_mask(CommandCompletions::eDiskFileCompletion), m_resolve(resolve) {} @@ -88,10 +82,6 @@ Status OptionValueFileSpec::SetValueFromString(llvm::StringRef value, return error; } -lldb::OptionValueSP OptionValueFileSpec::DeepCopy() const { - return OptionValueSP(new OptionValueFileSpec(*this)); -} - void OptionValueFileSpec::AutoComplete(CommandInterpreter &interpreter, CompletionRequest &request) { CommandCompletions::InvokeCommonCompletionCallbacks( diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileSpecList.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileSpecList.cpp index f2367b1941c9..2160fd61d428 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileSpecList.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileSpecList.cpp @@ -164,7 +164,7 @@ Status OptionValueFileSpecList::SetValueFromString(llvm::StringRef value, return error; } -lldb::OptionValueSP OptionValueFileSpecList::DeepCopy() const { +OptionValueSP OptionValueFileSpecList::Clone() const { std::lock_guard<std::recursive_mutex> lock(m_mutex); - return OptionValueSP(new OptionValueFileSpecList(m_current_value)); + return Cloneable::Clone(); } diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueFormat.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueFormat.cpp index b676bed50e62..76a446d1c3bc 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueFormat.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueFormat.cpp @@ -56,7 +56,3 @@ Status OptionValueFormat::SetValueFromString(llvm::StringRef value, } return error; } - -lldb::OptionValueSP OptionValueFormat::DeepCopy() const { - return OptionValueSP(new OptionValueFormat(*this)); -} diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueFormatEntity.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueFormatEntity.cpp index 509a21752e48..64fcaf2cbc85 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueFormatEntity.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueFormatEntity.cpp @@ -15,9 +15,7 @@ using namespace lldb; using namespace lldb_private; -OptionValueFormatEntity::OptionValueFormatEntity(const char *default_format) - : OptionValue(), m_current_format(), m_default_format(), m_current_entry(), - m_default_entry() { +OptionValueFormatEntity::OptionValueFormatEntity(const char *default_format) { if (default_format && default_format[0]) { llvm::StringRef default_format_str(default_format); Status error = FormatEntity::Parse(default_format_str, m_default_entry); @@ -111,10 +109,6 @@ Status OptionValueFormatEntity::SetValueFromString(llvm::StringRef value_str, return error; } -lldb::OptionValueSP OptionValueFormatEntity::DeepCopy() const { - return OptionValueSP(new OptionValueFormatEntity(*this)); -} - void OptionValueFormatEntity::AutoComplete(CommandInterpreter &interpreter, CompletionRequest &request) { FormatEntity::AutoComplete(request); diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueLanguage.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueLanguage.cpp index 5b310782a1ba..d2fbe248300d 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueLanguage.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueLanguage.cpp @@ -69,7 +69,3 @@ Status OptionValueLanguage::SetValueFromString(llvm::StringRef value, } return error; } - -lldb::OptionValueSP OptionValueLanguage::DeepCopy() const { - return OptionValueSP(new OptionValueLanguage(*this)); -} diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValuePathMappings.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValuePathMappings.cpp index 3b3f43d07293..4dceb5632716 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValuePathMappings.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValuePathMappings.cpp @@ -196,7 +196,3 @@ Status OptionValuePathMappings::SetValueFromString(llvm::StringRef value, } return error; } - -lldb::OptionValueSP OptionValuePathMappings::DeepCopy() const { - return OptionValueSP(new OptionValuePathMappings(*this)); -} diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueProperties.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueProperties.cpp index 6c4e77f614f9..ae073798ca12 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueProperties.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueProperties.cpp @@ -20,29 +20,7 @@ using namespace lldb; using namespace lldb_private; -OptionValueProperties::OptionValueProperties(ConstString name) - : OptionValue(), m_name(name), m_properties(), m_name_to_index() {} - -OptionValueProperties::OptionValueProperties( - const OptionValueProperties &global_properties) - : OptionValue(global_properties), - std::enable_shared_from_this<OptionValueProperties>(), - m_name(global_properties.m_name), - m_properties(global_properties.m_properties), - m_name_to_index(global_properties.m_name_to_index) { - // We now have an exact copy of "global_properties". We need to now find all - // non-global settings and copy the property values so that all non-global - // settings get new OptionValue instances created for them. - const size_t num_properties = m_properties.size(); - for (size_t i = 0; i < num_properties; ++i) { - // Duplicate any values that are not global when constructing properties - // from a global copy - if (!m_properties[i].IsGlobal()) { - lldb::OptionValueSP new_value_sp(m_properties[i].GetValue()->DeepCopy()); - m_properties[i].SetOptionValue(new_value_sp); - } - } -} +OptionValueProperties::OptionValueProperties(ConstString name) : m_name(name) {} size_t OptionValueProperties::GetNumProperties() const { return m_properties.size(); @@ -250,38 +228,50 @@ OptionValueProperties::GetPropertyAtIndexAsOptionValueLanguage( bool OptionValueProperties::GetPropertyAtIndexAsArgs( const ExecutionContext *exe_ctx, uint32_t idx, Args &args) const { const Property *property = GetPropertyAtIndex(exe_ctx, false, idx); - if (property) { - OptionValue *value = property->GetValue().get(); - if (value) { - const OptionValueArray *array = value->GetAsArray(); - if (array) - return array->GetArgs(args); - else { - const OptionValueDictionary *dict = value->GetAsDictionary(); - if (dict) - return dict->GetArgs(args); - } - } - } + if (!property) + return false; + + OptionValue *value = property->GetValue().get(); + if (!value) + return false; + + const OptionValueArgs *arguments = value->GetAsArgs(); + if (arguments) + return arguments->GetArgs(args); + + const OptionValueArray *array = value->GetAsArray(); + if (array) + return array->GetArgs(args); + + const OptionValueDictionary *dict = value->GetAsDictionary(); + if (dict) + return dict->GetArgs(args); + return false; } bool OptionValueProperties::SetPropertyAtIndexFromArgs( const ExecutionContext *exe_ctx, uint32_t idx, const Args &args) { const Property *property = GetPropertyAtIndex(exe_ctx, true, idx); - if (property) { - OptionValue *value = property->GetValue().get(); - if (value) { - OptionValueArray *array = value->GetAsArray(); - if (array) - return array->SetArgs(args, eVarSetOperationAssign).Success(); - else { - OptionValueDictionary *dict = value->GetAsDictionary(); - if (dict) - return dict->SetArgs(args, eVarSetOperationAssign).Success(); - } - } - } + if (!property) + return false; + + OptionValue *value = property->GetValue().get(); + if (!value) + return false; + + OptionValueArgs *arguments = value->GetAsArgs(); + if (arguments) + return arguments->SetArgs(args, eVarSetOperationAssign).Success(); + + OptionValueArray *array = value->GetAsArray(); + if (array) + return array->SetArgs(args, eVarSetOperationAssign).Success(); + + OptionValueDictionary *dict = value->GetAsDictionary(); + if (dict) + return dict->SetArgs(args, eVarSetOperationAssign).Success(); + return false; } @@ -552,8 +542,32 @@ Status OptionValueProperties::DumpPropertyValue(const ExecutionContext *exe_ctx, return error; } -lldb::OptionValueSP OptionValueProperties::DeepCopy() const { - llvm_unreachable("this shouldn't happen"); +OptionValuePropertiesSP +OptionValueProperties::CreateLocalCopy(const Properties &global_properties) { + auto global_props_sp = global_properties.GetValueProperties(); + lldbassert(global_props_sp); + + auto copy_sp = global_props_sp->DeepCopy(global_props_sp->GetParent()); + return std::static_pointer_cast<OptionValueProperties>(copy_sp); +} + +OptionValueSP +OptionValueProperties::DeepCopy(const OptionValueSP &new_parent) const { + auto copy_sp = OptionValue::DeepCopy(new_parent); + // copy_sp->GetAsProperties cannot be used here as it doesn't work for derived + // types that override GetType returning a different value. + auto *props_value_ptr = static_cast<OptionValueProperties *>(copy_sp.get()); + lldbassert(props_value_ptr); + + for (auto &property : props_value_ptr->m_properties) { + // Duplicate any values that are not global when constructing properties + // from a global copy. + if (!property.IsGlobal()) { + auto value_sp = property.GetValue()->DeepCopy(copy_sp); + property.SetOptionValue(value_sp); + } + } + return copy_sp; } const Property *OptionValueProperties::GetPropertyAtPath( @@ -616,11 +630,11 @@ void OptionValueProperties::Apropos( } else { bool match = false; llvm::StringRef name = property->GetName(); - if (name.contains_lower(keyword)) + if (name.contains_insensitive(keyword)) match = true; else { llvm::StringRef desc = property->GetDescription(); - if (desc.contains_lower(keyword)) + if (desc.contains_insensitive(keyword)) match = true; } if (match) { diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueRegex.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueRegex.cpp index bec3942d9cb0..bbeca8da7714 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueRegex.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueRegex.cpp @@ -59,7 +59,3 @@ Status OptionValueRegex::SetValueFromString(llvm::StringRef value, } return error; } - -lldb::OptionValueSP OptionValueRegex::DeepCopy() const { - return OptionValueSP(new OptionValueRegex(m_regex.GetText().str().c_str())); -} diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueSInt64.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueSInt64.cpp index ada20b2139a3..b875ba8e3536 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueSInt64.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueSInt64.cpp @@ -70,7 +70,3 @@ Status OptionValueSInt64::SetValueFromString(llvm::StringRef value_ref, } return error; } - -lldb::OptionValueSP OptionValueSInt64::DeepCopy() const { - return OptionValueSP(new OptionValueSInt64(*this)); -} diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueString.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueString.cpp index 22f5d08bf832..b4fec91bc33f 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueString.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueString.cpp @@ -117,10 +117,6 @@ Status OptionValueString::SetValueFromString(llvm::StringRef value, return error; } -lldb::OptionValueSP OptionValueString::DeepCopy() const { - return OptionValueSP(new OptionValueString(*this)); -} - Status OptionValueString::SetCurrentValue(llvm::StringRef value) { if (m_validator) { Status error(m_validator(value.str().c_str(), m_validator_baton)); diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueUInt64.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueUInt64.cpp index 98ef016e5f77..a2751a4d02eb 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueUInt64.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueUInt64.cpp @@ -68,7 +68,3 @@ Status OptionValueUInt64::SetValueFromString(llvm::StringRef value_ref, } return error; } - -lldb::OptionValueSP OptionValueUInt64::DeepCopy() const { - return OptionValueSP(new OptionValueUInt64(*this)); -} diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueUUID.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueUUID.cpp index 2bd749773556..283f9c1b67b3 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueUUID.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueUUID.cpp @@ -58,10 +58,6 @@ Status OptionValueUUID::SetValueFromString(llvm::StringRef value, return error; } -lldb::OptionValueSP OptionValueUUID::DeepCopy() const { - return OptionValueSP(new OptionValueUUID(*this)); -} - void OptionValueUUID::AutoComplete(CommandInterpreter &interpreter, CompletionRequest &request) { ExecutionContext exe_ctx(interpreter.GetExecutionContext()); diff --git a/contrib/llvm-project/lldb/source/Interpreter/Options.cpp b/contrib/llvm-project/lldb/source/Interpreter/Options.cpp index 9ecc9e229e0e..4aa298f0382b 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/Options.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/Options.cpp @@ -25,9 +25,9 @@ using namespace lldb; using namespace lldb_private; // Options -Options::Options() : m_getopt_table() { BuildValidOptionSets(); } +Options::Options() { BuildValidOptionSets(); } -Options::~Options() {} +Options::~Options() = default; void Options::NotifyOptionParsingStarting(ExecutionContext *execution_context) { m_seen_options.clear(); @@ -137,7 +137,6 @@ bool Options::VerifyOptions(CommandReturnObject &result) { result.SetStatus(eReturnStatusSuccessFinishNoResult); } else { result.AppendError("invalid combination of options for the given command"); - result.SetStatus(eReturnStatusFailed); } return options_are_valid; diff --git a/contrib/llvm-project/lldb/source/Interpreter/Property.cpp b/contrib/llvm-project/lldb/source/Interpreter/Property.cpp index a02497662ff5..55400a2bc42d 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/Property.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/Property.cpp @@ -22,7 +22,7 @@ using namespace lldb_private; Property::Property(const PropertyDefinition &definition) : m_name(definition.name), m_description(definition.description), - m_value_sp(), m_is_global(definition.global) { + m_is_global(definition.global) { switch (definition.type) { case OptionValue::eTypeInvalid: case OptionValue::eTypeProperties: diff --git a/contrib/llvm-project/lldb/source/Interpreter/ScriptInterpreter.cpp b/contrib/llvm-project/lldb/source/Interpreter/ScriptInterpreter.cpp index 013ed6aecb80..f26474836a68 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/ScriptInterpreter.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/ScriptInterpreter.cpp @@ -18,37 +18,36 @@ #if defined(_WIN32) #include "lldb/Host/windows/ConnectionGenericFileWindows.h" #endif +#include <cstdio> +#include <cstdlib> #include <memory> -#include <stdio.h> -#include <stdlib.h> #include <string> using namespace lldb; using namespace lldb_private; -ScriptInterpreter::ScriptInterpreter(Debugger &debugger, - lldb::ScriptLanguage script_lang) - : m_debugger(debugger), m_script_lang(script_lang) {} - -ScriptInterpreter::~ScriptInterpreter() {} +ScriptInterpreter::ScriptInterpreter( + Debugger &debugger, lldb::ScriptLanguage script_lang, + lldb::ScriptedProcessInterfaceUP scripted_process_interface_up) + : m_debugger(debugger), m_script_lang(script_lang), + m_scripted_process_interface_up( + std::move(scripted_process_interface_up)) {} void ScriptInterpreter::CollectDataForBreakpointCommandCallback( - std::vector<BreakpointOptions *> &bp_options_vec, + std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec, CommandReturnObject &result) { - result.SetStatus(eReturnStatusFailed); result.AppendError( "This script interpreter does not support breakpoint callbacks."); } void ScriptInterpreter::CollectDataForWatchpointCommandCallback( WatchpointOptions *bp_options, CommandReturnObject &result) { - result.SetStatus(eReturnStatusFailed); result.AppendError( "This script interpreter does not support watchpoint callbacks."); } bool ScriptInterpreter::LoadScriptingModule(const char *filename, - bool init_session, + const LoadScriptOptions &options, lldb_private::Status &error, StructuredData::ObjectSP *module_sp, FileSpec extra_search_dir) { @@ -71,22 +70,35 @@ std::string ScriptInterpreter::LanguageToString(lldb::ScriptLanguage language) { llvm_unreachable("Unhandled ScriptInterpreter!"); } +lldb::DataExtractorSP +ScriptInterpreter::GetDataExtractorFromSBData(const lldb::SBData &data) const { + return data.m_opaque_sp; +} + +Status +ScriptInterpreter::GetStatusFromSBError(const lldb::SBError &error) const { + if (error.m_opaque_up) + return *error.m_opaque_up.get(); + + return Status(); +} + lldb::ScriptLanguage ScriptInterpreter::StringToLanguage(const llvm::StringRef &language) { - if (language.equals_lower(LanguageToString(eScriptLanguageNone))) + if (language.equals_insensitive(LanguageToString(eScriptLanguageNone))) return eScriptLanguageNone; - if (language.equals_lower(LanguageToString(eScriptLanguagePython))) + if (language.equals_insensitive(LanguageToString(eScriptLanguagePython))) return eScriptLanguagePython; - if (language.equals_lower(LanguageToString(eScriptLanguageLua))) + if (language.equals_insensitive(LanguageToString(eScriptLanguageLua))) return eScriptLanguageLua; return eScriptLanguageUnknown; } Status ScriptInterpreter::SetBreakpointCommandCallback( - std::vector<BreakpointOptions *> &bp_options_vec, + std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec, const char *callback_text) { Status return_error; - for (BreakpointOptions *bp_options : bp_options_vec) { + for (BreakpointOptions &bp_options : bp_options_vec) { return_error = SetBreakpointCommandCallback(bp_options, callback_text); if (return_error.Success()) break; @@ -95,10 +107,10 @@ Status ScriptInterpreter::SetBreakpointCommandCallback( } Status ScriptInterpreter::SetBreakpointCommandCallbackFunction( - std::vector<BreakpointOptions *> &bp_options_vec, const char *function_name, - StructuredData::ObjectSP extra_args_sp) { + std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec, + const char *function_name, StructuredData::ObjectSP extra_args_sp) { Status error; - for (BreakpointOptions *bp_options : bp_options_vec) { + for (BreakpointOptions &bp_options : bp_options_vec) { error = SetBreakpointCommandCallbackFunction(bp_options, function_name, extra_args_sp); if (!error.Success()) diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp index d36aeca21c69..505c7d416a82 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp @@ -13,6 +13,7 @@ #include "ABISysV_arm64.h" #include "Utility/ARM64_DWARF_Registers.h" #include "lldb/Core/PluginManager.h" +#include "lldb/Target/Process.h" LLDB_PLUGIN_DEFINE(ABIAArch64) @@ -30,6 +31,18 @@ void ABIAArch64::Terminate() { #endif // LLDB_ENABLE_ALL } +lldb::addr_t ABIAArch64::FixCodeAddress(lldb::addr_t pc) { + if (lldb::ProcessSP process_sp = GetProcessSP()) + return FixAddress(pc, process_sp->GetCodeAddressMask()); + return pc; +} + +lldb::addr_t ABIAArch64::FixDataAddress(lldb::addr_t pc) { + if (lldb::ProcessSP process_sp = GetProcessSP()) + return FixAddress(pc, process_sp->GetDataAddressMask()); + return pc; +} + std::pair<uint32_t, uint32_t> ABIAArch64::GetEHAndDWARFNums(llvm::StringRef name) { if (name == "pc") diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h index bdff648f1b52..41bbf5cfdeb9 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h @@ -16,7 +16,14 @@ public: static void Initialize(); static void Terminate(); + virtual lldb::addr_t FixCodeAddress(lldb::addr_t pc) override; + virtual lldb::addr_t FixDataAddress(lldb::addr_t pc) override; + protected: + virtual lldb::addr_t FixAddress(lldb::addr_t pc, lldb::addr_t mask) { + return pc; + } + std::pair<uint32_t, uint32_t> GetEHAndDWARFNums(llvm::StringRef name) override; diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp index 09b319a84a08..348a081cfe17 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp @@ -66,7 +66,7 @@ bool ABIMacOSX_arm64::PrepareTrivialCall( if (log) { StreamString s; - s.Printf("ABISysV_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64 + s.Printf("ABIMacOSX_arm64::PrepareTrivialCall (tid = 0x%" PRIx64 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 ", return_addr = 0x%" PRIx64, thread.GetID(), (uint64_t)sp, (uint64_t)func_addr, @@ -86,7 +86,7 @@ bool ABIMacOSX_arm64::PrepareTrivialCall( eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA); // x0 - x7 contain first 8 simple args - if (args.size() > 8) // TODO handle more than 6 arguments + if (args.size() > 8) // TODO handle more than 8 arguments return false; for (size_t i = 0; i < args.size(); ++i) { @@ -384,6 +384,7 @@ bool ABIMacOSX_arm64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size); row->SetOffset(0); + row->SetUnspecifiedRegistersAreUndefined(true); row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true); row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true); @@ -654,7 +655,7 @@ ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl( const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr); if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) { - value.SetValueType(Value::eValueTypeScalar); + value.SetValueType(Value::ValueType::Scalar); bool success = false; if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) { @@ -814,6 +815,11 @@ ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl( return return_valobj_sp; } +lldb::addr_t ABIMacOSX_arm64::FixAddress(addr_t pc, addr_t mask) { + lldb::addr_t pac_sign_extension = 0x0080000000000000ULL; + return (pc & pac_sign_extension) ? pc | mask : pc & (~mask); +} + void ABIMacOSX_arm64::Initialize() { PluginManager::RegisterPlugin(GetPluginNameStatic(), pluginDesc, CreateInstance); diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h index fc8ccee92e71..dc3ab35115fd 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h @@ -62,6 +62,8 @@ public: return true; } + lldb::addr_t FixAddress(lldb::addr_t pc, lldb::addr_t mask) override; + // Static Functions static void Initialize(); diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp index 1214195dcfc0..16fb38e107c3 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp @@ -356,6 +356,7 @@ bool ABISysV_arm64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size); row->SetOffset(0); + row->SetUnspecifiedRegistersAreUndefined(true); row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true); row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true); @@ -622,7 +623,7 @@ ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl( const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr); if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) { - value.SetValueType(Value::eValueTypeScalar); + value.SetValueType(Value::ValueType::Scalar); bool success = false; if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) { @@ -781,6 +782,61 @@ ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl( return return_valobj_sp; } +lldb::addr_t ABISysV_arm64::FixAddress(addr_t pc, addr_t mask) { + lldb::addr_t pac_sign_extension = 0x0080000000000000ULL; + return (pc & pac_sign_extension) ? pc | mask : pc & (~mask); +} + +// Reads code or data address mask for the current Linux process. +static lldb::addr_t ReadLinuxProcessAddressMask(lldb::ProcessSP process_sp, + llvm::StringRef reg_name) { + // Linux configures user-space virtual addresses with top byte ignored. + // We set default value of mask such that top byte is masked out. + uint64_t address_mask = ~((1ULL << 56) - 1); + // If Pointer Authentication feature is enabled then Linux exposes + // PAC data and code mask register. Try reading relevant register + // below and merge it with default address mask calculated above. + lldb::ThreadSP thread_sp = process_sp->GetThreadList().GetSelectedThread(); + if (thread_sp) { + lldb::RegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext(); + if (reg_ctx_sp) { + const RegisterInfo *reg_info = + reg_ctx_sp->GetRegisterInfoByName(reg_name, 0); + if (reg_info) { + lldb::addr_t mask_reg_val = reg_ctx_sp->ReadRegisterAsUnsigned( + reg_info->kinds[eRegisterKindLLDB], LLDB_INVALID_ADDRESS); + if (mask_reg_val != LLDB_INVALID_ADDRESS) + address_mask |= mask_reg_val; + } + } + } + return address_mask; +} + +lldb::addr_t ABISysV_arm64::FixCodeAddress(lldb::addr_t pc) { + if (lldb::ProcessSP process_sp = GetProcessSP()) { + if (process_sp->GetTarget().GetArchitecture().GetTriple().isOSLinux() && + !process_sp->GetCodeAddressMask()) + process_sp->SetCodeAddressMask( + ReadLinuxProcessAddressMask(process_sp, "code_mask")); + + return FixAddress(pc, process_sp->GetCodeAddressMask()); + } + return pc; +} + +lldb::addr_t ABISysV_arm64::FixDataAddress(lldb::addr_t pc) { + if (lldb::ProcessSP process_sp = GetProcessSP()) { + if (process_sp->GetTarget().GetArchitecture().GetTriple().isOSLinux() && + !process_sp->GetDataAddressMask()) + process_sp->SetDataAddressMask( + ReadLinuxProcessAddressMask(process_sp, "data_mask")); + + return FixAddress(pc, process_sp->GetDataAddressMask()); + } + return pc; +} + void ABISysV_arm64::Initialize() { PluginManager::RegisterPlugin(GetPluginNameStatic(), "SysV ABI for AArch64 targets", CreateInstance); diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h index aeb74acc38b5..3428a7ad9418 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h @@ -67,6 +67,8 @@ public: bool GetPointerReturnRegister(const char *&name) override; + lldb::addr_t FixAddress(lldb::addr_t pc, lldb::addr_t mask) override; + // Static Functions static void Initialize(); @@ -83,6 +85,9 @@ public: uint32_t GetPluginVersion() override; + lldb::addr_t FixCodeAddress(lldb::addr_t pc) override; + lldb::addr_t FixDataAddress(lldb::addr_t pc) override; + protected: lldb::ValueObjectSP GetReturnValueObjectImpl(lldb_private::Thread &thread, diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/ARC/ABISysV_arc.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/ARC/ABISysV_arc.cpp index be8586722d8f..60cdbc534113 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/ARC/ABISysV_arc.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/ARC/ABISysV_arc.cpp @@ -466,7 +466,7 @@ ABISysV_arc::GetReturnValueObjectSimple(Thread &thread, if (!SetSizedInteger(value.GetScalar(), raw_value, byte_size, is_signed)) return ValueObjectSP(); - value.SetValueType(Value::eValueTypeScalar); + value.SetValueType(Value::ValueType::Scalar); } // Pointer return type. else if (type_flags & eTypeIsPointer) { @@ -474,7 +474,7 @@ ABISysV_arc::GetReturnValueObjectSimple(Thread &thread, LLDB_REGNUM_GENERIC_ARG1); value.GetScalar() = reg_ctx->ReadRegisterAsUnsigned(reg_info_r0, 0); - value.SetValueType(Value::eValueTypeScalar); + value.SetValueType(Value::ValueType::Scalar); } // Floating point return type. else if (type_flags & eTypeIsFloat) { @@ -537,7 +537,7 @@ ValueObjectSP ABISysV_arc::GetReturnValueObjectImpl(Thread &thread, auto reg_info_r0 = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1); value.GetScalar() = reg_ctx->ReadRegisterAsUnsigned(reg_info_r0, 0); - value.SetValueType(Value::eValueTypeScalar); + value.SetValueType(Value::ValueType::Scalar); } // Floating point return type. else if (retType.isFloatingPointTy()) { diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp index 06c4590b7740..e429f3ee0cc4 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp @@ -1824,6 +1824,7 @@ bool ABIMacOSX_arm::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size); row->SetOffset(0); + row->SetUnspecifiedRegistersAreUndefined(true); row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true); row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true); diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.cpp index 26b3152bed16..3e544e0483a7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.cpp @@ -1617,7 +1617,7 @@ ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl( thread.GetRegisterContext()->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX; value.GetScalar() = ptr; - } else if (compiler_type.IsVectorType(nullptr, nullptr)) { + } else if (compiler_type.IsVectorType()) { if (IsArmHardFloat(thread) && (*byte_size == 8 || *byte_size == 16)) { is_vfp_candidate = true; vfp_byte_size = 8; @@ -1704,7 +1704,7 @@ ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl( if (homogeneous_count > 0 && homogeneous_count <= 4) { llvm::Optional<uint64_t> base_byte_size = base_type.GetByteSize(&thread); - if (base_type.IsVectorType(nullptr, nullptr)) { + if (base_type.IsVectorType()) { if (base_byte_size && (*base_byte_size == 8 || *base_byte_size == 16)) { is_vfp_candidate = true; @@ -1940,6 +1940,7 @@ bool ABISysV_arm::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size); row->SetOffset(0); + row->SetUnspecifiedRegistersAreUndefined(true); row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true); row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true); diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp index 47aaefd3b228..6794f7d07210 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp @@ -1225,6 +1225,7 @@ bool ABISysV_hexagon::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { UnwindPlan::RowSP row(new UnwindPlan::Row); + row->SetUnspecifiedRegistersAreUndefined(true); row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_FP, 8); row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, -8, true); diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips.cpp index d66e0926ad99..538ec06c3b0d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips.cpp @@ -985,6 +985,7 @@ bool ABISysV_mips::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { UnwindPlan::RowSP row(new UnwindPlan::Row); + row->SetUnspecifiedRegistersAreUndefined(true); row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0); row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true); diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp index 751555722dac..7220508c75ff 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp @@ -764,7 +764,7 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl( const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0); if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) { - value.SetValueType(Value::eValueTypeScalar); + value.SetValueType(Value::ValueType::Scalar); bool success = false; if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) { @@ -1156,6 +1156,7 @@ bool ABISysV_mips64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { UnwindPlan::RowSP row(new UnwindPlan::Row); + row->SetUnspecifiedRegistersAreUndefined(true); row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0); row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true); diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.cpp index 91d2e59ed632..98a14b50cbf3 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.cpp @@ -520,7 +520,7 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectSimple( const uint32_t type_flags = return_compiler_type.GetTypeInfo(); if (type_flags & eTypeIsScalar) { - value.SetValueType(Value::eValueTypeScalar); + value.SetValueType(Value::ValueType::Scalar); bool success = false; if (type_flags & eTypeIsInteger) { @@ -603,7 +603,7 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectSimple( reg_ctx->GetRegisterInfoByName("r3", 0)->kinds[eRegisterKindLLDB]; value.GetScalar() = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r3_id, 0); - value.SetValueType(Value::eValueTypeScalar); + value.SetValueType(Value::ValueType::Scalar); return_valobj_sp = ValueObjectConstResult::Create( thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); } else if (type_flags & eTypeIsVector) { @@ -683,8 +683,6 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectImpl( r3_value.GetData(r3_data); rdx_value.GetData(rdx_data); - uint32_t fp_bytes = - 0; // Tracks how much of the xmm registers we've consumed so far uint32_t integer_bytes = 0; // Tracks how much of the r3/rds registers we've consumed so far @@ -751,7 +749,6 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectImpl( break; } else if (*field_bit_width == 64) { copy_from_offset = 0; - fp_bytes += field_byte_width; } else if (*field_bit_width == 32) { // This one is kind of complicated. If we are in an "eightbyte" // with another float, we'll be stuffed into an xmm register with @@ -815,8 +812,6 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectImpl( copy_from_offset = integer_bytes - 8; integer_bytes += field_byte_width; } - } else { - fp_bytes += field_byte_width; } } } @@ -900,6 +895,7 @@ bool ABISysV_ppc::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { UnwindPlan::RowSP row(new UnwindPlan::Row); const int32_t ptr_size = 4; + row->SetUnspecifiedRegistersAreUndefined(true); row->GetCFAValue().SetIsRegisterDereferenced(sp_reg_num); row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * 1, true); diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp index c7cb7736df9f..7cc9482e7c5d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp @@ -577,7 +577,7 @@ private: ValueSP NewScalarValue(CompilerType &type) { ValueSP value_sp(new Value); value_sp->SetCompilerType(type); - value_sp->SetValueType(Value::eValueTypeScalar); + value_sp->SetValueType(Value::ValueType::Scalar); return value_sp; } @@ -1003,6 +1003,7 @@ bool ABISysV_ppc64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { UnwindPlan::RowSP row(new UnwindPlan::Row); const int32_t ptr_size = 8; + row->SetUnspecifiedRegistersAreUndefined(true); row->GetCFAValue().SetIsRegisterDereferenced(sp_reg_num); row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * 2, true); diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.cpp index 22a64170017b..88e85111d871 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.cpp @@ -487,7 +487,7 @@ ValueObjectSP ABISysV_s390x::GetReturnValueObjectSimple( const uint32_t type_flags = return_compiler_type.GetTypeInfo(); if (type_flags & eTypeIsScalar) { - value.SetValueType(Value::eValueTypeScalar); + value.SetValueType(Value::ValueType::Scalar); bool success = false; if (type_flags & eTypeIsInteger) { @@ -571,7 +571,7 @@ ValueObjectSP ABISysV_s390x::GetReturnValueObjectSimple( reg_ctx->GetRegisterInfoByName("r2", 0)->kinds[eRegisterKindLLDB]; value.GetScalar() = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r2_id, 0); - value.SetValueType(Value::eValueTypeScalar); + value.SetValueType(Value::ValueType::Scalar); return_valobj_sp = ValueObjectConstResult::Create( thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); } diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.cpp index 89112deb2c4a..461e4af599d3 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.cpp @@ -389,6 +389,7 @@ bool ABIMacOSX_i386::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size); row->SetOffset(0); + row->SetUnspecifiedRegistersAreUndefined(true); row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true); row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true); diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp index 2f47d3f462d2..7d2f0a64d679 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp @@ -378,14 +378,14 @@ ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple( uint32_t ptr = thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff; - value.SetValueType(Value::eValueTypeScalar); + value.SetValueType(Value::ValueType::Scalar); value.GetScalar() = ptr; return_valobj_sp = ValueObjectConstResult::Create( thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); } else if ((type_flags & eTypeIsScalar) || (type_flags & eTypeIsEnumeration)) //'Integral' + 'Floating Point' { - value.SetValueType(Value::eValueTypeScalar); + value.SetValueType(Value::ValueType::Scalar); llvm::Optional<uint64_t> byte_size = return_compiler_type.GetByteSize(&thread); if (!byte_size) @@ -453,7 +453,7 @@ ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple( uint32_t enm = thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff; - value.SetValueType(Value::eValueTypeScalar); + value.SetValueType(Value::ValueType::Scalar); value.GetScalar() = enm; return_valobj_sp = ValueObjectConstResult::Create( thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); @@ -652,6 +652,7 @@ bool ABISysV_i386::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size); row->SetOffset(0); + row->SetUnspecifiedRegistersAreUndefined(true); row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true); row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true); diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp index 2aa2c02b2e87..196b45b3b6da 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp @@ -399,7 +399,7 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectSimple( const uint32_t type_flags = return_compiler_type.GetTypeInfo(); if (type_flags & eTypeIsScalar) { - value.SetValueType(Value::eValueTypeScalar); + value.SetValueType(Value::ValueType::Scalar); bool success = false; if (type_flags & eTypeIsInteger) { @@ -487,7 +487,7 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectSimple( value.GetScalar() = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0); - value.SetValueType(Value::eValueTypeScalar); + value.SetValueType(Value::ValueType::Scalar); return_valobj_sp = ValueObjectConstResult::Create( thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); } else if (type_flags & eTypeIsVector) { @@ -887,6 +887,7 @@ bool ABISysV_x86_64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { const int32_t ptr_size = 8; row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_rbp, 2 * ptr_size); row->SetOffset(0); + row->SetUnspecifiedRegistersAreUndefined(true); row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true); row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true); diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp index 06e0ce40836d..6c473c652c5f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp @@ -408,7 +408,7 @@ ValueObjectSP ABIWindows_x86_64::GetReturnValueObjectSimple( const uint32_t type_flags = return_compiler_type.GetTypeInfo(); if (type_flags & eTypeIsScalar) { - value.SetValueType(Value::eValueTypeScalar); + value.SetValueType(Value::ValueType::Scalar); bool success = false; if (type_flags & eTypeIsInteger) { @@ -494,7 +494,7 @@ ValueObjectSP ABIWindows_x86_64::GetReturnValueObjectSimple( value.GetScalar() = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0); - value.SetValueType(Value::eValueTypeScalar); + value.SetValueType(Value::ValueType::Scalar); return_valobj_sp = ValueObjectConstResult::Create( thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); } else if (type_flags & eTypeIsVector) { @@ -767,6 +767,7 @@ bool ABIWindows_x86_64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { const int32_t ptr_size = 8; row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_rbp, 2 * ptr_size); row->SetOffset(0); + row->SetUnspecifiedRegistersAreUndefined(true); row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true); row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true); diff --git a/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.cpp b/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.cpp new file mode 100644 index 000000000000..9994cc293d6a --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.cpp @@ -0,0 +1,45 @@ +//===-- ArchitectureAArch64.cpp -------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "Plugins/Architecture/AArch64/ArchitectureAArch64.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Utility/ArchSpec.h" + +using namespace lldb_private; +using namespace lldb; + +LLDB_PLUGIN_DEFINE(ArchitectureAArch64) + +ConstString ArchitectureAArch64::GetPluginNameStatic() { + return ConstString("aarch64"); +} + +void ArchitectureAArch64::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + "AArch64-specific algorithms", + &ArchitectureAArch64::Create); +} + +void ArchitectureAArch64::Terminate() { + PluginManager::UnregisterPlugin(&ArchitectureAArch64::Create); +} + +std::unique_ptr<Architecture> +ArchitectureAArch64::Create(const ArchSpec &arch) { + auto machine = arch.GetMachine(); + if (machine != llvm::Triple::aarch64 && machine != llvm::Triple::aarch64_be && + machine != llvm::Triple::aarch64_32) { + return nullptr; + } + return std::unique_ptr<Architecture>(new ArchitectureAArch64()); +} + +ConstString ArchitectureAArch64::GetPluginName() { + return GetPluginNameStatic(); +} +uint32_t ArchitectureAArch64::GetPluginVersion() { return 1; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.h b/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.h new file mode 100644 index 000000000000..775478cc9338 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.h @@ -0,0 +1,40 @@ +//===-- ArchitectureAArch64.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_SOURCE_PLUGINS_ARCHITECTURE_AARCH64_ARCHITECTUREAARCH64_H +#define LLDB_SOURCE_PLUGINS_ARCHITECTURE_AARCH64_ARCHITECTUREAARCH64_H + +#include "Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h" +#include "lldb/Core/Architecture.h" + +namespace lldb_private { + +class ArchitectureAArch64 : public Architecture { +public: + static ConstString GetPluginNameStatic(); + static void Initialize(); + static void Terminate(); + + ConstString GetPluginName() override; + uint32_t GetPluginVersion() override; + + void OverrideStopInfo(Thread &thread) const override{}; + + const MemoryTagManager *GetMemoryTagManager() const override { + return &m_memory_tag_manager; + } + +private: + static std::unique_ptr<Architecture> Create(const ArchSpec &arch); + ArchitectureAArch64() = default; + MemoryTagManagerAArch64MTE m_memory_tag_manager; +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_ARCHITECTURE_AARCH64_ARCHITECTUREAARCH64_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp b/contrib/llvm-project/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp index 22508969ceed..757c91570009 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp @@ -160,7 +160,6 @@ Instruction *ArchitectureMips::GetInstructionAtAddress( InstructionList instruction_list; InstructionSP prev_insn; - bool prefer_file_cache = true; // Read from file uint32_t inst_to_choose = 0; Address addr = resolved_addr; @@ -171,8 +170,7 @@ Instruction *ArchitectureMips::GetInstructionAtAddress( uint32_t insn_size = 0; disasm_sp->ParseInstructions(target, addr, - {Disassembler::Limit::Bytes, i * 2}, nullptr, - prefer_file_cache); + {Disassembler::Limit::Bytes, i * 2}, nullptr); uint32_t num_insns = disasm_sp->GetInstructionList().GetSize(); if (num_insns) { diff --git a/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp b/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp index 8a2d3232a39a..7cd505d0ed29 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp @@ -905,7 +905,8 @@ DisassemblerLLVMC::MCDisasmInstance::Create(const char *triple, const char *cpu, return Instance(); std::unique_ptr<llvm::MCContext> context_up( - new llvm::MCContext(asm_info_up.get(), reg_info_up.get(), nullptr)); + new llvm::MCContext(llvm::Triple(triple), asm_info_up.get(), + reg_info_up.get(), subtarget_info_up.get())); if (!context_up) return Instance(); diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h index 5707f8858f6c..c34e02ed5678 100644 --- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h +++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h @@ -35,15 +35,13 @@ class HexagonDYLDRendezvous { // the layout of this struct is not binary compatible, it is simply large // enough to hold the information on both 32 and 64 bit platforms. struct Rendezvous { - uint64_t version; - lldb::addr_t map_addr; - lldb::addr_t brk; - uint64_t state; - lldb::addr_t ldbase; - - Rendezvous() - : version(0), map_addr(LLDB_INVALID_ADDRESS), brk(LLDB_INVALID_ADDRESS), - state(0), ldbase(0) {} + uint64_t version = 0; + lldb::addr_t map_addr = LLDB_INVALID_ADDRESS; + lldb::addr_t brk = LLDB_INVALID_ADDRESS; + uint64_t state = 0; + lldb::addr_t ldbase = 0; + + Rendezvous() = default; }; public: diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h index 3e88d88f407a..5775f5a730cd 100644 --- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h +++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h @@ -38,13 +38,13 @@ class DYLDRendezvous { // the layout of this struct is not binary compatible, it is simply large // enough to hold the information on both 32 and 64 bit platforms. struct Rendezvous { - uint64_t version; - lldb::addr_t map_addr; - lldb::addr_t brk; - uint64_t state; - lldb::addr_t ldbase; + uint64_t version = 0; + lldb::addr_t map_addr = 0; + lldb::addr_t brk = 0; + uint64_t state = 0; + lldb::addr_t ldbase = 0; - Rendezvous() : version(0), map_addr(0), brk(0), state(0), ldbase(0) {} + Rendezvous() = default; }; public: diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp index c1fceeb1482c..8a5528f1e474 100644 --- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp @@ -10,6 +10,7 @@ #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" #include "lldb/Symbol/ObjectFile.h" +#include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" #include "DynamicLoaderStatic.h" @@ -105,6 +106,15 @@ void DynamicLoaderStatic::LoadAllImagesAtFileAddresses() { // the file... SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx)); if (section_sp) { + // If this section already has a load address set in the target, + // don't re-set it to the file address. Something may have + // set it to a more correct value already. + if (m_process->GetTarget() + .GetSectionLoadList() + .GetSectionLoadAddress(section_sp) != + LLDB_INVALID_ADDRESS) { + continue; + } if (m_process->GetTarget().SetSectionLoadAddress( section_sp, section_sp->GetFileAddress())) changed = true; diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp index 7f9504b9b3a9..54dfa3e9d6f2 100644 --- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp @@ -28,7 +28,7 @@ LLDB_PLUGIN_DEFINE(DynamicLoaderWindowsDYLD) DynamicLoaderWindowsDYLD::DynamicLoaderWindowsDYLD(Process *process) : DynamicLoader(process) {} -DynamicLoaderWindowsDYLD::~DynamicLoaderWindowsDYLD() {} +DynamicLoaderWindowsDYLD::~DynamicLoaderWindowsDYLD() = default; void DynamicLoaderWindowsDYLD::Initialize() { PluginManager::RegisterPlugin(GetPluginNameStatic(), @@ -193,7 +193,7 @@ DynamicLoaderWindowsDYLD::GetStepThroughTrampolinePlan(Thread &thread, AddressRange range(pc, 2 * 15); DisassemblerSP disassembler_sp = Disassembler::DisassembleRange( - arch, nullptr, nullptr, m_process->GetTarget(), range, true); + arch, nullptr, nullptr, m_process->GetTarget(), range); if (!disassembler_sp) { return ThreadPlanSP(); } diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp index 3edbc4ab98c0..85e2fcfc838c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp @@ -15,7 +15,6 @@ #include "lldb/Target/Target.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" -#include "stdlib.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" @@ -27,6 +26,7 @@ #include "clang/Sema/SemaDiagnostic.h" #include "llvm/Support/Casting.h" #include "llvm/Support/raw_ostream.h" +#include <cstdlib> using namespace llvm; using namespace clang; @@ -43,7 +43,7 @@ ASTResultSynthesizer::ASTResultSynthesizer(ASTConsumer *passthrough, m_passthrough_sema = dyn_cast<SemaConsumer>(passthrough); } -ASTResultSynthesizer::~ASTResultSynthesizer() {} +ASTResultSynthesizer::~ASTResultSynthesizer() = default; void ASTResultSynthesizer::Initialize(ASTContext &Context) { m_ast_context = &Context; diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp index 40f0de40da52..a2722db5d24a 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp @@ -9,7 +9,6 @@ #include "ASTStructExtractor.h" #include "lldb/Utility/Log.h" -#include "stdlib.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" @@ -21,6 +20,7 @@ #include "clang/Sema/Sema.h" #include "llvm/Support/Casting.h" #include "llvm/Support/raw_ostream.h" +#include <cstdlib> using namespace llvm; using namespace clang; @@ -38,7 +38,7 @@ ASTStructExtractor::ASTStructExtractor(ASTConsumer *passthrough, m_passthrough_sema = dyn_cast<SemaConsumer>(passthrough); } -ASTStructExtractor::~ASTStructExtractor() {} +ASTStructExtractor::~ASTStructExtractor() = default; void ASTStructExtractor::Initialize(ASTContext &Context) { m_ast_context = &Context; diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp index 1e438ed9d73e..a95fce1c5aa9 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp @@ -8,17 +8,17 @@ #include "ASTUtils.h" -lldb_private::ExternalASTSourceWrapper::~ExternalASTSourceWrapper() {} +lldb_private::ExternalASTSourceWrapper::~ExternalASTSourceWrapper() = default; void lldb_private::ExternalASTSourceWrapper::PrintStats() { m_Source->PrintStats(); } -lldb_private::ASTConsumerForwarder::~ASTConsumerForwarder() {} +lldb_private::ASTConsumerForwarder::~ASTConsumerForwarder() = default; void lldb_private::ASTConsumerForwarder::PrintStats() { m_c->PrintStats(); } -lldb_private::SemaSourceWithPriorities::~SemaSourceWithPriorities() {} +lldb_private::SemaSourceWithPriorities::~SemaSourceWithPriorities() = default; void lldb_private::SemaSourceWithPriorities::PrintStats() { for (size_t i = 0; i < Sources.size(); ++i) diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp index e2601a059bb7..94647b0ef978 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp @@ -184,7 +184,7 @@ private: } public: - DeclContextOverride() {} + DeclContextOverride() = default; void OverrideAllDeclsFromContainingFunction(clang::Decl *decl) { for (DeclContext *decl_context = decl->getLexicalDeclContext(); @@ -359,9 +359,6 @@ bool ClangASTImporter::CanImport(const CompilerType &type) { if (!ClangUtil::IsClangType(type)) return false; - // TODO: remove external completion BOOL - // CompleteAndFetchChildren should get the Decl out and check for the - clang::QualType qual_type( ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type))); @@ -435,8 +432,6 @@ bool ClangASTImporter::CanImport(const CompilerType &type) { bool ClangASTImporter::Import(const CompilerType &type) { if (!ClangUtil::IsClangType(type)) return false; - // TODO: remove external completion BOOL - // CompleteAndFetchChildren should get the Decl out and check for the clang::QualType qual_type( ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type))); @@ -830,6 +825,10 @@ ClangASTImporter::ASTImporterDelegate::ImportImpl(Decl *From) { // Check which ASTContext this declaration originally came from. DeclOrigin origin = m_master.GetDeclOrigin(From); + + // Prevent infinite recursion when the origin tracking contains a cycle. + assert(origin.decl != From && "Origin points to itself?"); + // If it originally came from the target ASTContext then we can just // pretend that the original is the one we imported. This can happen for // example when inspecting a persistent declaration from the scratch @@ -889,6 +888,37 @@ ClangASTImporter::ASTImporterDelegate::ImportImpl(Decl *From) { LLDB_LOG(log, "[ClangASTImporter] Complete definition not found"); } + // Disable the minimal import for fields that have record types. There is + // no point in minimally importing the record behind their type as Clang + // will anyway request their definition when the FieldDecl is added to the + // RecordDecl (as Clang will query the FieldDecl's type for things such + // as a deleted constexpr destructor). + // By importing the type ahead of time we avoid some corner cases where + // the FieldDecl's record is importing in the middle of Clang's + // `DeclContext::addDecl` logic. + if (clang::FieldDecl *fd = dyn_cast<FieldDecl>(From)) { + // This is only necessary because we do the 'minimal import'. Remove this + // once LLDB stopped using that mode. + assert(isMinimalImport() && "Only necessary for minimal import"); + QualType field_type = fd->getType(); + if (field_type->isRecordType()) { + // First get the underlying record and minimally import it. + clang::TagDecl *record_decl = field_type->getAsTagDecl(); + llvm::Expected<Decl *> imported = Import(record_decl); + if (!imported) + return imported.takeError(); + // Check how/if the import got redirected to a different AST. Now + // import the definition of what was actually imported. If there is no + // origin then that means the record was imported by just picking a + // compatible type in the target AST (in which case there is no more + // importing to do). + if (clang::Decl *origin = m_master.GetDeclOrigin(*imported).decl) { + if (llvm::Error def_err = ImportDefinition(record_decl)) + return std::move(def_err); + } + } + } + return ASTImporter::ImportImpl(From); } @@ -904,16 +934,6 @@ void ClangASTImporter::ASTImporterDelegate::ImportDefinitionTo( MapImported(from, to); ASTImporter::Imported(from, to); - /* - if (to_objc_interface) - to_objc_interface->startDefinition(); - - CXXRecordDecl *to_cxx_record = dyn_cast<CXXRecordDecl>(to); - - if (to_cxx_record) - to_cxx_record->startDefinition(); - */ - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); if (llvm::Error err = ImportDefinition(from)) { @@ -1088,22 +1108,23 @@ void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from, DeclOrigin origin = from_context_md->getOrigin(from); if (origin.Valid()) { - if (!to_context_md->hasOrigin(to) || user_id != LLDB_INVALID_UID) - if (origin.ctx != &to->getASTContext()) + if (origin.ctx != &to->getASTContext()) { + if (!to_context_md->hasOrigin(to) || user_id != LLDB_INVALID_UID) to_context_md->setOrigin(to, origin); - ImporterDelegateSP direct_completer = - m_master.GetDelegate(&to->getASTContext(), origin.ctx); + ImporterDelegateSP direct_completer = + m_master.GetDelegate(&to->getASTContext(), origin.ctx); - if (direct_completer.get() != this) - direct_completer->ASTImporter::Imported(origin.decl, to); + if (direct_completer.get() != this) + direct_completer->ASTImporter::Imported(origin.decl, to); - LLDB_LOG(log, - " [ClangASTImporter] Propagated origin " - "(Decl*){0}/(ASTContext*){1} from (ASTContext*){2} to " - "(ASTContext*){3}", - origin.decl, origin.ctx, &from->getASTContext(), - &to->getASTContext()); + LLDB_LOG(log, + " [ClangASTImporter] Propagated origin " + "(Decl*){0}/(ASTContext*){1} from (ASTContext*){2} to " + "(ASTContext*){3}", + origin.decl, origin.ctx, &from->getASTContext(), + &to->getASTContext()); + } } else { if (m_new_decl_listener) m_new_decl_listener->NewDeclImported(from, to); diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h index bf4ad174cf9c..4f589d34aa48 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h @@ -23,6 +23,7 @@ #include "lldb/Host/FileSystem.h" #include "lldb/Symbol/CompilerDeclContext.h" +#include "lldb/Utility/LLDBAssert.h" #include "lldb/lldb-types.h" #include "Plugins/ExpressionParser/Clang/CxxModuleHandler.h" @@ -34,6 +35,32 @@ namespace lldb_private { class ClangASTMetadata; class TypeSystemClang; +/// Manages and observes all Clang AST node importing in LLDB. +/// +/// The ClangASTImporter takes care of two things: +/// +/// 1. Keeps track of all ASTImporter instances in LLDB. +/// +/// Clang's ASTImporter takes care of importing types from one ASTContext to +/// another. This class expands this concept by allowing copying from several +/// ASTContext instances to several other ASTContext instances. Instead of +/// constructing a new ASTImporter manually to copy over a type/decl, this class +/// can be asked to do this. It will construct a ASTImporter for the caller (and +/// will cache the ASTImporter instance for later use) and then perform the +/// import. +/// +/// This mainly prevents that a caller might construct several ASTImporter +/// instances for the same source/target ASTContext combination. As the +/// ASTImporter has an internal state that keeps track of already imported +/// declarations and so on, using only one ASTImporter instance is more +/// efficient and less error-prone than using multiple. +/// +/// 2. Keeps track of from where declarations were imported (origin-tracking). +/// The ASTImporter instances in this class usually only performa a minimal +/// import, i.e., only a shallow copy is made that is filled out on demand +/// when more information is requested later on. This requires record-keeping +/// of where any shallow clone originally came from so that the right original +/// declaration can be found and used as the source of any missing information. class ClangASTImporter { public: struct LayoutInfo { @@ -52,12 +79,34 @@ public: : m_file_manager(clang::FileSystemOptions(), FileSystem::Instance().GetVirtualFileSystem()) {} + /// Copies the given type and the respective declarations to the destination + /// type system. + /// + /// This function does a shallow copy and requires that the target AST + /// has an ExternalASTSource which queries this ClangASTImporter instance + /// for any additional information that is maybe lacking in the shallow copy. + /// This also means that the type system of src_type can *not* be deleted + /// after this function has been called. If you need to delete the source + /// type system you either need to delete the destination type system first + /// or use \ref ClangASTImporter::DeportType. + /// + /// \see ClangASTImporter::DeportType CompilerType CopyType(TypeSystemClang &dst, const CompilerType &src_type); + /// \see ClangASTImporter::CopyType clang::Decl *CopyDecl(clang::ASTContext *dst_ctx, clang::Decl *decl); + /// Copies the given type and the respective declarations to the destination + /// type system. + /// + /// Unlike CopyType this function ensures that types/declarations which are + /// originally from the AST of src_type are fully copied over. The type + /// system of src_type can safely be deleted after calling this function. + /// \see ClangASTImporter::CopyType CompilerType DeportType(TypeSystemClang &dst, const CompilerType &src_type); + /// Copies the given decl to the destination type system. + /// \see ClangASTImporter::DeportType clang::Decl *DeportDecl(clang::ASTContext *dst_ctx, clang::Decl *decl); /// Sets the layout for the given RecordDecl. The layout will later be @@ -78,8 +127,22 @@ public: llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets); + /// Returns true iff the given type was copied from another TypeSystemClang + /// and the original type in this other TypeSystemClang might contain + /// additional information (e.g., the definition of a 'class' type) that could + /// be imported. + /// + /// \see ClangASTImporter::Import bool CanImport(const CompilerType &type); + /// If the given type was copied from another TypeSystemClang then copy over + /// all missing information (e.g., the definition of a 'class' type). + /// + /// \return True iff an original type in another TypeSystemClang was found. + /// Note: Does *not* return false if an original type was found but + /// no information was imported over. + /// + /// \see ClangASTImporter::Import bool Import(const CompilerType &type); bool CompleteType(const CompilerType &compiler_type); @@ -94,6 +157,14 @@ public: bool RequireCompleteType(clang::QualType type); + /// Updates the internal origin-tracking information so that the given + /// 'original' decl is from now on used to import additional information + /// into the given decl. + /// + /// Usually the origin-tracking in the ClangASTImporter is automatically + /// updated when a declaration is imported, so the only valid reason to ever + /// call this is if there is a 'better' original decl and the target decl + /// is only a shallow clone that lacks any contents. void SetDeclOrigin(const clang::Decl *decl, clang::Decl *original_decl); ClangASTMetadata *GetDeclMetadata(const clang::Decl *decl); @@ -145,10 +216,13 @@ public: void ForgetSource(clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx); struct DeclOrigin { - DeclOrigin() : ctx(nullptr), decl(nullptr) {} + DeclOrigin() = default; DeclOrigin(clang::ASTContext *_ctx, clang::Decl *_decl) - : ctx(_ctx), decl(_decl) {} + : ctx(_ctx), decl(_decl) { + // The decl has to be in its associated ASTContext. + assert(_decl == nullptr || &_decl->getASTContext() == _ctx); + } DeclOrigin(const DeclOrigin &rhs) { ctx = rhs.ctx; @@ -162,8 +236,8 @@ public: bool Valid() const { return (ctx != nullptr || decl != nullptr); } - clang::ASTContext *ctx; - clang::Decl *decl; + clang::ASTContext *ctx = nullptr; + clang::Decl *decl = nullptr; }; /// Listener interface used by the ASTImporterDelegate to inform other code @@ -190,6 +264,16 @@ public: : clang::ASTImporter(*target_ctx, master.m_file_manager, *source_ctx, master.m_file_manager, true /*minimal*/), m_master(master), m_source_ctx(source_ctx) { + // Target and source ASTContext shouldn't be identical. Importing AST + // nodes within the same AST doesn't make any sense as the whole idea + // is to import them to a different AST. + lldbassert(target_ctx != source_ctx && "Can't import into itself"); + // This is always doing a minimal import of any declarations. This means + // that there has to be an ExternalASTSource in the target ASTContext + // (that should implement the callbacks that complete any declarations + // on demand). Without an ExternalASTSource, this ASTImporter will just + // do a minimal import and the imported declarations won't be completed. + assert(target_ctx->getExternalSource() && "Missing ExternalSource"); setODRHandling(clang::ASTImporter::ODRHandlingType::Liberal); } @@ -272,6 +356,13 @@ public: /// Sets the DeclOrigin for the given Decl and overwrites any existing /// DeclOrigin. void setOrigin(const clang::Decl *decl, DeclOrigin origin) { + // Setting the origin of any decl to itself (or to a different decl + // in the same ASTContext) doesn't make any sense. It will also cause + // ASTImporterDelegate::ImportImpl to infinite recurse when trying to find + // the 'original' Decl when importing code. + assert(&decl->getASTContext() != origin.ctx && + "Trying to set decl origin to its own ASTContext?"); + assert(decl != origin.decl && "Trying to set decl origin to itself?"); m_origins[decl] = origin; } diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp index 0f34c48c7e82..b43423707ae1 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp @@ -479,10 +479,7 @@ void ClangASTSource::FindExternalLexicalDecls( decl->getDeclKindName(), ast_dump); } - Decl *copied_decl = CopyDecl(decl); - - if (!copied_decl) - continue; + CopyDecl(decl); // FIXME: We should add the copied decl to the 'decls' list. This would // add the copied Decl into the DeclContext and make sure that we @@ -492,12 +489,6 @@ void ClangASTSource::FindExternalLexicalDecls( // lookup issues later on. // We can't just add them for now as the ASTImporter already added the // decl into the DeclContext and this would add it twice. - - if (FieldDecl *copied_field = dyn_cast<FieldDecl>(copied_decl)) { - QualType copied_field_type = copied_field->getType(); - - m_ast_importer_sp->RequireCompleteType(copied_field_type); - } } else { SkippedDecls = true; } @@ -850,8 +841,8 @@ void ClangASTSource::FindDeclInModules(NameSearchContext &context, ConstString name) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - ClangModulesDeclVendor *modules_decl_vendor = - m_target->GetClangModulesDeclVendor(); + std::shared_ptr<ClangModulesDeclVendor> modules_decl_vendor = + GetClangModulesDeclVendor(); if (!modules_decl_vendor) return; @@ -1143,8 +1134,8 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { // Check the modules only if the debug information didn't have a complete // interface. - if (ClangModulesDeclVendor *modules_decl_vendor = - m_target->GetClangModulesDeclVendor()) { + if (std::shared_ptr<ClangModulesDeclVendor> modules_decl_vendor = + GetClangModulesDeclVendor()) { ConstString interface_name(interface_decl->getNameAsString().c_str()); bool append = false; uint32_t max_matches = 1; @@ -1313,8 +1304,8 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) { // Check the modules only if the debug information didn't have a complete // interface. - ClangModulesDeclVendor *modules_decl_vendor = - m_target->GetClangModulesDeclVendor(); + std::shared_ptr<ClangModulesDeclVendor> modules_decl_vendor = + GetClangModulesDeclVendor(); if (!modules_decl_vendor) break; @@ -1570,10 +1561,10 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, if (log) { LLDB_LOG(log, "LRT returned:"); - LLDB_LOG(log, "LRT Original = (RecordDecl*)%p", + LLDB_LOG(log, "LRT Original = (RecordDecl*){0}", static_cast<const void *>(origin_record.decl)); - LLDB_LOG(log, "LRT Size = %" PRId64, size); - LLDB_LOG(log, "LRT Alignment = %" PRId64, alignment); + LLDB_LOG(log, "LRT Size = {0}", size); + LLDB_LOG(log, "LRT Alignment = {0}", alignment); LLDB_LOG(log, "LRT Fields:"); for (RecordDecl::field_iterator fi = record->field_begin(), fe = record->field_end(); @@ -1750,3 +1741,10 @@ CompilerType ClangASTSource::GuardedCopyType(const CompilerType &src_type) { return m_clang_ast_context->GetType(copied_qual_type); } + +std::shared_ptr<ClangModulesDeclVendor> +ClangASTSource::GetClangModulesDeclVendor() { + auto persistent_vars = llvm::cast<ClangPersistentVariables>( + m_target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC)); + return persistent_vars->GetClangModulesDeclVendor(); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h index 14761fbeb26b..3afd1fd5f2d1 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h @@ -314,6 +314,8 @@ protected: /// The imported type. CompilerType GuardedCopyType(const CompilerType &src_type); + std::shared_ptr<ClangModulesDeclVendor> GetClangModulesDeclVendor(); + public: /// Returns true if a name should be ignored by name lookup. /// diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h index bf52bec4b1fa..6313117c08d6 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h @@ -22,7 +22,7 @@ class ClangDeclVendor : public DeclVendor { public: ClangDeclVendor(DeclVendorKind kind) : DeclVendor(kind) {} - virtual ~ClangDeclVendor() {} + virtual ~ClangDeclVendor() = default; using DeclVendor::FindDecls; diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp index 852ce3bbd3db..731b81c61a6f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp @@ -350,7 +350,7 @@ bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl, if (!var) return false; - LLDB_LOG(log, "Adding value for (NamedDecl*)%p [%s - %s] to the structure", + LLDB_LOG(log, "Adding value for (NamedDecl*){0} [{1} - {2}] to the structure", decl, name, var->GetName()); // We know entity->m_parser_vars is valid because we used a parser variable @@ -752,7 +752,7 @@ void ClangExpressionDeclMap::SearchPersistenDecls(NameSearchContext &context, MaybeRegisterFunctionBody(parser_function_decl); } - LLDB_LOG(log, " CEDM::FEVD Found persistent decl %s", name); + LLDB_LOG(log, " CEDM::FEVD Found persistent decl {0}", name); context.AddNamedDecl(parser_named_decl); } @@ -1021,7 +1021,8 @@ void ClangExpressionDeclMap::LookupInModulesDeclVendor( if (!m_target) return; - auto *modules_decl_vendor = m_target->GetClangModulesDeclVendor(); + std::shared_ptr<ClangModulesDeclVendor> modules_decl_vendor = + GetClangModulesDeclVendor(); if (!modules_decl_vendor) return; @@ -1213,8 +1214,8 @@ void ClangExpressionDeclMap::LookupFunction( std::vector<clang::NamedDecl *> decls_from_modules; if (target) { - if (ClangModulesDeclVendor *decl_vendor = - target->GetClangModulesDeclVendor()) { + if (std::shared_ptr<ClangModulesDeclVendor> decl_vendor = + GetClangModulesDeclVendor()) { decl_vendor->FindDecls(name, false, UINT32_MAX, decls_from_modules); } } @@ -1493,7 +1494,7 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var, if (var_location_expr.GetExpressionData(const_value_extractor)) { var_location = Value(const_value_extractor.GetDataStart(), const_value_extractor.GetByteSize()); - var_location.SetValueType(Value::eValueTypeHostAddress); + var_location.SetValueType(Value::ValueType::HostAddress); } else { LLDB_LOG(log, "Error evaluating constant variable: {0}", err.AsCString()); return false; @@ -1512,10 +1513,10 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var, if (parser_type) *parser_type = TypeFromParser(type_to_use); - if (var_location.GetContextType() == Value::eContextTypeInvalid) + if (var_location.GetContextType() == Value::ContextType::Invalid) var_location.SetCompilerType(type_to_use); - if (var_location.GetValueType() == Value::eValueTypeFileAddress) { + if (var_location.GetValueType() == Value::ValueType::FileAddress) { SymbolContext var_sc; var->CalculateSymbolContext(&var_sc); @@ -1529,7 +1530,7 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var, if (load_addr != LLDB_INVALID_ADDRESS) { var_location.GetScalar() = load_addr; - var_location.SetValueType(Value::eValueTypeLoadAddress); + var_location.SetValueType(Value::ValueType::LoadAddress); } } @@ -1665,11 +1666,11 @@ void ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context, const Address symbol_address = symbol.GetAddress(); lldb::addr_t symbol_load_addr = symbol_address.GetLoadAddress(target); - // parser_vars->m_lldb_value.SetContext(Value::eContextTypeClangType, + // parser_vars->m_lldb_value.SetContext(Value::ContextType::ClangType, // user_type.GetOpaqueQualType()); parser_vars->m_lldb_value.SetCompilerType(user_type); parser_vars->m_lldb_value.GetScalar() = symbol_load_addr; - parser_vars->m_lldb_value.SetValueType(Value::eValueTypeLoadAddress); + parser_vars->m_lldb_value.SetValueType(Value::ValueType::LoadAddress); parser_vars->m_named_decl = var_decl; parser_vars->m_llvm_value = nullptr; @@ -1860,14 +1861,14 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, entity->GetParserVars(GetParserID()); if (load_addr != LLDB_INVALID_ADDRESS) { - parser_vars->m_lldb_value.SetValueType(Value::eValueTypeLoadAddress); + parser_vars->m_lldb_value.SetValueType(Value::ValueType::LoadAddress); parser_vars->m_lldb_value.GetScalar() = load_addr; } else { // We have to try finding a file address. lldb::addr_t file_addr = fun_address.GetFileAddress(); - parser_vars->m_lldb_value.SetValueType(Value::eValueTypeFileAddress); + parser_vars->m_lldb_value.SetValueType(Value::ValueType::FileAddress); parser_vars->m_lldb_value.GetScalar() = file_addr; } diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h index a9cd5d166b9d..e39dc587bc43 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h @@ -9,8 +9,8 @@ #ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONDECLMAP_H #define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONDECLMAP_H -#include <signal.h> -#include <stdint.h> +#include <csignal> +#include <cstdint> #include <vector> @@ -248,10 +248,10 @@ public: lldb::SymbolType symbol_type); struct TargetInfo { - lldb::ByteOrder byte_order; - size_t address_byte_size; + lldb::ByteOrder byte_order = lldb::eByteOrderInvalid; + size_t address_byte_size = 0; - TargetInfo() : byte_order(lldb::eByteOrderInvalid), address_byte_size(0) {} + TargetInfo() = default; bool IsValid() { return (byte_order != lldb::eByteOrderInvalid && address_byte_size != 0); @@ -308,7 +308,7 @@ private: /// The following values should not live beyond parsing class ParserVars { public: - ParserVars() {} + ParserVars() = default; Target *GetTarget() { if (m_exe_ctx.GetTargetPtr()) @@ -353,16 +353,15 @@ private: /// The following values contain layout information for the materialized /// struct, but are not specific to a single materialization struct StructVars { - StructVars() - : m_struct_alignment(0), m_struct_size(0), m_struct_laid_out(false), - m_result_name(), m_object_pointer_type(nullptr, nullptr) {} - - lldb::offset_t - m_struct_alignment; ///< The alignment of the struct in bytes. - size_t m_struct_size; ///< The size of the struct in bytes. - bool m_struct_laid_out; ///< True if the struct has been laid out and the - ///layout is valid (that is, no new fields have been - ///added since). + StructVars() : m_result_name(), m_object_pointer_type(nullptr, nullptr) {} + + lldb::offset_t m_struct_alignment = + 0; ///< The alignment of the struct in bytes. + size_t m_struct_size = 0; ///< The size of the struct in bytes. + bool m_struct_laid_out = + false; ///< True if the struct has been laid out and the + /// layout is valid (that is, no new fields have been + /// added since). ConstString m_result_name; ///< The name of the result variable ($1, for example) TypeFromUser m_object_pointer_type; ///< The type of the "this" variable, if diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h index e33e5df22236..37bcaf000cfc 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h @@ -38,7 +38,7 @@ public: ExpressionTypeSystemHelper::LLVMCastKind::eKindClangHelper) {} /// Destructor - virtual ~ClangExpressionHelper() {} + virtual ~ClangExpressionHelper() = default; /// Return the object that the parser should use when resolving external /// values. May be NULL if everything should be self-contained. diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp index 7644a5e1423e..0b5e1ab059d2 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp @@ -343,6 +343,7 @@ static void SetupDefaultClangDiagnostics(CompilerInstance &compiler) { const std::vector<const char *> groupsToIgnore = { "unused-value", "odr", + "unused-getter-return-value", }; for (const char *group : groupsToIgnore) { compiler.getDiagnostics().setSeverityForGroup( @@ -513,7 +514,7 @@ ClangExpressionParser::ClangExpressionParser( LLDB_LOGF(log, "Using SIMD alignment: %d", target_info->getSimdDefaultAlign()); LLDB_LOGF(log, "Target datalayout string: '%s'", - target_info->getDataLayout().getStringRepresentation().c_str()); + target_info->getDataLayoutString()); LLDB_LOGF(log, "Target ABI: '%s'", target_info->getABI().str().c_str()); LLDB_LOGF(log, "Target vector alignment: %d", target_info->getMaxVectorAlign()); @@ -657,7 +658,8 @@ ClangExpressionParser::ClangExpressionParser( // // FIXME: We shouldn't need to do this, the target should be immutable once // created. This complexity should be lifted elsewhere. - m_compiler->getTarget().adjust(m_compiler->getLangOpts()); + m_compiler->getTarget().adjust(m_compiler->getDiagnostics(), + m_compiler->getLangOpts()); // 6. Set up the diagnostic buffer for reporting errors @@ -686,11 +688,11 @@ ClangExpressionParser::ClangExpressionParser( break; } - if (ClangModulesDeclVendor *decl_vendor = - target_sp->GetClangModulesDeclVendor()) { - if (auto *clang_persistent_vars = llvm::cast<ClangPersistentVariables>( - target_sp->GetPersistentExpressionStateForLanguage( - lldb::eLanguageTypeC))) { + if (auto *clang_persistent_vars = llvm::cast<ClangPersistentVariables>( + target_sp->GetPersistentExpressionStateForLanguage( + lldb::eLanguageTypeC))) { + if (std::shared_ptr<ClangModulesDeclVendor> decl_vendor = + clang_persistent_vars->GetClangModulesDeclVendor()) { std::unique_ptr<PPCallbacks> pp_callbacks( new LLDBPreprocessorCallbacks(*decl_vendor, *clang_persistent_vars, m_compiler->getSourceManager())); @@ -723,7 +725,7 @@ ClangExpressionParser::ClangExpressionParser( m_compiler->getCodeGenOpts(), *m_llvm_context)); } -ClangExpressionParser::~ClangExpressionParser() {} +ClangExpressionParser::~ClangExpressionParser() = default; namespace { diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp index 180e08b03c93..31707f81a270 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp @@ -31,6 +31,7 @@ using namespace lldb_private; #define PREFIX_NAME "<lldb wrapper prefix>" +#define SUFFIX_NAME "<lldb wrapper suffix>" const llvm::StringRef ClangExpressionSourceCode::g_prefix_file_name = PREFIX_NAME; @@ -73,6 +74,9 @@ extern "C" } )"; +const char *ClangExpressionSourceCode::g_expression_suffix = + "\n;\n#line 1 \"" SUFFIX_NAME "\"\n"; + namespace { class AddMacroState { @@ -180,7 +184,7 @@ lldb_private::ClangExpressionSourceCode::ClangExpressionSourceCode( // containing only the user expression. This will hide our wrapper code // from the user when we render diagnostics with Clang. m_start_marker = "#line 1 \"" + filename.str() + "\"\n"; - m_end_marker = "\n;\n#line 1 \"<lldb wrapper suffix>\"\n"; + m_end_marker = g_expression_suffix; } namespace { @@ -314,10 +318,11 @@ bool ClangExpressionSourceCode::GetText( } } - ClangModulesDeclVendor *decl_vendor = target->GetClangModulesDeclVendor(); auto *persistent_vars = llvm::cast<ClangPersistentVariables>( target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC)); - if (decl_vendor && persistent_vars) { + std::shared_ptr<ClangModulesDeclVendor> decl_vendor = + persistent_vars->GetClangModulesDeclVendor(); + if (decl_vendor) { const ClangModulesDeclVendor::ModuleVector &hand_imported_modules = persistent_vars->GetHandLoadedClangModules(); ClangModulesDeclVendor::ModuleVector modules_for_macros; diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h index 9a54f0e3ad8d..54ae837fb30f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h @@ -27,6 +27,7 @@ public: /// the user expression. static const llvm::StringRef g_prefix_file_name; static const char *g_expression_prefix; + static const char *g_expression_suffix; /// The possible ways an expression can be wrapped. enum class WrapKind { diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h index 58d589962abe..7bb68e78373f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h @@ -9,9 +9,9 @@ #ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONVARIABLE_H #define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONVARIABLE_H -#include <signal.h> -#include <stdint.h> -#include <string.h> +#include <csignal> +#include <cstdint> +#include <cstring> #include <map> #include <string> @@ -116,19 +116,19 @@ public: /// The following values should not live beyond parsing class ParserVars { public: - ParserVars() - : m_named_decl(nullptr), m_llvm_value(nullptr), - m_lldb_value(), m_lldb_var(), m_lldb_sym(nullptr) {} - - const clang::NamedDecl - *m_named_decl; ///< The Decl corresponding to this variable - llvm::Value *m_llvm_value; ///< The IR value corresponding to this variable; - ///usually a GlobalValue + ParserVars() : m_lldb_value(), m_lldb_var() {} + + const clang::NamedDecl *m_named_decl = + nullptr; ///< The Decl corresponding to this variable + llvm::Value *m_llvm_value = + nullptr; ///< The IR value corresponding to this variable; + /// usually a GlobalValue lldb_private::Value m_lldb_value; ///< The value found in LLDB for this variable lldb::VariableSP m_lldb_var; ///< The original variable for this variable - const lldb_private::Symbol *m_lldb_sym; ///< The original symbol for this - ///variable, if it was a symbol + const lldb_private::Symbol *m_lldb_sym = + nullptr; ///< The original symbol for this + /// variable, if it was a symbol }; private: @@ -157,13 +157,13 @@ public: /// The following values are valid if the variable is used by JIT code struct JITVars { - JITVars() : m_alignment(0), m_size(0), m_offset(0) {} + JITVars() = default; - lldb::offset_t - m_alignment; ///< The required alignment of the variable, in bytes - size_t m_size; ///< The space required for the variable, in bytes - lldb::offset_t - m_offset; ///< The offset of the variable in the struct, in bytes + lldb::offset_t m_alignment = + 0; ///< The required alignment of the variable, in bytes + size_t m_size = 0; ///< The space required for the variable, in bytes + lldb::offset_t m_offset = + 0; ///< The offset of the variable in the struct, in bytes }; private: diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp index 0c9ad2021035..2cfa9a4c9ccf 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp @@ -59,7 +59,7 @@ ClangFunctionCaller::ClangFunctionCaller(ExecutionContextScope &exe_scope, } // Destructor -ClangFunctionCaller::~ClangFunctionCaller() {} +ClangFunctionCaller::~ClangFunctionCaller() = default; unsigned diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp index c014ad504d37..336058a5abb9 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp @@ -42,9 +42,9 @@ using namespace lldb_private; namespace { -// Any Clang compiler requires a consumer for diagnostics. This one stores -// them as strings so we can provide them to the user in case a module failed -// to load. +/// Any Clang compiler requires a consumer for diagnostics. This one stores +/// them as strings so we can provide them to the user in case a module failed +/// to load. class StoringDiagnosticConsumer : public clang::DiagnosticConsumer { public: StoringDiagnosticConsumer(); @@ -74,8 +74,8 @@ private: Log *m_log; }; -// The private implementation of our ClangModulesDeclVendor. Contains all the -// Clang state required to load modules. +/// The private implementation of our ClangModulesDeclVendor. Contains all the +/// Clang state required to load modules. class ClangModulesDeclVendorImpl : public ClangModulesDeclVendor { public: ClangModulesDeclVendorImpl( @@ -100,9 +100,9 @@ public: std::function<bool(llvm::StringRef, llvm::StringRef)> handler) override; private: - void - ReportModuleExportsHelper(std::set<ClangModulesDeclVendor::ModuleID> &exports, - clang::Module *module); + typedef llvm::DenseSet<ModuleID> ExportedModuleSet; + void ReportModuleExportsHelper(ExportedModuleSet &exports, + clang::Module *module); void ReportModuleExports(ModuleVector &exports, clang::Module *module); @@ -120,7 +120,7 @@ private: typedef std::vector<ConstString> ImportedModule; typedef std::map<ImportedModule, clang::Module *> ImportedModuleMap; - typedef std::set<ModuleID> ImportedModuleSet; + typedef llvm::DenseSet<ModuleID> ImportedModuleSet; ImportedModuleMap m_imported_modules; ImportedModuleSet m_user_imported_modules; // We assume that every ASTContext has an TypeSystemClang, so we also store @@ -176,7 +176,7 @@ void StoringDiagnosticConsumer::EndSourceFile() { ClangModulesDeclVendor::ClangModulesDeclVendor() : ClangDeclVendor(eClangModuleDeclVendor) {} -ClangModulesDeclVendor::~ClangModulesDeclVendor() {} +ClangModulesDeclVendor::~ClangModulesDeclVendor() = default; ClangModulesDeclVendorImpl::ClangModulesDeclVendorImpl( llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagnostics_engine, @@ -195,8 +195,7 @@ ClangModulesDeclVendorImpl::ClangModulesDeclVendorImpl( } void ClangModulesDeclVendorImpl::ReportModuleExportsHelper( - std::set<ClangModulesDeclVendor::ModuleID> &exports, - clang::Module *module) { + ExportedModuleSet &exports, clang::Module *module) { if (exports.count(reinterpret_cast<ClangModulesDeclVendor::ModuleID>(module))) return; @@ -206,20 +205,18 @@ void ClangModulesDeclVendorImpl::ReportModuleExportsHelper( module->getExportedModules(sub_exports); - for (clang::Module *module : sub_exports) { + for (clang::Module *module : sub_exports) ReportModuleExportsHelper(exports, module); - } } void ClangModulesDeclVendorImpl::ReportModuleExports( ClangModulesDeclVendor::ModuleVector &exports, clang::Module *module) { - std::set<ClangModulesDeclVendor::ModuleID> exports_set; + ExportedModuleSet exports_set; ReportModuleExportsHelper(exports_set, module); - for (ModuleID module : exports_set) { + for (ModuleID module : exports_set) exports.push_back(module); - } } bool ClangModulesDeclVendorImpl::AddModule(const SourceModule &module, @@ -237,17 +234,15 @@ bool ClangModulesDeclVendorImpl::AddModule(const SourceModule &module, std::vector<ConstString> imported_module; - for (ConstString path_component : module.path) { + for (ConstString path_component : module.path) imported_module.push_back(path_component); - } { ImportedModuleMap::iterator mi = m_imported_modules.find(imported_module); if (mi != m_imported_modules.end()) { - if (exported_modules) { + if (exported_modules) ReportModuleExports(*exported_modules, mi->second); - } return true; } } @@ -338,9 +333,8 @@ bool ClangModulesDeclVendorImpl::AddModule(const SourceModule &module, clang::Module *requested_module = DoGetModule(clang_path, true); if (requested_module != nullptr) { - if (exported_modules) { + if (exported_modules) ReportModuleExports(*exported_modules, requested_module); - } m_imported_modules[imported_module] = requested_module; @@ -388,9 +382,8 @@ uint32_t ClangModulesDeclVendorImpl::FindDecls(ConstString name, bool append, uint32_t max_matches, std::vector<CompilerDecl> &decls) { - if (!m_enabled) { + if (!m_enabled) return 0; - } if (!append) decls.clear(); @@ -423,18 +416,16 @@ ClangModulesDeclVendorImpl::FindDecls(ConstString name, bool append, void ClangModulesDeclVendorImpl::ForEachMacro( const ClangModulesDeclVendor::ModuleVector &modules, std::function<bool(llvm::StringRef, llvm::StringRef)> handler) { - if (!m_enabled) { + if (!m_enabled) return; - } typedef std::map<ModuleID, ssize_t> ModulePriorityMap; ModulePriorityMap module_priorities; ssize_t priority = 0; - for (ModuleID module : modules) { + for (ModuleID module : modules) module_priorities[module] = priority++; - } if (m_compiler_instance->getPreprocessor().getExternalSource()) { m_compiler_instance->getPreprocessor() @@ -455,9 +446,8 @@ void ClangModulesDeclVendorImpl::ForEachMacro( .getExternalIdentifierLookup()) { lookup->get(mi->first->getName()); } - if (!ii) { + if (!ii) ii = mi->first; - } } ssize_t found_priority = -1; @@ -504,24 +494,21 @@ void ClangModulesDeclVendorImpl::ForEachMacro( for (auto pi = macro_info->param_begin(), pe = macro_info->param_end(); pi != pe; ++pi) { - if (!first_arg) { + if (!first_arg) macro_expansion.append(", "); - } else { + else first_arg = false; - } macro_expansion.append((*pi)->getName().str()); } if (macro_info->isC99Varargs()) { - if (first_arg) { + if (first_arg) macro_expansion.append("..."); - } else { + else macro_expansion.append(", ..."); - } - } else if (macro_info->isGNUVarargs()) { + } else if (macro_info->isGNUVarargs()) macro_expansion.append("..."); - } macro_expansion.append(")"); } @@ -533,11 +520,10 @@ void ClangModulesDeclVendorImpl::ForEachMacro( for (clang::MacroInfo::tokens_iterator ti = macro_info->tokens_begin(), te = macro_info->tokens_end(); ti != te; ++ti) { - if (!first_token) { + if (!first_token) macro_expansion.append(" "); - } else { + else first_token = false; - } if (ti->isLiteral()) { if (const char *literal_data = ti->getLiteralData()) { @@ -718,7 +704,7 @@ ClangModulesDeclVendor::Create(Target &target) { if (!instance->hasTarget()) return nullptr; - instance->getTarget().adjust(instance->getLangOpts()); + instance->getTarget().adjust(*diagnostics_engine, instance->getLangOpts()); if (!action->BeginSourceFile(*instance, instance->getFrontendOpts().Inputs[0])) diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp index 42afac9edb0d..13d6a37113b8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp @@ -8,6 +8,7 @@ #include "ClangPersistentVariables.h" #include "ClangASTImporter.h" +#include "ClangModulesDeclVendor.h" #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/Value.h" @@ -23,8 +24,10 @@ using namespace lldb; using namespace lldb_private; -ClangPersistentVariables::ClangPersistentVariables() - : lldb_private::PersistentExpressionState(LLVMCastKind::eKindClang) {} +ClangPersistentVariables::ClangPersistentVariables( + std::shared_ptr<Target> target_sp) + : lldb_private::PersistentExpressionState(LLVMCastKind::eKindClang), + m_target_sp(target_sp) {} ExpressionVariableSP ClangPersistentVariables::CreatePersistentVariable( const lldb::ValueObjectSP &valobj_sp) { @@ -109,6 +112,15 @@ ClangPersistentVariables::GetClangASTImporter() { return m_ast_importer_sp; } +std::shared_ptr<ClangModulesDeclVendor> +ClangPersistentVariables::GetClangModulesDeclVendor() { + if (!m_modules_decl_vendor_sp) { + m_modules_decl_vendor_sp.reset( + ClangModulesDeclVendor::Create(*m_target_sp.get())); + } + return m_modules_decl_vendor_sp; +} + ConstString ClangPersistentVariables::GetNextPersistentVariableName(bool is_error) { llvm::SmallString<64> name; diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h index f888b2d56e68..b8a359d05f75 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h @@ -19,6 +19,8 @@ namespace lldb_private { class ClangASTImporter; +class ClangModulesDeclVendor; +class Target; class TypeSystemClang; /// \class ClangPersistentVariables ClangPersistentVariables.h @@ -30,7 +32,7 @@ class TypeSystemClang; /// 0-based counter for naming result variables. class ClangPersistentVariables : public PersistentExpressionState { public: - ClangPersistentVariables(); + ClangPersistentVariables(std::shared_ptr<Target> target_sp); ~ClangPersistentVariables() override = default; @@ -40,6 +42,7 @@ public: } std::shared_ptr<ClangASTImporter> GetClangASTImporter(); + std::shared_ptr<ClangModulesDeclVendor> GetClangModulesDeclVendor(); lldb::ExpressionVariableSP CreatePersistentVariable(const lldb::ValueObjectSP &valobj_sp) override; @@ -106,6 +109,8 @@ private: ///these are the highest- ///< priority source for macros. std::shared_ptr<ClangASTImporter> m_ast_importer_sp; + std::shared_ptr<ClangModulesDeclVendor> m_modules_decl_vendor_sp; + std::shared_ptr<Target> m_target_sp; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp index 9be294750fa0..1b205b13113b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp @@ -8,7 +8,7 @@ #include "lldb/Host/Config.h" -#include <stdio.h> +#include <cstdio> #if HAVE_SYS_TYPES_H #include <sys/types.h> #endif @@ -90,7 +90,7 @@ ClangUserExpression::ClangUserExpression( } } -ClangUserExpression::~ClangUserExpression() {} +ClangUserExpression::~ClangUserExpression() = default; void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); @@ -349,10 +349,6 @@ bool ClangUserExpression::SetupPersistentState(DiagnosticManager &diagnostic_man static void SetupDeclVendor(ExecutionContext &exe_ctx, Target *target, DiagnosticManager &diagnostic_manager) { - ClangModulesDeclVendor *decl_vendor = target->GetClangModulesDeclVendor(); - if (!decl_vendor) - return; - if (!target->GetEnableAutoImportClangModules()) return; @@ -361,6 +357,11 @@ static void SetupDeclVendor(ExecutionContext &exe_ctx, Target *target, if (!persistent_state) return; + std::shared_ptr<ClangModulesDeclVendor> decl_vendor = + persistent_state->GetClangModulesDeclVendor(); + if (!decl_vendor) + return; + StackFrame *frame = exe_ctx.GetFramePtr(); if (!frame) return; diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp index 9788a4e1c183..a78116352c2e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp @@ -14,7 +14,7 @@ #include "ClangExpressionSourceCode.h" #include "ClangPersistentVariables.h" -#include <stdio.h> +#include <cstdio> #if HAVE_SYS_TYPES_H #include <sys/types.h> #endif @@ -34,21 +34,38 @@ using namespace lldb_private; char ClangUtilityFunction::ID; -/// Constructor -/// -/// \param[in] text -/// The text of the function. Must be a full translation unit. -/// -/// \param[in] name -/// The name of the function, as used in the text. ClangUtilityFunction::ClangUtilityFunction(ExecutionContextScope &exe_scope, - std::string text, std::string name) + std::string text, std::string name, + bool enable_debugging) : UtilityFunction( exe_scope, - std::string(ClangExpressionSourceCode::g_expression_prefix) + text, - std::move(name)) {} + std::string(ClangExpressionSourceCode::g_expression_prefix) + text + + std::string(ClangExpressionSourceCode::g_expression_suffix), + std::move(name), enable_debugging) { + // Write the source code to a file so that LLDB's source manager can display + // it when debugging the code. + if (enable_debugging) { + int temp_fd = -1; + llvm::SmallString<128> result_path; + llvm::sys::fs::createTemporaryFile("lldb", "expr", temp_fd, result_path); + if (temp_fd != -1) { + lldb_private::NativeFile file(temp_fd, File::eOpenOptionWrite, true); + text = "#line 1 \"" + std::string(result_path) + "\"\n" + text; + size_t bytes_written = text.size(); + file.Write(text.c_str(), bytes_written); + if (bytes_written == text.size()) { + // If we successfully wrote the source to a temporary file, replace the + // function text with the next text containing the line directive. + m_function_text = + std::string(ClangExpressionSourceCode::g_expression_prefix) + text + + std::string(ClangExpressionSourceCode::g_expression_suffix); + } + file.Close(); + } + } +} -ClangUtilityFunction::~ClangUtilityFunction() {} +ClangUtilityFunction::~ClangUtilityFunction() = default; /// Install the utility function into a process /// diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h index 7914e1406cd0..b8a154b3baed 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h @@ -48,8 +48,11 @@ public: /// /// \param[in] name /// The name of the function, as used in the text. + /// + /// \param[in] enable_debugging + /// Enable debugging of this function. ClangUtilityFunction(ExecutionContextScope &exe_scope, std::string text, - std::string name); + std::string name, bool enable_debugging); ~ClangUtilityFunction() override; @@ -71,9 +74,9 @@ public: private: class ClangUtilityFunctionHelper : public ClangExpressionHelper { public: - ClangUtilityFunctionHelper() {} + ClangUtilityFunctionHelper() = default; - ~ClangUtilityFunctionHelper() override {} + ~ClangUtilityFunctionHelper() override = default; /// Return the object that the parser should use when resolving external /// values. May be NULL if everything should be self-contained. diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h index b984db43fa6d..425106bba0a3 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h @@ -59,7 +59,7 @@ public: /// Creates a configuration by analyzing the given list of used source files. explicit CppModuleConfiguration(const FileSpecList &support_files); /// Creates an empty and invalid configuration. - CppModuleConfiguration() {} + CppModuleConfiguration() = default; /// Returns true iff this is a valid configuration that can be used to /// load and compile modules. diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp index f953e860969c..74dd04600b4b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp @@ -33,6 +33,9 @@ CxxModuleHandler::CxxModuleHandler(ASTImporter &importer, ASTContext *target) "shared_ptr", "unique_ptr", "weak_ptr", + // iterator + "move_iterator", + "__wrap_iter", // utility "allocator", "pair", diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp index b35bf07034bd..5655d548ee34 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp @@ -14,6 +14,7 @@ #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/Operator.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" @@ -41,14 +42,12 @@ using namespace llvm; -static char ID; - typedef SmallVector<Instruction *, 2> InstrList; IRForTarget::FunctionValueCache::FunctionValueCache(Maker const &maker) : m_maker(maker), m_values() {} -IRForTarget::FunctionValueCache::~FunctionValueCache() {} +IRForTarget::FunctionValueCache::~FunctionValueCache() = default; llvm::Value * IRForTarget::FunctionValueCache::GetValue(llvm::Function *function) { @@ -72,13 +71,9 @@ IRForTarget::IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map, lldb_private::IRExecutionUnit &execution_unit, lldb_private::Stream &error_stream, const char *func_name) - : ModulePass(ID), m_resolve_vars(resolve_vars), m_func_name(func_name), - m_module(nullptr), m_decl_map(decl_map), - m_CFStringCreateWithBytes(nullptr), m_sel_registerName(nullptr), - m_objc_getClass(nullptr), m_intptr_ty(nullptr), - m_error_stream(error_stream), m_execution_unit(execution_unit), - m_result_store(nullptr), m_result_is_pointer(false), - m_reloc_placeholder(nullptr), + : m_resolve_vars(resolve_vars), m_func_name(func_name), + m_decl_map(decl_map), m_error_stream(error_stream), + m_execution_unit(execution_unit), m_entry_instruction_finder(FindEntryInstruction) {} /* Handy utility functions used at several places in the code */ @@ -105,8 +100,6 @@ static std::string PrintType(const llvm::Type *type, bool truncate = false) { return s; } -IRForTarget::~IRForTarget() {} - bool IRForTarget::FixFunctionLinkage(llvm::Function &llvm_function) { llvm_function.setLinkage(GlobalValue::ExternalLinkage); @@ -1582,20 +1575,14 @@ bool IRForTarget::UnfoldConstant(Constant *old_constant, FunctionValueCache get_element_pointer_maker( [&value_maker, &entry_instruction_finder, old_constant, constant_expr](llvm::Function *function) -> llvm::Value * { - Value *ptr = constant_expr->getOperand(0); + auto *gep = cast<llvm::GEPOperator>(constant_expr); + Value *ptr = gep->getPointerOperand(); if (ptr == old_constant) ptr = value_maker.GetValue(function); std::vector<Value *> index_vector; - - unsigned operand_index; - unsigned num_operands = constant_expr->getNumOperands(); - - for (operand_index = 1; operand_index < num_operands; - ++operand_index) { - Value *operand = constant_expr->getOperand(operand_index); - + for (Value *operand : gep->indices()) { if (operand == old_constant) operand = value_maker.GetValue(function); @@ -1605,7 +1592,7 @@ bool IRForTarget::UnfoldConstant(Constant *old_constant, ArrayRef<Value *> indices(index_vector); return GetElementPtrInst::Create( - nullptr, ptr, indices, "", + gep->getSourceElementType(), ptr, indices, "", llvm::cast<Instruction>( entry_instruction_finder.GetValue(function))); }); @@ -1788,7 +1775,8 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) { ConstantInt *offset_int( ConstantInt::get(offset_type, offset, true)); GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create( - nullptr, argument, offset_int, "", entry_instruction); + argument->getType()->getPointerElementType(), argument, + offset_int, "", entry_instruction); if (name == m_result_name && !m_result_is_pointer) { BitCastInst *bit_cast = new BitCastInst( @@ -2022,10 +2010,3 @@ bool IRForTarget::runOnModule(Module &llvm_module) { return true; } - -void IRForTarget::assignPassManager(PMStack &pass_mgr_stack, - PassManagerType pass_mgr_type) {} - -PassManagerType IRForTarget::getPotentialPassManagerType() const { - return PMT_ModulePassManager; -} diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h index ebfc0cae626c..5f212fa8f918 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h @@ -58,7 +58,7 @@ class IRMemoryMap; /// transformations to the IR which make it relocatable. These /// transformations are discussed in more detail next to their relevant /// functions. -class IRForTarget : public llvm::ModulePass { +class IRForTarget { public: enum class LookupResult { Success, Fail, Ignore }; @@ -87,9 +87,6 @@ public: lldb_private::Stream &error_stream, const char *func_name = "$__lldb_expr"); - /// Destructor - ~IRForTarget() override; - /// Run this IR transformer on a single module /// /// Implementation of the llvm::ModulePass::runOnModule() function. @@ -101,20 +98,7 @@ public: /// /// \return /// True on success; false otherwise - bool runOnModule(llvm::Module &llvm_module) override; - - /// Interface stub - /// - /// Implementation of the llvm::ModulePass::assignPassManager() function. - void assignPassManager(llvm::PMStack &pass_mgr_stack, - llvm::PassManagerType pass_mgr_type = - llvm::PMT_ModulePassManager) override; - - /// Returns PMT_ModulePassManager - /// - /// Implementation of the llvm::ModulePass::getPotentialPassManagerType() - /// function. - llvm::PassManagerType getPotentialPassManagerType() const override; + bool runOnModule(llvm::Module &llvm_module); private: /// Ensures that the current function's linkage is set to external. @@ -419,51 +403,46 @@ private: /// True on success; false otherwise bool ReplaceVariables(llvm::Function &llvm_function); - /// Flags - bool m_resolve_vars; ///< True if external variable references and persistent - ///variable references should be resolved - lldb_private::ConstString - m_func_name; ///< The name of the function to translate - lldb_private::ConstString - m_result_name; ///< The name of the result variable ($0, $1, ...) - lldb_private::TypeFromParser - m_result_type; ///< The type of the result variable. - llvm::Module *m_module; ///< The module being processed, or NULL if that has - ///not been determined yet. - std::unique_ptr<llvm::DataLayout> m_target_data; ///< The target data for the - ///module being processed, or - ///NULL if there is no - ///module. - lldb_private::ClangExpressionDeclMap - *m_decl_map; ///< The DeclMap containing the Decls - llvm::FunctionCallee - m_CFStringCreateWithBytes; ///< The address of the function - /// CFStringCreateWithBytes, cast to the - /// appropriate function pointer type - llvm::FunctionCallee m_sel_registerName; ///< The address of the function - /// sel_registerName, cast to the - /// appropriate function pointer type - llvm::FunctionCallee m_objc_getClass; ///< The address of the function - /// objc_getClass, cast to the - /// appropriate function pointer type - llvm::IntegerType - *m_intptr_ty; ///< The type of an integer large enough to hold a pointer. - lldb_private::Stream - &m_error_stream; ///< The stream on which errors should be printed - lldb_private::IRExecutionUnit & - m_execution_unit; ///< The execution unit containing the IR being created. - - llvm::StoreInst *m_result_store; ///< If non-NULL, the store instruction that - ///writes to the result variable. If - /// m_has_side_effects is true, this is - /// NULL. - bool m_result_is_pointer; ///< True if the function's result in the AST is a - ///pointer (see comments in - /// ASTResultSynthesizer::SynthesizeBodyResult) - + /// True if external variable references and persistent variable references + /// should be resolved + bool m_resolve_vars; + /// The name of the function to translate + lldb_private::ConstString m_func_name; + /// The name of the result variable ($0, $1, ...) + lldb_private::ConstString m_result_name; + /// The type of the result variable. + lldb_private::TypeFromParser m_result_type; + /// The module being processed, or NULL if that has not been determined yet. + llvm::Module *m_module = nullptr; + /// The target data for the module being processed, or NULL if there is no + /// module. + std::unique_ptr<llvm::DataLayout> m_target_data; + /// The DeclMap containing the Decls + lldb_private::ClangExpressionDeclMap *m_decl_map; + /// The address of the function CFStringCreateWithBytes, cast to the + /// appropriate function pointer type + llvm::FunctionCallee m_CFStringCreateWithBytes; + /// The address of the function sel_registerName, cast to the appropriate + /// function pointer type. + llvm::FunctionCallee m_sel_registerName; + /// The address of the function objc_getClass, cast to the appropriate + /// function pointer type. + llvm::FunctionCallee m_objc_getClass; + /// The type of an integer large enough to hold a pointer. + llvm::IntegerType *m_intptr_ty = nullptr; + /// The stream on which errors should be printed. + lldb_private::Stream &m_error_stream; + /// The execution unit containing the IR being created. + lldb_private::IRExecutionUnit &m_execution_unit; + /// If non-NULL, the store instruction that writes to the result variable. If + /// m_has_side_effects is true, this is NULL. + llvm::StoreInst *m_result_store = nullptr; + /// True if the function's result in the AST is a pointer (see comments in + /// ASTResultSynthesizer::SynthesizeBodyResult) + bool m_result_is_pointer = false; /// A placeholder that will be replaced by a pointer to the final location of /// the static allocation. - llvm::GlobalVariable *m_reloc_placeholder; + llvm::GlobalVariable *m_reloc_placeholder = nullptr; class FunctionValueCache { public: diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp index 555912780df9..bf0bbdab740f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include <stdlib.h> +#include <cstdlib> #include "EmulateInstructionARM.h" #include "EmulationStateARM.h" diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h index d15d80c97e38..dfd7c926dabf 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h @@ -19,8 +19,8 @@ namespace lldb_private { // ITSession - Keep track of the IT Block progression. class ITSession { public: - ITSession() : ITCounter(0), ITState(0) {} - ~ITSession() {} + ITSession() = default; + ~ITSession() = default; // InitIT - Initializes ITCounter/ITState. bool InitIT(uint32_t bits7_0); @@ -39,8 +39,8 @@ public: uint32_t GetCond(); private: - uint32_t ITCounter; // Possible values: 0, 1, 2, 3, 4. - uint32_t ITState; // A2.5.2 Consists of IT[7:5] and IT[4:0] initially. + uint32_t ITCounter = 0; // Possible values: 0, 1, 2, 3, 4. + uint32_t ITState = 0; // A2.5.2 Consists of IT[7:5] and IT[4:0] initially. }; class EmulateInstructionARM : public EmulateInstruction { diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp index aef08baa8ae9..569482c7b23b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp @@ -20,11 +20,11 @@ using namespace lldb; using namespace lldb_private; -EmulationStateARM::EmulationStateARM() : m_gpr(), m_vfp_regs(), m_memory() { +EmulationStateARM::EmulationStateARM() : m_vfp_regs(), m_memory() { ClearPseudoRegisters(); } -EmulationStateARM::~EmulationStateARM() {} +EmulationStateARM::~EmulationStateARM() = default; bool EmulationStateARM::LoadPseudoRegistersFromFrame(StackFrame &frame) { RegisterContext *reg_ctx = frame.GetRegisterContext().get(); diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h index 955c7c642058..28bc5d98649d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h @@ -61,7 +61,7 @@ public: const lldb_private::RegisterValue ®_value); private: - uint32_t m_gpr[17]; + uint32_t m_gpr[17] = {0}; struct _sd_regs { uint32_t s_regs[32]; // sregs 0 - 31 & dregs 0 - 15 diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp b/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp index d4cb726fc7e5..a1a93c0b5a5f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp @@ -8,7 +8,7 @@ #include "EmulateInstructionMIPS.h" -#include <stdlib.h> +#include <cstdlib> #include "lldb/Core/Address.h" #include "lldb/Core/Opcode.h" @@ -159,8 +159,8 @@ EmulateInstructionMIPS::EmulateInstructionMIPS( target->createMCSubtargetInfo(triple.getTriple(), cpu, features)); assert(m_asm_info.get() && m_subtype_info.get()); - m_context = std::make_unique<llvm::MCContext>(m_asm_info.get(), - m_reg_info.get(), nullptr); + m_context = std::make_unique<llvm::MCContext>( + triple, m_asm_info.get(), m_reg_info.get(), m_subtype_info.get()); assert(m_context.get()); m_disasm.reset(target->createMCDisassembler(*m_subtype_info, *m_context)); @@ -1018,8 +1018,9 @@ bool EmulateInstructionMIPS::SetInstruction(const Opcode &insn_opcode, const size_t bytes_read = target->ReadMemory(next_addr, /* Address of next instruction */ - true, /* prefer_file_cache */ - buf, sizeof(uint32_t), error, &load_addr); + buf, sizeof(uint32_t), error, + false, /* force_live_memory */ + &load_addr); if (bytes_read == 0) return true; diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp b/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp index 4ccaf0de0758..6044d00c0cbf 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp @@ -8,7 +8,7 @@ #include "EmulateInstructionMIPS64.h" -#include <stdlib.h> +#include <cstdlib> #include "lldb/Core/Address.h" #include "lldb/Core/Opcode.h" @@ -163,8 +163,8 @@ EmulateInstructionMIPS64::EmulateInstructionMIPS64( target->createMCSubtargetInfo(triple.getTriple(), cpu, features)); assert(m_asm_info.get() && m_subtype_info.get()); - m_context = std::make_unique<llvm::MCContext>(m_asm_info.get(), - m_reg_info.get(), nullptr); + m_context = std::make_unique<llvm::MCContext>( + triple, m_asm_info.get(), m_reg_info.get(), m_subtype_info.get()); assert(m_context.get()); m_disasm.reset(target->createMCDisassembler(*m_subtype_info, *m_context)); diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp b/contrib/llvm-project/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp index 5d97513c0be7..4e78c369c128 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp @@ -8,7 +8,7 @@ #include "EmulateInstructionPPC64.h" -#include <stdlib.h> +#include <cstdlib> #include "lldb/Core/PluginManager.h" #include "lldb/Symbol/UnwindPlan.h" diff --git a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp index 99784bd3dbd1..9a88b343878c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp @@ -127,7 +127,7 @@ InstrumentationRuntimeMainThreadChecker::RetrieveReportData( StackFrameSP responsible_frame; for (unsigned I = 0; I < thread_sp->GetStackFrameCount(); ++I) { StackFrameSP frame = thread_sp->GetStackFrameAtIndex(I); - Address addr = frame->GetFrameCodeAddress(); + Address addr = frame->GetFrameCodeAddressForSymbolication(); if (addr.GetModule() == runtime_module_sp) // Skip PCs from the runtime. continue; @@ -135,11 +135,6 @@ InstrumentationRuntimeMainThreadChecker::RetrieveReportData( if (!responsible_frame) responsible_frame = frame; - // First frame in stacktrace should point to a real PC, not return address. - if (I != 0 && trace->GetSize() == 0) { - addr.Slide(-1); - } - lldb::addr_t PC = addr.GetLoadAddress(&target); trace->AddItem(StructuredData::ObjectSP(new StructuredData::Integer(PC))); } @@ -271,8 +266,11 @@ InstrumentationRuntimeMainThreadChecker::GetBacktracesFromExtendedStopInfo( info->GetObjectForDotSeparatedPath("tid"); tid_t tid = thread_id_obj ? thread_id_obj->GetIntegerValue() : 0; - HistoryThread *history_thread = new HistoryThread(*process_sp, tid, PCs); - ThreadSP new_thread_sp(history_thread); + // We gather symbolication addresses above, so no need for HistoryThread to + // try to infer the call addresses. + bool pcs_are_call_addresses = true; + ThreadSP new_thread_sp = std::make_shared<HistoryThread>( + *process_sp, tid, PCs, pcs_are_call_addresses); // Save this in the Process' ExtendedThreadList so a strong pointer retains // the object diff --git a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp index b60eb53f3d4a..58bc38a551f0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp @@ -29,7 +29,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Stream.h" -#include <ctype.h> +#include <cctype> #include <memory> @@ -150,8 +150,8 @@ StructuredData::ObjectSP InstrumentationRuntimeUBSan::RetrieveReportData( StructuredData::Array *trace = new StructuredData::Array(); auto trace_sp = StructuredData::ObjectSP(trace); for (unsigned I = 0; I < thread_sp->GetStackFrameCount(); ++I) { - const Address FCA = - thread_sp->GetStackFrameAtIndex(I)->GetFrameCodeAddress(); + const Address FCA = thread_sp->GetStackFrameAtIndex(I) + ->GetFrameCodeAddressForSymbolication(); if (FCA.GetModule() == runtime_module_sp) // Skip PCs from the runtime. continue; @@ -324,8 +324,11 @@ InstrumentationRuntimeUBSan::GetBacktracesFromExtendedStopInfo( info->GetObjectForDotSeparatedPath("tid"); tid_t tid = thread_id_obj ? thread_id_obj->GetIntegerValue() : 0; - HistoryThread *history_thread = new HistoryThread(*process_sp, tid, PCs); - ThreadSP new_thread_sp(history_thread); + // We gather symbolication addresses above, so no need for HistoryThread to + // try to infer the call addresses. + bool pcs_are_call_addresses = true; + ThreadSP new_thread_sp = std::make_shared<HistoryThread>( + *process_sp, tid, PCs, pcs_are_call_addresses); std::string stop_reason_description = GetStopReasonDescription(info); new_thread_sp->SetName(stop_reason_description.c_str()); diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp index 35788a6445c2..1c498a2ddc11 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp @@ -74,14 +74,12 @@ public: const CompilerType reserved_type = clang_ast_context->GetBasicType(lldb::eBasicTypeInt); const char *const FuncPtr_name("__FuncPtr"); - const CompilerType FuncPtr_type = - clang_ast_importer->CopyType(*clang_ast_context, function_pointer_type); m_block_struct_type = clang_ast_context->CreateStructForIdentifier( ConstString(), {{isa_name, isa_type}, {flags_name, flags_type}, {reserved_name, reserved_type}, - {FuncPtr_name, FuncPtr_type}}); + {FuncPtr_name, function_pointer_type}}); } ~BlockPointerSyntheticFrontEnd() override = default; diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index d844498fd8a3..895fd55f499c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -59,6 +59,11 @@ lldb_private::ConstString CPlusPlusLanguage::GetPluginNameStatic() { return g_name; } +bool CPlusPlusLanguage::SymbolNameFitsToLanguage(Mangled mangled) const { + const char *mangled_name = mangled.GetMangledName().GetCString(); + return mangled_name && CPlusPlusLanguage::IsCPPMangledName(mangled_name); +} + // PluginInterface protocol lldb_private::ConstString CPlusPlusLanguage::GetPluginName() { @@ -1054,7 +1059,7 @@ CPlusPlusLanguage::GetHardcodedSummaries() { .SetSkipReferences(false), lldb_private::formatters::VectorTypeSummaryProvider, "vector_type pointer summary provider")); - if (valobj.GetCompilerType().IsVectorType(nullptr, nullptr)) { + if (valobj.GetCompilerType().IsVectorType()) { if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled()) return formatter_sp; } @@ -1074,7 +1079,7 @@ CPlusPlusLanguage::GetHardcodedSummaries() { .SetSkipReferences(false), lldb_private::formatters::BlockPointerSummaryProvider, "block pointer summary provider")); - if (valobj.GetCompilerType().IsBlockPointerType(nullptr)) { + if (valobj.GetCompilerType().IsBlockPointerType()) { return formatter_sp; } return nullptr; @@ -1104,7 +1109,7 @@ CPlusPlusLanguage::GetHardcodedSynthetics() { .SetNonCacheable(true), "vector_type synthetic children", lldb_private::formatters::VectorTypeSyntheticFrontEndCreator)); - if (valobj.GetCompilerType().IsVectorType(nullptr, nullptr)) { + if (valobj.GetCompilerType().IsVectorType()) { if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled()) return formatter_sp; } @@ -1123,7 +1128,7 @@ CPlusPlusLanguage::GetHardcodedSynthetics() { .SetNonCacheable(true), "block pointer synthetic children", lldb_private::formatters::BlockPointerSyntheticFrontEndCreator)); - if (valobj.GetCompilerType().IsBlockPointerType(nullptr)) { + if (valobj.GetCompilerType().IsBlockPointerType()) { return formatter_sp; } return nullptr; @@ -1147,7 +1152,7 @@ bool CPlusPlusLanguage::IsSourceFile(llvm::StringRef file_path) const { const auto suffixes = {".cpp", ".cxx", ".c++", ".cc", ".c", ".h", ".hh", ".hpp", ".hxx", ".h++"}; for (auto suffix : suffixes) { - if (file_path.endswith_lower(suffix)) + if (file_path.endswith_insensitive(suffix)) return true; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h index e2b5d2918753..9163be4807ec 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h @@ -28,8 +28,7 @@ public: class MethodName { public: MethodName() - : m_full(), m_basename(), m_context(), m_arguments(), m_qualifiers(), - m_parsed(false), m_parse_error(false) {} + : m_full(), m_basename(), m_context(), m_arguments(), m_qualifiers() {} MethodName(ConstString s) : m_full(s), m_basename(), m_context(), m_arguments(), m_qualifiers(), @@ -68,8 +67,8 @@ public: llvm::StringRef m_context; // Decl context: "lldb::SBTarget" llvm::StringRef m_arguments; // Arguments: "(unsigned int)" llvm::StringRef m_qualifiers; // Qualifiers: "const" - bool m_parsed; - bool m_parse_error; + bool m_parsed = false; + bool m_parse_error = false; }; CPlusPlusLanguage() = default; @@ -105,6 +104,8 @@ public: static lldb_private::ConstString GetPluginNameStatic(); + bool SymbolNameFitsToLanguage(Mangled mangled) const override; + static bool IsCPPMangledName(llvm::StringRef name); // Extract C++ context and identifier from a string using heuristic matching diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h index 6fe6b12725b0..426434c48608 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h @@ -69,7 +69,7 @@ private: size_t begin_index = 0; size_t end_index = 0; - Range() {} + Range() = default; Range(size_t begin, size_t end) : begin_index(begin), end_index(end) { assert(end >= begin); } diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp index 2b16ebe79daf..8eda422f3145 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp @@ -379,8 +379,7 @@ lldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator( lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd:: LibcxxSharedPtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) - : SyntheticChildrenFrontEnd(*valobj_sp), m_cntrl(nullptr), m_count_sp(), - m_weak_count_sp(), m_ptr_size(0), m_byte_order(lldb::eByteOrderInvalid) { + : SyntheticChildrenFrontEnd(*valobj_sp), m_cntrl(nullptr) { if (valobj_sp) Update(); } @@ -403,42 +402,23 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::GetChildAtIndex( if (idx == 0) return valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true); - if (idx > 2) - return lldb::ValueObjectSP(); - if (idx == 1) { - if (!m_count_sp) { - ValueObjectSP shared_owners_sp(m_cntrl->GetChildMemberWithName( - ConstString("__shared_owners_"), true)); - if (!shared_owners_sp) - return lldb::ValueObjectSP(); - uint64_t count = 1 + shared_owners_sp->GetValueAsUnsigned(0); - DataExtractor data(&count, 8, m_byte_order, m_ptr_size); - m_count_sp = CreateValueObjectFromData( - "count", data, valobj_sp->GetExecutionContextRef(), - shared_owners_sp->GetCompilerType()); - } - return m_count_sp; - } else /* if (idx == 2) */ - { - if (!m_weak_count_sp) { - ValueObjectSP shared_weak_owners_sp(m_cntrl->GetChildMemberWithName( - ConstString("__shared_weak_owners_"), true)); - if (!shared_weak_owners_sp) - return lldb::ValueObjectSP(); - uint64_t count = 1 + shared_weak_owners_sp->GetValueAsUnsigned(0); - DataExtractor data(&count, 8, m_byte_order, m_ptr_size); - m_weak_count_sp = CreateValueObjectFromData( - "count", data, valobj_sp->GetExecutionContextRef(), - shared_weak_owners_sp->GetCompilerType()); + if (auto ptr_sp = + valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true)) { + Status status; + auto value_sp = ptr_sp->Dereference(status); + if (status.Success()) { + auto value_type_sp = + valobj_sp->GetCompilerType().GetTypeTemplateArgument(0); + return value_sp->Cast(value_type_sp); + } } - return m_weak_count_sp; } + + return lldb::ValueObjectSP(); } bool lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::Update() { - m_count_sp.reset(); - m_weak_count_sp.reset(); m_cntrl = nullptr; ValueObjectSP valobj_sp = m_backend.GetSP(); @@ -449,9 +429,6 @@ bool lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::Update() { if (!target_sp) return false; - m_byte_order = target_sp->GetArchitecture().GetByteOrder(); - m_ptr_size = target_sp->GetArchitecture().GetAddressByteSize(); - lldb::ValueObjectSP cntrl_sp( valobj_sp->GetChildMemberWithName(ConstString("__cntrl_"), true)); @@ -469,10 +446,8 @@ size_t lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd:: GetIndexOfChildWithName(ConstString name) { if (name == "__ptr_") return 0; - if (name == "count") + if (name == "$$dereference$$") return 1; - if (name == "weak_count") - return 2; return UINT32_MAX; } @@ -488,7 +463,7 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator( lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd:: LibcxxUniquePtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) - : SyntheticChildrenFrontEnd(*valobj_sp), m_compressed_pair_sp() { + : SyntheticChildrenFrontEnd(*valobj_sp) { if (valobj_sp) Update(); } @@ -505,19 +480,27 @@ lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEndCreator( size_t lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd:: CalculateNumChildren() { - return (m_compressed_pair_sp ? 1 : 0); + return (m_value_ptr_sp ? 1 : 0); } lldb::ValueObjectSP lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::GetChildAtIndex( size_t idx) { - if (!m_compressed_pair_sp) + if (!m_value_ptr_sp) return lldb::ValueObjectSP(); - if (idx != 0) - return lldb::ValueObjectSP(); + if (idx == 0) + return m_value_ptr_sp; - return m_compressed_pair_sp; + if (idx == 1) { + Status status; + auto value_sp = m_value_ptr_sp->Dereference(status); + if (status.Success()) { + return value_sp; + } + } + + return lldb::ValueObjectSP(); } bool lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::Update() { @@ -530,7 +513,7 @@ bool lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::Update() { if (!ptr_sp) return false; - m_compressed_pair_sp = GetValueOfLibCXXCompressedPair(*ptr_sp); + m_value_ptr_sp = GetValueOfLibCXXCompressedPair(*ptr_sp); return false; } @@ -544,6 +527,8 @@ size_t lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd:: GetIndexOfChildWithName(ConstString name) { if (name == "__value_") return 0; + if (name == "$$dereference$$") + return 1; return UINT32_MAX; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h index ea5a7c178178..99e206543197 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h @@ -105,10 +105,6 @@ public: private: ValueObject *m_cntrl; - lldb::ValueObjectSP m_count_sp; - lldb::ValueObjectSP m_weak_count_sp; - uint8_t m_ptr_size; - lldb::ByteOrder m_byte_order; }; class LibcxxUniquePtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd { @@ -128,7 +124,7 @@ public: ~LibcxxUniquePtrSyntheticFrontEnd() override; private: - lldb::ValueObjectSP m_compressed_pair_sp; + lldb::ValueObjectSP m_value_ptr_sp; }; SyntheticChildrenFrontEnd * diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp index 6de4637a6a4a..e5b868fc0fce 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp @@ -85,7 +85,7 @@ ValueObjectSP BitsetFrontEnd::GetChildAtIndex(size_t idx) { CompilerType type; ValueObjectSP chunk; // For small bitsets __first_ is not an array, but a plain size_t. - if (m_first->GetCompilerType().IsArrayType(&type, nullptr, nullptr)) { + if (m_first->GetCompilerType().IsArrayType(&type)) { llvm::Optional<uint64_t> bit_size = type.GetBitSize(ctx.GetBestExecutionContextScope()); if (!bit_size || *bit_size == 0) diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp index 0d5ae16a0b29..47c6634ed65e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp @@ -27,8 +27,7 @@ namespace { class ListEntry { public: ListEntry() = default; - ListEntry(ValueObjectSP entry_sp) : m_entry_sp(entry_sp) {} - ListEntry(const ListEntry &rhs) = default; + ListEntry(ValueObjectSP entry_sp) : m_entry_sp(std::move(entry_sp)) {} ListEntry(ValueObject *entry) : m_entry_sp(entry ? entry->GetSP() : ValueObjectSP()) {} @@ -73,9 +72,8 @@ private: class ListIterator { public: ListIterator() = default; - ListIterator(ListEntry entry) : m_entry(entry) {} - ListIterator(ValueObjectSP entry) : m_entry(entry) {} - ListIterator(const ListIterator &rhs) = default; + ListIterator(ListEntry entry) : m_entry(std::move(entry)) {} + ListIterator(ValueObjectSP entry) : m_entry(std::move(entry)) {} ListIterator(ValueObject *entry) : m_entry(entry) {} ValueObjectSP value() { return m_entry.GetEntry(); } diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp index 64a199e24e4a..25c2bfd9387b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp @@ -26,7 +26,6 @@ class MapEntry { public: MapEntry() = default; explicit MapEntry(ValueObjectSP entry_sp) : m_entry_sp(entry_sp) {} - MapEntry(const MapEntry &rhs) = default; explicit MapEntry(ValueObject *entry) : m_entry_sp(entry ? entry->GetSP() : ValueObjectSP()) {} @@ -86,9 +85,9 @@ class MapIterator { public: MapIterator() = default; MapIterator(MapEntry entry, size_t depth = 0) - : m_entry(entry), m_max_depth(depth), m_error(false) {} + : m_entry(std::move(entry)), m_max_depth(depth), m_error(false) {} MapIterator(ValueObjectSP entry, size_t depth = 0) - : m_entry(entry), m_max_depth(depth), m_error(false) {} + : m_entry(std::move(entry)), m_max_depth(depth), m_error(false) {} MapIterator(const MapIterator &rhs) : m_entry(rhs.m_entry), m_max_depth(rhs.m_max_depth), m_error(false) {} MapIterator(ValueObject *entry, size_t depth = 0) @@ -138,7 +137,7 @@ protected: } private: - MapEntry tree_min(MapEntry &&x) { + MapEntry tree_min(MapEntry x) { if (x.null()) return MapEntry(); MapEntry left(x.left()); diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp index 0b34b4e2fc89..79e864a2cbd5 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp @@ -99,9 +99,17 @@ bool LibStdcppUniquePtrSyntheticFrontEnd::Update() { if (ptr_obj) m_ptr_obj = ptr_obj->Clone(ConstString("pointer")).get(); - ValueObjectSP del_obj = tuple_frontend->GetChildAtIndex(1); - if (del_obj) - m_del_obj = del_obj->Clone(ConstString("deleter")).get(); + // Add a 'deleter' child if there was a non-empty deleter type specified. + // + // The object might have size=1 in the TypeSystem but occupies no dedicated + // storage due to no_unique_address, so infer the actual size from the total + // size of the unique_ptr class. If sizeof(unique_ptr) == sizeof(void*) then + // the deleter is empty and should be hidden. + if (tuple_sp->GetByteSize() > ptr_obj->GetByteSize()) { + ValueObjectSP del_obj = tuple_frontend->GetChildAtIndex(1); + if (del_obj) + m_del_obj = del_obj->Clone(ConstString("deleter")).get(); + } if (m_ptr_obj) { Status error; diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/Cocoa.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/Cocoa.cpp index d871d3470e70..1479f4f0c151 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/Cocoa.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/Cocoa.cpp @@ -351,7 +351,7 @@ static void NSNumber_FormatInt(ValueObject &valobj, Stream &stream, int value, } static void NSNumber_FormatLong(ValueObject &valobj, Stream &stream, - uint64_t value, lldb::LanguageType lang) { + int64_t value, lldb::LanguageType lang) { static ConstString g_TypeHint("NSNumber:long"); std::string prefix, suffix; @@ -367,10 +367,10 @@ static void NSNumber_FormatLong(ValueObject &valobj, Stream &stream, } static void NSNumber_FormatInt128(ValueObject &valobj, Stream &stream, - const llvm::APInt &value, - lldb::LanguageType lang) { + const llvm::APInt &value, + lldb::LanguageType lang) { static ConstString g_TypeHint("NSNumber:int128_t"); - + std::string prefix, suffix; if (Language *language = Language::FindPlugin(lang)) { if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, @@ -379,11 +379,11 @@ static void NSNumber_FormatInt128(ValueObject &valobj, Stream &stream, suffix.clear(); } } - + stream.PutCString(prefix.c_str()); const int radix = 10; const bool isSigned = true; - std::string str = value.toString(radix, isSigned); + std::string str = llvm::toString(value, radix, isSigned); stream.PutCString(str.c_str()); stream.PutCString(suffix.c_str()); } @@ -426,6 +426,7 @@ bool lldb_private::formatters::NSNumberSummaryProvider( if (!process_sp) return false; + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS); ObjCLanguageRuntime *runtime = ObjCLanguageRuntime::Get(*process_sp); if (!runtime) @@ -456,9 +457,18 @@ bool lldb_private::formatters::NSNumberSummaryProvider( return NSDecimalNumberSummaryProvider(valobj, stream, options); if (class_name == "NSNumber" || class_name == "__NSCFNumber") { - uint64_t value = 0; + int64_t value = 0; uint64_t i_bits = 0; - if (descriptor->GetTaggedPointerInfo(&i_bits, &value)) { + if (descriptor->GetTaggedPointerInfoSigned(&i_bits, &value)) { + // Check for "preserved" numbers. We still don't support them yet. + if (i_bits & 0x8) { + if (log) + log->Printf( + "Unsupported (preserved) NSNumber tagged pointer 0x%" PRIu64, + valobj_addr); + return false; + } + switch (i_bits) { case 0: NSNumber_FormatChar(valobj, stream, (char)value, options.GetLanguage()); @@ -498,49 +508,66 @@ bool lldb_private::formatters::NSNumberSummaryProvider( f64 = 0x5, sint128 = 0x6 }; - + uint64_t data_location = valobj_addr + 2 * ptr_size; TypeCodes type_code; - + if (new_format) { - uint64_t cfinfoa = - process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, - ptr_size, 0, error); - + uint64_t cfinfoa = process_sp->ReadUnsignedIntegerFromMemory( + valobj_addr + ptr_size, ptr_size, 0, error); + if (error.Fail()) return false; bool is_preserved_number = cfinfoa & 0x8; if (is_preserved_number) { - lldbassert(!static_cast<bool>("We should handle preserved numbers!")); + if (log) + log->Printf( + "Unsupported preserved NSNumber tagged pointer 0x%" PRIu64, + valobj_addr); return false; } type_code = static_cast<TypeCodes>(cfinfoa & 0x7); } else { - uint8_t data_type = - process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, 1, - 0, error) & 0x1F; - + uint8_t data_type = process_sp->ReadUnsignedIntegerFromMemory( + valobj_addr + ptr_size, 1, 0, error) & + 0x1F; + if (error.Fail()) return false; - + switch (data_type) { - case 1: type_code = TypeCodes::sint8; break; - case 2: type_code = TypeCodes::sint16; break; - case 3: type_code = TypeCodes::sint32; break; - case 17: data_location += 8; LLVM_FALLTHROUGH; - case 4: type_code = TypeCodes::sint64; break; - case 5: type_code = TypeCodes::f32; break; - case 6: type_code = TypeCodes::f64; break; - default: return false; + case 1: + type_code = TypeCodes::sint8; + break; + case 2: + type_code = TypeCodes::sint16; + break; + case 3: + type_code = TypeCodes::sint32; + break; + case 17: + data_location += 8; + LLVM_FALLTHROUGH; + case 4: + type_code = TypeCodes::sint64; + break; + case 5: + type_code = TypeCodes::f32; + break; + case 6: + type_code = TypeCodes::f64; + break; + default: + return false; } } - + uint64_t value = 0; bool success = false; switch (type_code) { - case TypeCodes::sint8: + case TypeCodes::sint8: value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 1, 0, error); if (error.Fail()) @@ -548,7 +575,7 @@ bool lldb_private::formatters::NSNumberSummaryProvider( NSNumber_FormatChar(valobj, stream, (char)value, options.GetLanguage()); success = true; break; - case TypeCodes::sint16: + case TypeCodes::sint16: value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 2, 0, error); if (error.Fail()) @@ -573,8 +600,7 @@ bool lldb_private::formatters::NSNumberSummaryProvider( NSNumber_FormatLong(valobj, stream, value, options.GetLanguage()); success = true; break; - case TypeCodes::f32: - { + case TypeCodes::f32: { uint32_t flt_as_int = process_sp->ReadUnsignedIntegerFromMemory( data_location, 4, 0, error); if (error.Fail()) @@ -585,8 +611,7 @@ bool lldb_private::formatters::NSNumberSummaryProvider( success = true; break; } - case TypeCodes::f64: - { + case TypeCodes::f64: { uint64_t dbl_as_lng = process_sp->ReadUnsignedIntegerFromMemory( data_location, 8, 0, error); if (error.Fail()) @@ -600,16 +625,17 @@ bool lldb_private::formatters::NSNumberSummaryProvider( case TypeCodes::sint128: // internally, this is the same { uint64_t words[2]; - words[1] = process_sp->ReadUnsignedIntegerFromMemory( - data_location, 8, 0, error); + words[1] = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8, + 0, error); if (error.Fail()) return false; - words[0] = process_sp->ReadUnsignedIntegerFromMemory( - data_location + 8, 8, 0, error); + words[0] = process_sp->ReadUnsignedIntegerFromMemory(data_location + 8, + 8, 0, error); if (error.Fail()) return false; llvm::APInt i128_value(128, words); - NSNumber_FormatInt128(valobj, stream, i128_value, options.GetLanguage()); + NSNumber_FormatInt128(valobj, stream, i128_value, + options.GetLanguage()); success = true; break; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp index efc80cc75557..a862da551813 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp @@ -13,7 +13,7 @@ #include "lldb/Symbol/TypeSystem.h" #include "lldb/Target/Target.h" -#include <inttypes.h> +#include <cinttypes> using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp index afb9c6951f55..326f47a10660 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp @@ -410,6 +410,7 @@ bool lldb_private::formatters::NSDictionarySummaryProvider( static const ConstString g_DictionaryM("__NSDictionaryM"); static const ConstString g_DictionaryMLegacy("__NSDictionaryM_Legacy"); static const ConstString g_DictionaryMImmutable("__NSDictionaryM_Immutable"); + static const ConstString g_DictionaryMFrozen("__NSFrozenDictionaryM"); static const ConstString g_Dictionary1("__NSSingleEntryDictionaryI"); static const ConstString g_Dictionary0("__NSDictionary0"); static const ConstString g_DictionaryCF("__CFDictionary"); @@ -427,7 +428,8 @@ bool lldb_private::formatters::NSDictionarySummaryProvider( return false; value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U); - } else if (class_name == g_DictionaryM || class_name == g_DictionaryMLegacy) { + } else if (class_name == g_DictionaryM || class_name == g_DictionaryMLegacy + || class_name == g_DictionaryMFrozen) { AppleObjCRuntime *apple_runtime = llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime); Status error; @@ -509,6 +511,7 @@ lldb_private::formatters::NSDictionarySyntheticFrontEndCreator( static const ConstString g_DictionaryM("__NSDictionaryM"); static const ConstString g_Dictionary1("__NSSingleEntryDictionaryI"); static const ConstString g_DictionaryImmutable("__NSDictionaryM_Immutable"); + static const ConstString g_DictionaryMFrozen("__NSFrozenDictionaryM"); static const ConstString g_DictionaryMLegacy("__NSDictionaryM_Legacy"); static const ConstString g_Dictionary0("__NSDictionary0"); static const ConstString g_DictionaryCF("__CFDictionary"); @@ -520,7 +523,7 @@ lldb_private::formatters::NSDictionarySyntheticFrontEndCreator( if (class_name == g_DictionaryI) { return (new NSDictionaryISyntheticFrontEnd(valobj_sp)); - } else if (class_name == g_DictionaryM) { + } else if (class_name == g_DictionaryM || class_name == g_DictionaryMFrozen) { if (runtime->GetFoundationVersion() >= 1437) { return (new Foundation1437::NSDictionaryMSyntheticFrontEnd(valobj_sp)); } else if (runtime->GetFoundationVersion() >= 1428) { diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp index a15b0f64954a..068bca9e7b94 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp @@ -209,14 +209,13 @@ protected: m_process = nullptr; } - InlinedIndexes() - : m_indexes(0), m_count(0), m_ptr_size(0), m_process(nullptr) {} + InlinedIndexes() {} private: - uint64_t m_indexes; - size_t m_count; - uint32_t m_ptr_size; - Process *m_process; + uint64_t m_indexes = 0; + size_t m_count = 0; + uint32_t m_ptr_size = 0; + Process *m_process = nullptr; // cfr. Foundation for the details of this code size_t _lengthForInlinePayload(uint32_t ptr_size) { @@ -271,10 +270,10 @@ protected: m_count = 0; } - OutsourcedIndexes() : m_indexes(nullptr), m_count(0) {} + OutsourcedIndexes() {} - ValueObject *m_indexes; - size_t m_count; + ValueObject *m_indexes = nullptr; + size_t m_count = 0; }; union { @@ -288,9 +287,9 @@ protected: m_outsourced.Clear(); } - Impl() : m_mode(Mode::Invalid) {} + Impl() {} - Mode m_mode; + Mode m_mode = Mode::Invalid; } m_impl; uint32_t m_ptr_size; diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSSet.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSSet.cpp index 4dbbe6fbddff..43ef7b694bbe 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSSet.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSSet.cpp @@ -444,18 +444,12 @@ bool lldb_private::formatters::NSSetISyntheticFrontEnd::Update() { if (!valobj_sp) return false; m_exe_ctx_ref = valobj_sp->GetExecutionContextRef(); - Status error; - if (valobj_sp->IsPointerType()) { - valobj_sp = valobj_sp->Dereference(error); - if (error.Fail() || !valobj_sp) - return false; - } - error.Clear(); lldb::ProcessSP process_sp(valobj_sp->GetProcessSP()); if (!process_sp) return false; m_ptr_size = process_sp->GetAddressByteSize(); - uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size; + uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size; + Status error; if (m_ptr_size == 4) { m_data_32 = new DataDescriptor_32(); process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32), @@ -728,18 +722,12 @@ lldb_private::formatters:: if (!valobj_sp) return false; m_exe_ctx_ref = valobj_sp->GetExecutionContextRef(); - Status error; - if (valobj_sp->IsPointerType()) { - valobj_sp = valobj_sp->Dereference(error); - if (error.Fail() || !valobj_sp) - return false; - } - error.Clear(); lldb::ProcessSP process_sp(valobj_sp->GetProcessSP()); if (!process_sp) return false; m_ptr_size = process_sp->GetAddressByteSize(); - uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size; + uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size; + Status error; if (m_ptr_size == 4) { m_data_32 = new D32(); process_sp->ReadMemory(data_location, m_data_32, sizeof(D32), diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp index 29391daaab93..379c53432b7b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp @@ -225,14 +225,17 @@ ConstString ObjCLanguage::MethodName::GetFullNameWithoutCategory( return ConstString(); } -std::vector<ConstString> +std::vector<Language::MethodNameVariant> ObjCLanguage::GetMethodNameVariants(ConstString method_name) const { - std::vector<ConstString> variant_names; + std::vector<Language::MethodNameVariant> variant_names; ObjCLanguage::MethodName objc_method(method_name.GetCString(), false); if (!objc_method.IsValid(false)) { return variant_names; } + variant_names.emplace_back(objc_method.GetSelector(), + lldb::eFunctionNameTypeSelector); + const bool is_class_method = objc_method.GetType() == MethodName::eTypeClassMethod; const bool is_instance_method = @@ -242,31 +245,43 @@ ObjCLanguage::GetMethodNameVariants(ConstString method_name) const { if (is_class_method || is_instance_method) { if (name_sans_category) - variant_names.emplace_back(name_sans_category); + variant_names.emplace_back(name_sans_category, + lldb::eFunctionNameTypeFull); } else { StreamString strm; strm.Printf("+%s", objc_method.GetFullName().GetCString()); - variant_names.emplace_back(strm.GetString()); + variant_names.emplace_back(ConstString(strm.GetString()), + lldb::eFunctionNameTypeFull); strm.Clear(); strm.Printf("-%s", objc_method.GetFullName().GetCString()); - variant_names.emplace_back(strm.GetString()); + variant_names.emplace_back(ConstString(strm.GetString()), + lldb::eFunctionNameTypeFull); strm.Clear(); if (name_sans_category) { strm.Printf("+%s", name_sans_category.GetCString()); - variant_names.emplace_back(strm.GetString()); + variant_names.emplace_back(ConstString(strm.GetString()), + lldb::eFunctionNameTypeFull); strm.Clear(); strm.Printf("-%s", name_sans_category.GetCString()); - variant_names.emplace_back(strm.GetString()); + variant_names.emplace_back(ConstString(strm.GetString()), + lldb::eFunctionNameTypeFull); } } return variant_names; } +bool ObjCLanguage::SymbolNameFitsToLanguage(Mangled mangled) const { + ConstString demangled_name = mangled.GetDemangledName(); + if (!demangled_name) + return false; + return ObjCLanguage::IsPossibleObjCMethodName(demangled_name.GetCString()); +} + static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) { if (!objc_category_sp) return; @@ -990,8 +1005,11 @@ std::unique_ptr<Language::TypeScavenger> ObjCLanguage::GetTypeScavenger() { bool result = false; if (auto *target = exe_scope->CalculateTarget().get()) { - if (auto *clang_modules_decl_vendor = - target->GetClangModulesDeclVendor()) { + auto *persistent_vars = llvm::cast<ClangPersistentVariables>( + target->GetPersistentExpressionStateForLanguage( + lldb::eLanguageTypeC)); + if (std::shared_ptr<ClangModulesDeclVendor> clang_modules_decl_vendor = + persistent_vars->GetClangModulesDeclVendor()) { ConstString key_cs(key); auto types = clang_modules_decl_vendor->FindTypes( key_cs, /*max_matches*/ UINT32_MAX); @@ -1116,7 +1134,7 @@ bool ObjCLanguage::IsNilReference(ValueObject &valobj) { bool ObjCLanguage::IsSourceFile(llvm::StringRef file_path) const { const auto suffixes = {".h", ".m", ".M"}; for (auto suffix : suffixes) { - if (file_path.endswith_lower(suffix)) + if (file_path.endswith_insensitive(suffix)) return true; } return false; diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h index 02c15e86046b..691c51883c8a 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h @@ -27,9 +27,7 @@ public: public: enum Type { eTypeUnspecified, eTypeClassMethod, eTypeInstanceMethod }; - MethodName() - : m_full(), m_class(), m_category(), m_selector(), - m_type(eTypeUnspecified), m_category_is_valid(false) {} + MethodName() : m_full(), m_class(), m_category(), m_selector() {} MethodName(const char *name, bool strict) : m_full(), m_class(), m_category(), m_selector(), @@ -81,8 +79,8 @@ public: m_class_category; // Class with category: "NSString(my_additions)" ConstString m_category; // Category: "my_additions" ConstString m_selector; // Selector: "myStringWithCString:" - Type m_type; - bool m_category_is_valid; + Type m_type = eTypeUnspecified; + bool m_category_is_valid = false; }; ObjCLanguage() = default; @@ -102,9 +100,12 @@ public: // variant_names[1] => "-[NSString(my_additions) myStringWithCString:]" // variant_names[2] => "+[NSString myStringWithCString:]" // variant_names[3] => "-[NSString myStringWithCString:]" - std::vector<ConstString> + // Also returns the FunctionNameType of each possible name. + std::vector<Language::MethodNameVariant> GetMethodNameVariants(ConstString method_name) const override; + bool SymbolNameFitsToLanguage(Mangled mangled) const override; + lldb::TypeCategoryImplSP GetFormatters() override; std::vector<ConstString> diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp index 0a4017eda434..359978553210 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp @@ -19,7 +19,7 @@ LLDB_PLUGIN_DEFINE(ObjCPlusPlusLanguage) bool ObjCPlusPlusLanguage::IsSourceFile(llvm::StringRef file_path) const { const auto suffixes = {".h", ".mm"}; for (auto suffix : suffixes) { - if (file_path.endswith_lower(suffix)) + if (file_path.endswith_insensitive(suffix)) return true; } return false; diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp index 24ab9cc5f238..bed2a98067e6 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include <string.h> +#include <cstring> #include <memory> @@ -322,6 +322,9 @@ CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo( } } + if (symbol == nullptr) + return optional_info; + // Case 1 or 3 if (scl.GetSize() >= 1) { optional_info = line_entry_helper(target, scl[0], symbol, @@ -397,8 +400,8 @@ CPPLanguageRuntime::GetStepThroughTrampolinePlan(Thread &thread, // We create a ThreadPlan to keep stepping through using the address range // of the current function. ret_plan_sp = std::make_shared<ThreadPlanStepInRange>( - thread, range_of_curr_func, sc, eOnlyThisThread, eLazyBoolYes, - eLazyBoolYes); + thread, range_of_curr_func, sc, nullptr, eOnlyThisThread, + eLazyBoolYes, eLazyBoolYes); return ret_plan_sp; } } diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp index 6ea9751f563a..f5b587c51960 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp @@ -196,7 +196,7 @@ bool ItaniumABILanguageRuntime::GetDynamicTypeAndAddress( // class_type_or_name.Clear(); - value_type = Value::ValueType::eValueTypeScalar; + value_type = Value::ValueType::Scalar; // Only a pointer or reference type can have a different dynamic and static // type: diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp index bdd5c29db848..405b8a6f16b7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp @@ -252,6 +252,7 @@ bool ClassDescriptorV2::method_list_t::Read(Process *process, } bool ClassDescriptorV2::method_t::Read(Process *process, lldb::addr_t addr, + lldb::addr_t relative_selector_base_addr, bool is_small, bool has_direct_sel) { size_t ptr_size = process->GetAddressByteSize(); size_t size = GetSize(process, is_small); @@ -281,6 +282,8 @@ bool ClassDescriptorV2::method_t::Read(Process *process, lldb::addr_t addr, 0, error); if (!error.Success()) return false; + } else if (relative_selector_base_addr != LLDB_INVALID_ADDRESS) { + m_name_ptr = relative_selector_base_addr + nameref_offset; } m_types_ptr = addr + 4 + types_offset; m_imp_ptr = addr + 8 + imp_offset; @@ -389,14 +392,14 @@ bool ClassDescriptorV2::Describe( if (base_method_list->m_entsize != method_t::GetSize(process, is_small)) return false; - std::unique_ptr<method_t> method; - method = std::make_unique<method_t>(); - + std::unique_ptr<method_t> method = std::make_unique<method_t>(); + lldb::addr_t relative_selector_base_addr = + m_runtime.GetRelativeSelectorBaseAddr(); for (uint32_t i = 0, e = base_method_list->m_count; i < e; ++i) { method->Read(process, base_method_list->m_first_ptr + (i * base_method_list->m_entsize), - is_small, has_direct_selector); + relative_selector_base_addr, is_small, has_direct_selector); if (instance_method_func(method->m_name.c_str(), method->m_types.c_str())) break; @@ -514,8 +517,7 @@ uint64_t ClassDescriptorV2::GetInstanceSize() { return 0; } -ClassDescriptorV2::iVarsStorage::iVarsStorage() - : m_filled(false), m_ivars(), m_mutex() {} +ClassDescriptorV2::iVarsStorage::iVarsStorage() : m_ivars(), m_mutex() {} size_t ClassDescriptorV2::iVarsStorage::size() { return m_ivars.size(); } diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h index 9ef21c6e7208..7ba957940ae7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h @@ -41,6 +41,12 @@ public: return false; } + bool GetTaggedPointerInfoSigned(uint64_t *info_bits = nullptr, + int64_t *value_bits = nullptr, + uint64_t *payload = nullptr) override { + return false; + } + uint64_t GetInstanceSize() override; ObjCLanguageRuntime::ObjCISA GetISA() override { return m_objc_class_ptr; } @@ -71,16 +77,14 @@ private: static const uint32_t RW_REALIZED = (1 << 31); struct objc_class_t { - ObjCLanguageRuntime::ObjCISA m_isa; // The class's metaclass. - ObjCLanguageRuntime::ObjCISA m_superclass; - lldb::addr_t m_cache_ptr; - lldb::addr_t m_vtable_ptr; - lldb::addr_t m_data_ptr; - uint8_t m_flags; + ObjCLanguageRuntime::ObjCISA m_isa = 0; // The class's metaclass. + ObjCLanguageRuntime::ObjCISA m_superclass = 0; + lldb::addr_t m_cache_ptr = 0; + lldb::addr_t m_vtable_ptr = 0; + lldb::addr_t m_data_ptr = 0; + uint8_t m_flags = 0; - objc_class_t() - : m_isa(0), m_superclass(0), m_cache_ptr(0), m_vtable_ptr(0), - m_data_ptr(0), m_flags(0) {} + objc_class_t() = default; void Clear() { m_isa = 0; @@ -162,7 +166,8 @@ private: + field_size; // IMP imp; } - bool Read(Process *process, lldb::addr_t addr, bool, bool); + bool Read(Process *process, lldb::addr_t addr, + lldb::addr_t relative_method_lists_base_addr, bool, bool); }; struct ivar_list_t { @@ -207,7 +212,7 @@ private: void fill(AppleObjCRuntimeV2 &runtime, ClassDescriptorV2 &descriptor); private: - bool m_filled; + bool m_filled = false; std::vector<iVarDescriptor> m_ivars; std::recursive_mutex m_mutex; }; @@ -253,7 +258,7 @@ public: ClassDescriptorV2Tagged( ObjCLanguageRuntime::ClassDescriptorSP actual_class_sp, - uint64_t payload) { + uint64_t u_payload, int64_t s_payload) { if (!actual_class_sp) { m_valid = false; return; @@ -264,9 +269,10 @@ public: return; } m_valid = true; - m_payload = payload; + m_payload = u_payload; m_info_bits = (m_payload & 0x0FULL); m_value_bits = (m_payload & ~0x0FULL) >> 4; + m_value_bits_signed = (s_payload & ~0x0FLL) >> 4; } ~ClassDescriptorV2Tagged() override = default; @@ -308,6 +314,18 @@ public: return true; } + bool GetTaggedPointerInfoSigned(uint64_t *info_bits = nullptr, + int64_t *value_bits = nullptr, + uint64_t *payload = nullptr) override { + if (info_bits) + *info_bits = GetInfoBits(); + if (value_bits) + *value_bits = GetValueBitsSigned(); + if (payload) + *payload = GetPayload(); + return true; + } + uint64_t GetInstanceSize() override { return (IsValid() ? m_pointer_size : 0); } @@ -319,6 +337,10 @@ public: // these calls are not part of any formal tagged pointers specification virtual uint64_t GetValueBits() { return (IsValid() ? m_value_bits : 0); } + virtual int64_t GetValueBitsSigned() { + return (IsValid() ? m_value_bits_signed : 0); + } + virtual uint64_t GetInfoBits() { return (IsValid() ? m_info_bits : 0); } virtual uint64_t GetPayload() { return (IsValid() ? m_payload : 0); } @@ -329,6 +351,7 @@ private: bool m_valid; uint64_t m_info_bits; uint64_t m_value_bits; + int64_t m_value_bits_signed; uint64_t m_payload; }; diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp index 7b331307c0f7..9bc40c16e5d0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp @@ -59,7 +59,7 @@ public: clang::DeclContext::lookup_result result = non_const_interface_decl->lookup(name); - return (result.size() != 0); + return (!result.empty()); } while (false); SetNoExternalVisibleDeclsForName(decl_ctx, name); @@ -555,7 +555,7 @@ uint32_t AppleObjCDeclVendor::FindDecls(ConstString name, bool append, if (!lookup_result.empty()) { if (clang::ObjCInterfaceDecl *result_iface_decl = - llvm::dyn_cast<clang::ObjCInterfaceDecl>(lookup_result[0])) { + llvm::dyn_cast<clang::ObjCInterfaceDecl>(*lookup_result.begin())) { if (log) { clang::QualType result_iface_type = ast_ctx.getObjCInterfaceType(result_iface_decl); diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp index 973a5570c06e..88e86c51fe44 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp @@ -48,7 +48,7 @@ LLDB_PLUGIN_DEFINE(AppleObjCRuntime) char AppleObjCRuntime::ID = 0; -AppleObjCRuntime::~AppleObjCRuntime() {} +AppleObjCRuntime::~AppleObjCRuntime() = default; AppleObjCRuntime::AppleObjCRuntime(Process *process) : ObjCLanguageRuntime(process), m_read_objc_library(false), diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp index b37e5a9a7bf9..98d0e9cf991b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp @@ -49,7 +49,7 @@ bool AppleObjCRuntimeV1::GetDynamicTypeAndAddress( TypeAndOrName &class_type_or_name, Address &address, Value::ValueType &value_type) { class_type_or_name.Clear(); - value_type = Value::ValueType::eValueTypeScalar; + value_type = Value::ValueType::Scalar; if (CouldHaveDynamicValue(in_value)) { auto class_descriptor(GetClassDescriptor(in_value)); if (class_descriptor && class_descriptor->IsValid() && @@ -339,8 +339,6 @@ void AppleObjCRuntimeV1::UpdateISAToDescriptorMapIfNeeded() { if (!objc_module_sp) return; - uint32_t isa_count = 0; - lldb::addr_t hash_table_ptr = GetISAHashTablePointer(); if (hash_table_ptr != LLDB_INVALID_ADDRESS) { // Read the NXHashTable struct: @@ -383,8 +381,6 @@ void AppleObjCRuntimeV1::UpdateISAToDescriptorMapIfNeeded() { if (bucket_isa_count == 0) continue; - isa_count += bucket_isa_count; - ObjCISA isa; if (bucket_isa_count == 1) { // When we only have one entry in the bucket, the bucket data diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h index 4eb7d979394b..12ee2cc53639 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h @@ -64,6 +64,12 @@ public: return false; } + bool GetTaggedPointerInfoSigned(uint64_t *info_bits = nullptr, + int64_t *value_bits = nullptr, + uint64_t *payload = nullptr) override { + return false; + } + uint64_t GetInstanceSize() override { return m_instance_size; } ObjCISA GetISA() override { return m_isa; } @@ -120,8 +126,7 @@ protected: class HashTableSignature { public: - HashTableSignature() - : m_count(0), m_num_buckets(0), m_buckets_ptr(LLDB_INVALID_ADDRESS) {} + HashTableSignature() = default; bool NeedsUpdate(uint32_t count, uint32_t num_buckets, lldb::addr_t buckets_ptr) { @@ -137,9 +142,9 @@ protected: } protected: - uint32_t m_count; - uint32_t m_num_buckets; - lldb::addr_t m_buckets_ptr; + uint32_t m_count = 0; + uint32_t m_num_buckets = 0; + lldb::addr_t m_buckets_ptr = LLDB_INVALID_ADDRESS; }; lldb::addr_t GetISAHashTablePointer(); diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp index ee84ccd869fc..10512a97ad69 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include <stdint.h> +#include <cstdint> #include <memory> #include <string> @@ -39,6 +39,7 @@ #include "lldb/Symbol/TypeList.h" #include "lldb/Symbol/VariableList.h" #include "lldb/Target/ABI.h" +#include "lldb/Target/DynamicLoader.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" @@ -75,8 +76,7 @@ char AppleObjCRuntimeV2::ID = 0; static const char *g_get_dynamic_class_info_name = "__lldb_apple_objc_v2_get_dynamic_class_info"; -// Testing using the new C++11 raw string literals. If this breaks GCC then we -// will need to revert to the code above... + static const char *g_get_dynamic_class_info_body = R"( extern "C" @@ -121,14 +121,20 @@ __lldb_apple_objc_v2_get_dynamic_class_info (void *gdb_objc_realized_classes_ptr if (grc) { const unsigned num_classes = grc->num_classes; + DEBUG_PRINTF ("num_classes = %u\n", grc->num_classes); if (class_infos_ptr) { + const unsigned num_buckets_minus_one = grc->num_buckets_minus_one; + DEBUG_PRINTF ("num_buckets_minus_one = %u\n", num_buckets_minus_one); + const size_t max_class_infos = class_infos_byte_size/sizeof(ClassInfo); + DEBUG_PRINTF ("max_class_infos = %u\n", max_class_infos); + ClassInfo *class_infos = (ClassInfo *)class_infos_ptr; BucketInfo *buckets = (BucketInfo *)grc->buckets; - + uint32_t idx = 0; - for (unsigned i=0; i<=grc->num_buckets_minus_one; ++i) + for (unsigned i=0; i<=num_buckets_minus_one; ++i) { if (buckets[i].name_ptr != NX_MAPNOTAKEY) { @@ -140,6 +146,7 @@ __lldb_apple_objc_v2_get_dynamic_class_info (void *gdb_objc_realized_classes_ptr h = ((h << 5) + h) + c; class_infos[idx].hash = h; class_infos[idx].isa = buckets[i].isa; + DEBUG_PRINTF ("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, buckets[i].name_ptr); } ++idx; } @@ -157,6 +164,75 @@ __lldb_apple_objc_v2_get_dynamic_class_info (void *gdb_objc_realized_classes_ptr )"; +static const char *g_get_dynamic_class_info2_name = + "__lldb_apple_objc_v2_get_dynamic_class_info2"; + +static const char *g_get_dynamic_class_info2_body = R"( + +extern "C" { + int printf(const char * format, ...); + void free(void *ptr); + Class* objc_copyRealizedClassList_nolock(unsigned int *outCount); + const char* objc_debug_class_getNameRaw(Class cls); +} + +#define DEBUG_PRINTF(fmt, ...) if (should_log) printf(fmt, ## __VA_ARGS__) + +struct ClassInfo +{ + Class isa; + uint32_t hash; +} __attribute__((__packed__)); + +uint32_t +__lldb_apple_objc_v2_get_dynamic_class_info2(void *gdb_objc_realized_classes_ptr, + void *class_infos_ptr, + uint32_t class_infos_byte_size, + uint32_t should_log) +{ + DEBUG_PRINTF ("class_infos_ptr = %p\n", class_infos_ptr); + DEBUG_PRINTF ("class_infos_byte_size = %u\n", class_infos_byte_size); + + const size_t max_class_infos = class_infos_byte_size/sizeof(ClassInfo); + DEBUG_PRINTF ("max_class_infos = %u\n", max_class_infos); + + ClassInfo *class_infos = (ClassInfo *)class_infos_ptr; + + uint32_t count = 0; + Class* realized_class_list = objc_copyRealizedClassList_nolock(&count); + DEBUG_PRINTF ("count = %u\n", count); + + uint32_t idx = 0; + for (uint32_t i=0; i<=count; ++i) + { + if (idx < max_class_infos) + { + Class isa = realized_class_list[i]; + const char *name_ptr = objc_debug_class_getNameRaw(isa); + if (name_ptr == NULL) + continue; + const char *s = name_ptr; + uint32_t h = 5381; + for (unsigned char c = *s; c; c = *++s) + h = ((h << 5) + h) + c; + class_infos[idx].hash = h; + class_infos[idx].isa = isa; + DEBUG_PRINTF ("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, name_ptr); + } + idx++; + } + + if (idx < max_class_infos) + { + class_infos[idx].isa = NULL; + class_infos[idx].hash = 0; + } + + free(realized_class_list); + return count; +} +)"; + // We'll substitute in class_getName or class_getNameRaw depending // on which is present. static const char *g_shared_cache_class_name_funcptr = R"( @@ -169,8 +245,7 @@ extern "C" static const char *g_get_shared_cache_class_info_name = "__lldb_apple_objc_v2_get_shared_cache_class_info"; -// Testing using the new C++11 raw string literals. If this breaks GCC then we -// will need to revert to the code above... + static const char *g_get_shared_cache_class_info_body = R"( extern "C" @@ -188,6 +263,12 @@ struct objc_classheader_t { int32_t hiOffset; }; +struct objc_classheader_v16_t { + uint64_t isDuplicate : 1, + objectCacheOffset : 47, // Offset from the shared cache base + dylibObjCIndex : 16; +}; + struct objc_clsopt_t { uint32_t capacity; uint32_t occupied; @@ -205,6 +286,22 @@ struct objc_clsopt_t { // objc_classheader_t duplicateOffsets[duplicateCount]; }; +struct objc_clsopt_v16_t { + uint32_t version; + uint32_t capacity; + uint32_t occupied; + uint32_t shift; + uint32_t mask; + uint64_t salt; + uint32_t scramble[256]; + uint8_t tab[0]; // tab[mask+1] + // uint8_t checkbytes[capacity]; + // int32_t offset[capacity]; + // objc_classheader_t clsOffsets[capacity]; + // uint32_t duplicateCount; + // objc_classheader_t duplicateOffsets[duplicateCount]; +}; + struct objc_opt_t { uint32_t version; int32_t selopt_offset; @@ -220,6 +317,20 @@ struct objc_opt_v14_t { int32_t clsopt_offset; }; +struct objc_opt_v16_t { + uint32_t version; + uint32_t flags; + int32_t selopt_offset; + int32_t headeropt_ro_offset; + int32_t unused_clsopt_offset; + int32_t unused_protocolopt_offset; + int32_t headeropt_rw_offset; + int32_t unused_protocolopt2_offset; + int32_t largeSharedCachesClassOffset; + int32_t largeSharedCachesProtocolOffset; + uint64_t relativeMethodSelectorBaseAddressCacheOffset; +}; + struct ClassInfo { Class isa; @@ -228,20 +339,33 @@ struct ClassInfo uint32_t __lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr, + void *shared_cache_base_ptr, void *class_infos_ptr, + uint64_t *relative_selector_offset, uint32_t class_infos_byte_size, uint32_t should_log) { + *relative_selector_offset = 0; uint32_t idx = 0; DEBUG_PRINTF ("objc_opt_ro_ptr = %p\n", objc_opt_ro_ptr); + DEBUG_PRINTF ("shared_cache_base_ptr = %p\n", shared_cache_base_ptr); DEBUG_PRINTF ("class_infos_ptr = %p\n", class_infos_ptr); DEBUG_PRINTF ("class_infos_byte_size = %u (%llu class infos)\n", class_infos_byte_size, (uint64_t)(class_infos_byte_size/sizeof(ClassInfo))); if (objc_opt_ro_ptr) { const objc_opt_t *objc_opt = (objc_opt_t *)objc_opt_ro_ptr; const objc_opt_v14_t* objc_opt_v14 = (objc_opt_v14_t*)objc_opt_ro_ptr; - const bool is_v14_format = objc_opt->version >= 14; - if (is_v14_format) + const objc_opt_v16_t* objc_opt_v16 = (objc_opt_v16_t*)objc_opt_ro_ptr; + if (objc_opt->version >= 16) + { + *relative_selector_offset = objc_opt_v16->relativeMethodSelectorBaseAddressCacheOffset; + DEBUG_PRINTF ("objc_opt->version = %u\n", objc_opt_v16->version); + DEBUG_PRINTF ("objc_opt->flags = %u\n", objc_opt_v16->flags); + DEBUG_PRINTF ("objc_opt->selopt_offset = %d\n", objc_opt_v16->selopt_offset); + DEBUG_PRINTF ("objc_opt->headeropt_ro_offset = %d\n", objc_opt_v16->headeropt_ro_offset); + DEBUG_PRINTF ("objc_opt->relativeMethodSelectorBaseAddressCacheOffset = %d\n", *relative_selector_offset); + } + else if (objc_opt->version >= 14) { DEBUG_PRINTF ("objc_opt->version = %u\n", objc_opt_v14->version); DEBUG_PRINTF ("objc_opt->flags = %u\n", objc_opt_v14->flags); @@ -256,10 +380,126 @@ __lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr, DEBUG_PRINTF ("objc_opt->headeropt_offset = %d\n", objc_opt->headeropt_offset); DEBUG_PRINTF ("objc_opt->clsopt_offset = %d\n", objc_opt->clsopt_offset); } - if (objc_opt->version == 12 || objc_opt->version == 13 || objc_opt->version == 14 || objc_opt->version == 15) + + if (objc_opt->version == 16) + { + const objc_clsopt_v16_t* clsopt = (const objc_clsopt_v16_t*)((uint8_t *)objc_opt + objc_opt_v16->largeSharedCachesClassOffset); + const size_t max_class_infos = class_infos_byte_size/sizeof(ClassInfo); + + DEBUG_PRINTF("max_class_infos = %llu\n", (uint64_t)max_class_infos); + + ClassInfo *class_infos = (ClassInfo *)class_infos_ptr; + + const uint8_t *checkbytes = &clsopt->tab[clsopt->mask+1]; + const int32_t *offsets = (const int32_t *)(checkbytes + clsopt->capacity); + const objc_classheader_v16_t *classOffsets = (const objc_classheader_v16_t *)(offsets + clsopt->capacity); + + DEBUG_PRINTF ("clsopt->capacity = %u\n", clsopt->capacity); + DEBUG_PRINTF ("clsopt->mask = 0x%8.8x\n", clsopt->mask); + DEBUG_PRINTF ("classOffsets = %p\n", classOffsets); + + for (uint32_t i=0; i<clsopt->capacity; ++i) + { + const uint64_t objectCacheOffset = classOffsets[i].objectCacheOffset; + DEBUG_PRINTF("objectCacheOffset[%u] = %u\n", i, objectCacheOffset); + + if (classOffsets[i].isDuplicate) { + DEBUG_PRINTF("isDuplicate = true\n"); + continue; // duplicate + } + + if (objectCacheOffset == 0) { + DEBUG_PRINTF("objectCacheOffset == invalidEntryOffset\n"); + continue; // invalid offset + } + + if (class_infos && idx < max_class_infos) + { + class_infos[idx].isa = (Class)((uint8_t *)shared_cache_base_ptr + objectCacheOffset); + + // Lookup the class name. + const char *name = class_name_lookup_func(class_infos[idx].isa); + DEBUG_PRINTF("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, name); + + // Hash the class name so we don't have to read it. + const char *s = name; + uint32_t h = 5381; + for (unsigned char c = *s; c; c = *++s) + { + // class_getName demangles swift names and the hash must + // be calculated on the mangled name. hash==0 means lldb + // will fetch the mangled name and compute the hash in + // ParseClassInfoArray. + if (c == '.') + { + h = 0; + break; + } + h = ((h << 5) + h) + c; + } + class_infos[idx].hash = h; + } + else + { + DEBUG_PRINTF("not(class_infos && idx < max_class_infos)\n"); + } + ++idx; + } + + const uint32_t *duplicate_count_ptr = (uint32_t *)&classOffsets[clsopt->capacity]; + const uint32_t duplicate_count = *duplicate_count_ptr; + const objc_classheader_v16_t *duplicateClassOffsets = (const objc_classheader_v16_t *)(&duplicate_count_ptr[1]); + + DEBUG_PRINTF ("duplicate_count = %u\n", duplicate_count); + DEBUG_PRINTF ("duplicateClassOffsets = %p\n", duplicateClassOffsets); + + for (uint32_t i=0; i<duplicate_count; ++i) + { + const uint64_t objectCacheOffset = classOffsets[i].objectCacheOffset; + DEBUG_PRINTF("objectCacheOffset[%u] = %u\n", i, objectCacheOffset); + + if (classOffsets[i].isDuplicate) { + DEBUG_PRINTF("isDuplicate = true\n"); + continue; // duplicate + } + + if (objectCacheOffset == 0) { + DEBUG_PRINTF("objectCacheOffset == invalidEntryOffset\n"); + continue; // invalid offset + } + + if (class_infos && idx < max_class_infos) + { + class_infos[idx].isa = (Class)((uint8_t *)shared_cache_base_ptr + objectCacheOffset); + + // Lookup the class name. + const char *name = class_name_lookup_func(class_infos[idx].isa); + DEBUG_PRINTF("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, name); + + // Hash the class name so we don't have to read it. + const char *s = name; + uint32_t h = 5381; + for (unsigned char c = *s; c; c = *++s) + { + // class_getName demangles swift names and the hash must + // be calculated on the mangled name. hash==0 means lldb + // will fetch the mangled name and compute the hash in + // ParseClassInfoArray. + if (c == '.') + { + h = 0; + break; + } + h = ((h << 5) + h) + c; + } + class_infos[idx].hash = h; + } + } + } + else if (objc_opt->version >= 12 && objc_opt->version <= 15) { const objc_clsopt_t* clsopt = NULL; - if (is_v14_format) + if (objc_opt->version >= 14) clsopt = (const objc_clsopt_t*)((uint8_t *)objc_opt_v14 + objc_opt_v14->clsopt_offset); else clsopt = (const objc_clsopt_t*)((uint8_t *)objc_opt + objc_opt->clsopt_offset); @@ -291,7 +531,7 @@ __lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr, DEBUG_PRINTF("clsOffset == invalidEntryOffset\n"); continue; // invalid offset } - + if (class_infos && idx < max_class_infos) { class_infos[idx].isa = (Class)((uint8_t *)clsopt + clsOffset); @@ -321,7 +561,7 @@ __lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr, } ++idx; } - + const uint32_t *duplicate_count_ptr = (uint32_t *)&classOffsets[clsopt->capacity]; const uint32_t duplicate_count = *duplicate_count_ptr; const objc_classheader_t *duplicateClassOffsets = (const objc_classheader_t *)(&duplicate_count_ptr[1]); @@ -334,7 +574,7 @@ __lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr, continue; // duplicate else if (clsOffset == invalidEntryOffset) continue; // invalid offset - + if (class_infos && idx < max_class_infos) { class_infos[idx].isa = (Class)((uint8_t *)clsopt + clsOffset); @@ -353,7 +593,7 @@ __lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr, { h = 0; break; - } + } h = ((h << 5) + h) + c; } class_infos[idx].hash = h; @@ -380,55 +620,57 @@ ExtractRuntimeGlobalSymbol(Process *process, ConstString name, error.SetErrorString("no process"); return default_value; } + if (!module_sp) { error.SetErrorString("no module"); return default_value; } + if (!byte_size) byte_size = process->GetAddressByteSize(); const Symbol *symbol = module_sp->FindFirstSymbolWithNameAndType(name, lldb::eSymbolTypeData); - if (symbol && symbol->ValueIsAddress()) { - lldb::addr_t symbol_load_addr = - symbol->GetAddressRef().GetLoadAddress(&process->GetTarget()); - if (symbol_load_addr != LLDB_INVALID_ADDRESS) { - if (read_value) - return process->ReadUnsignedIntegerFromMemory( - symbol_load_addr, byte_size, default_value, error); - else - return symbol_load_addr; - } else { - error.SetErrorString("symbol address invalid"); - return default_value; - } - } else { + + if (!symbol || !symbol->ValueIsAddress()) { error.SetErrorString("no symbol"); return default_value; } + + lldb::addr_t symbol_load_addr = + symbol->GetAddressRef().GetLoadAddress(&process->GetTarget()); + if (symbol_load_addr == LLDB_INVALID_ADDRESS) { + error.SetErrorString("symbol address invalid"); + return default_value; + } + + if (read_value) + return process->ReadUnsignedIntegerFromMemory(symbol_load_addr, byte_size, + default_value, error); + return symbol_load_addr; } static void RegisterObjCExceptionRecognizer(Process *process); AppleObjCRuntimeV2::AppleObjCRuntimeV2(Process *process, const ModuleSP &objc_module_sp) - : AppleObjCRuntime(process), m_get_class_info_code(), - m_get_class_info_args(LLDB_INVALID_ADDRESS), - m_get_class_info_args_mutex(), m_get_shared_cache_class_info_code(), - m_get_shared_cache_class_info_args(LLDB_INVALID_ADDRESS), - m_get_shared_cache_class_info_args_mutex(), m_decl_vendor_up(), + : AppleObjCRuntime(process), m_objc_module_sp(objc_module_sp), + m_dynamic_class_info_extractor(*this), + m_shared_cache_class_info_extractor(*this), m_decl_vendor_up(), m_tagged_pointer_obfuscator(LLDB_INVALID_ADDRESS), - m_isa_hash_table_ptr(LLDB_INVALID_ADDRESS), m_hash_signature(), - m_has_object_getClass(false), m_loaded_objc_opt(false), - m_non_pointer_isa_cache_up( - NonPointerISACache::CreateInstance(*this, objc_module_sp)), + m_isa_hash_table_ptr(LLDB_INVALID_ADDRESS), + m_relative_selector_base(LLDB_INVALID_ADDRESS), m_hash_signature(), + m_has_object_getClass(false), m_has_objc_copyRealizedClassList(false), + m_loaded_objc_opt(false), m_non_pointer_isa_cache_up(), m_tagged_pointer_vendor_up( TaggedPointerVendorV2::CreateInstance(*this, objc_module_sp)), m_encoding_to_type_sp(), m_noclasses_warning_emitted(false), - m_CFBoolean_values() { + m_CFBoolean_values(), m_realized_class_generation_count(0) { static const ConstString g_gdb_object_getClass("gdb_object_getClass"); - m_has_object_getClass = - (objc_module_sp->FindFirstSymbolWithNameAndType( - g_gdb_object_getClass, eSymbolTypeCode) != nullptr); + m_has_object_getClass = HasSymbol(g_gdb_object_getClass); + static const ConstString g_objc_copyRealizedClassList( + "_ZL33objc_copyRealizedClassList_nolockPj"); + m_has_objc_copyRealizedClassList = HasSymbol(g_objc_copyRealizedClassList); + RegisterObjCExceptionRecognizer(process); } @@ -451,7 +693,7 @@ bool AppleObjCRuntimeV2::GetDynamicTypeAndAddress( assert(in_value.GetTargetSP().get() == m_process->CalculateTarget().get()); class_type_or_name.Clear(); - value_type = Value::ValueType::eValueTypeScalar; + value_type = Value::ValueType::Scalar; // Make sure we can have a dynamic value before starting... if (CouldHaveDynamicValue(in_value)) { @@ -498,15 +740,21 @@ LanguageRuntime *AppleObjCRuntimeV2::CreateInstance(Process *process, if (AppleObjCRuntime::GetObjCVersion(process, objc_module_sp) == ObjCRuntimeVersions::eAppleObjC_V2) return new AppleObjCRuntimeV2(process, objc_module_sp); - else - return nullptr; - } else return nullptr; + } + return nullptr; } static constexpr OptionDefinition g_objc_classtable_dump_options[] = { - {LLDB_OPT_SET_ALL, false, "verbose", 'v', OptionParser::eNoArgument, - nullptr, {}, 0, eArgTypeNone, + {LLDB_OPT_SET_ALL, + false, + "verbose", + 'v', + OptionParser::eNoArgument, + nullptr, + {}, + 0, + eArgTypeNone, "Print ivar and method information in detail"}}; class CommandObjectObjC_ClassTable_Dump : public CommandObjectParsed { @@ -548,12 +796,13 @@ public: }; CommandObjectObjC_ClassTable_Dump(CommandInterpreter &interpreter) - : CommandObjectParsed( - interpreter, "dump", "Dump information on Objective-C classes " - "known to the current process.", - "language objc class-table dump", - eCommandRequiresProcess | eCommandProcessMustBeLaunched | - eCommandProcessMustBePaused), + : CommandObjectParsed(interpreter, "dump", + "Dump information on Objective-C classes " + "known to the current process.", + "language objc class-table dump", + eCommandRequiresProcess | + eCommandProcessMustBeLaunched | + eCommandProcessMustBePaused), m_options() { CommandArgumentEntry arg; CommandArgumentData index_arg; @@ -581,8 +830,8 @@ protected: case 0: break; case 1: { - regex_up = std::make_unique<RegularExpression>( - llvm::StringRef::withNullAsEmpty(command.GetArgumentAtIndex(0))); + regex_up = + std::make_unique<RegularExpression>(command.GetArgumentAtIndex(0)); if (!regex_up->IsValid()) { result.AppendError( "invalid argument - please provide a valid regular expression"); @@ -632,6 +881,7 @@ protected: ivar.m_type.GetDisplayTypeName().AsCString("<unknown>"), ivar.m_size, ivar.m_offset); } + iterator->second->Describe( nullptr, [&std_out](const char *name, const char *type) -> bool { @@ -655,11 +905,10 @@ protected: } result.SetStatus(lldb::eReturnStatusSuccessFinishResult); return true; - } else { - result.AppendError("current process has no Objective-C runtime loaded"); - result.SetStatus(lldb::eReturnStatusFailed); - return false; } + result.AppendError("current process has no Objective-C runtime loaded"); + result.SetStatus(lldb::eReturnStatusFailed); + return false; } CommandOptions m_options; @@ -741,11 +990,10 @@ protected: } result.SetStatus(lldb::eReturnStatusSuccessFinishResult); return true; - } else { - result.AppendError("current process has no Objective-C runtime loaded"); - result.SetStatus(lldb::eReturnStatusFailed); - return false; } + result.AppendError("current process has no Objective-C runtime loaded"); + result.SetStatus(lldb::eReturnStatusFailed); + return false; } }; @@ -951,11 +1199,7 @@ bool AppleObjCRuntimeV2::IsTaggedPointer(addr_t ptr) { class RemoteNXMapTable { public: - RemoteNXMapTable() - : m_count(0), m_num_buckets_minus_one(0), - m_buckets_ptr(LLDB_INVALID_ADDRESS), m_process(nullptr), - m_end_iterator(*this, -1), m_load_addr(LLDB_INVALID_ADDRESS), - m_map_pair_size(0), m_invalid_key(0) {} + RemoteNXMapTable() : m_end_iterator(*this, -1) {} void Dump() { printf("RemoteNXMapTable.m_load_addr = 0x%" PRIx64 "\n", m_load_addr); @@ -1129,18 +1373,17 @@ public: private: // contents of _NXMapTable struct - uint32_t m_count; - uint32_t m_num_buckets_minus_one; - lldb::addr_t m_buckets_ptr; - lldb_private::Process *m_process; + uint32_t m_count = 0; + uint32_t m_num_buckets_minus_one = 0; + lldb::addr_t m_buckets_ptr = LLDB_INVALID_ADDRESS; + lldb_private::Process *m_process = nullptr; const_iterator m_end_iterator; - lldb::addr_t m_load_addr; - size_t m_map_pair_size; - lldb::addr_t m_invalid_key; + lldb::addr_t m_load_addr = LLDB_INVALID_ADDRESS; + size_t m_map_pair_size = 0; + lldb::addr_t m_invalid_key = 0; }; -AppleObjCRuntimeV2::HashTableSignature::HashTableSignature() - : m_count(0), m_num_buckets(0), m_buckets_ptr(0) {} +AppleObjCRuntimeV2::HashTableSignature::HashTableSignature() = default; void AppleObjCRuntimeV2::HashTableSignature::UpdateSignature( const RemoteNXMapTable &hash_table) { @@ -1171,8 +1414,8 @@ bool AppleObjCRuntimeV2::HashTableSignature::NeedsUpdate( ObjCLanguageRuntime::ClassDescriptorSP AppleObjCRuntimeV2::GetClassDescriptorFromISA(ObjCISA isa) { ObjCLanguageRuntime::ClassDescriptorSP class_descriptor_sp; - if (m_non_pointer_isa_cache_up) - class_descriptor_sp = m_non_pointer_isa_cache_up->GetClassDescriptor(isa); + if (auto *non_pointer_isa_cache = GetNonPointerIsaCache()) + class_descriptor_sp = non_pointer_isa_cache->GetClassDescriptor(isa); if (!class_descriptor_sp) class_descriptor_sp = ObjCLanguageRuntime::GetClassDescriptorFromISA(isa); return class_descriptor_sp; @@ -1214,11 +1457,9 @@ AppleObjCRuntimeV2::GetClassDescriptor(ValueObject &valobj) { objc_class_sp = GetClassDescriptorFromISA(isa); if (isa && !objc_class_sp) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | - LIBLLDB_LOG_TYPES)); + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TYPES)); LLDB_LOGF(log, - "0x%" PRIx64 - ": AppleObjCRuntimeV2::GetClassDescriptor() ISA was " + "0x%" PRIx64 ": AppleObjCRuntimeV2::GetClassDescriptor() ISA was " "not in class descriptor cache 0x%" PRIx64, isa_pointer, isa); } @@ -1229,28 +1470,29 @@ lldb::addr_t AppleObjCRuntimeV2::GetTaggedPointerObfuscator() { if (m_tagged_pointer_obfuscator != LLDB_INVALID_ADDRESS) return m_tagged_pointer_obfuscator; - Process *process = GetProcess(); ModuleSP objc_module_sp(GetObjCModule()); if (!objc_module_sp) return LLDB_INVALID_ADDRESS; - static ConstString g_gdb_objc_obfuscator("objc_debug_taggedpointer_obfuscator"); + static ConstString g_gdb_objc_obfuscator( + "objc_debug_taggedpointer_obfuscator"); const Symbol *symbol = objc_module_sp->FindFirstSymbolWithNameAndType( - g_gdb_objc_obfuscator, lldb::eSymbolTypeAny); + g_gdb_objc_obfuscator, lldb::eSymbolTypeAny); if (symbol) { lldb::addr_t g_gdb_obj_obfuscator_ptr = - symbol->GetLoadAddress(&process->GetTarget()); + symbol->GetLoadAddress(&process->GetTarget()); if (g_gdb_obj_obfuscator_ptr != LLDB_INVALID_ADDRESS) { Status error; - m_tagged_pointer_obfuscator = process->ReadPointerFromMemory( - g_gdb_obj_obfuscator_ptr, error); + m_tagged_pointer_obfuscator = + process->ReadPointerFromMemory(g_gdb_obj_obfuscator_ptr, error); } } - // If we don't have a correct value at this point, there must be no obfuscation. + // If we don't have a correct value at this point, there must be no + // obfuscation. if (m_tagged_pointer_obfuscator == LLDB_INVALID_ADDRESS) m_tagged_pointer_obfuscator = 0; @@ -1284,11 +1526,212 @@ lldb::addr_t AppleObjCRuntimeV2::GetISAHashTablePointer() { return m_isa_hash_table_ptr; } +std::unique_ptr<UtilityFunction> +AppleObjCRuntimeV2::DynamicClassInfoExtractor::GetClassInfoUtilityFunctionImpl( + ExecutionContext &exe_ctx, std::string code, std::string name) { + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TYPES)); + + LLDB_LOG(log, "Creating utility function {0}", name); + + TypeSystemClang *ast = + ScratchTypeSystemClang::GetForTarget(exe_ctx.GetTargetRef()); + if (!ast) + return {}; + + auto utility_fn_or_error = exe_ctx.GetTargetRef().CreateUtilityFunction( + std::move(code), std::move(name), eLanguageTypeC, exe_ctx); + if (!utility_fn_or_error) { + LLDB_LOG_ERROR( + log, utility_fn_or_error.takeError(), + "Failed to get utility function for implementation lookup: {0}"); + return {}; + } + + // Make some types for our arguments. + CompilerType clang_uint32_t_type = + ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32); + CompilerType clang_void_pointer_type = + ast->GetBasicType(eBasicTypeVoid).GetPointerType(); + + // Make the runner function for our implementation utility function. + ValueList arguments; + Value value; + value.SetValueType(Value::ValueType::Scalar); + value.SetCompilerType(clang_void_pointer_type); + arguments.PushValue(value); + arguments.PushValue(value); + value.SetValueType(Value::ValueType::Scalar); + value.SetCompilerType(clang_uint32_t_type); + arguments.PushValue(value); + arguments.PushValue(value); + + std::unique_ptr<UtilityFunction> utility_fn = std::move(*utility_fn_or_error); + + Status error; + utility_fn->MakeFunctionCaller(clang_uint32_t_type, arguments, + exe_ctx.GetThreadSP(), error); + + if (error.Fail()) { + LLDB_LOG(log, + "Failed to make function caller for implementation lookup: {0}.", + error.AsCString()); + return {}; + } + + return utility_fn; +} + +UtilityFunction * +AppleObjCRuntimeV2::DynamicClassInfoExtractor::GetClassInfoUtilityFunction( + ExecutionContext &exe_ctx, Helper helper) { + switch (helper) { + case gdb_objc_realized_classes: { + if (!m_gdb_objc_realized_classes_helper.utility_function) + m_gdb_objc_realized_classes_helper.utility_function = + GetClassInfoUtilityFunctionImpl(exe_ctx, + g_get_dynamic_class_info_body, + g_get_dynamic_class_info_name); + return m_gdb_objc_realized_classes_helper.utility_function.get(); + } + case objc_copyRealizedClassList: { + if (!m_objc_copyRealizedClassList_helper.utility_function) + m_objc_copyRealizedClassList_helper.utility_function = + GetClassInfoUtilityFunctionImpl(exe_ctx, + g_get_dynamic_class_info2_body, + g_get_dynamic_class_info2_name); + return m_objc_copyRealizedClassList_helper.utility_function.get(); + } + } + llvm_unreachable("Unexpected helper"); +} + +lldb::addr_t & +AppleObjCRuntimeV2::DynamicClassInfoExtractor::GetClassInfoArgs(Helper helper) { + switch (helper) { + case gdb_objc_realized_classes: + return m_gdb_objc_realized_classes_helper.args; + case objc_copyRealizedClassList: + return m_objc_copyRealizedClassList_helper.args; + } + llvm_unreachable("Unexpected helper"); +} + +AppleObjCRuntimeV2::DynamicClassInfoExtractor::Helper +AppleObjCRuntimeV2::DynamicClassInfoExtractor::ComputeHelper() const { + if (!m_runtime.m_has_objc_copyRealizedClassList) + return DynamicClassInfoExtractor::gdb_objc_realized_classes; + + if (Process *process = m_runtime.GetProcess()) { + if (DynamicLoader *loader = process->GetDynamicLoader()) { + if (loader->IsFullyInitialized()) + return DynamicClassInfoExtractor::objc_copyRealizedClassList; + } + } + + return DynamicClassInfoExtractor::gdb_objc_realized_classes; +} + +std::unique_ptr<UtilityFunction> +AppleObjCRuntimeV2::SharedCacheClassInfoExtractor:: + GetClassInfoUtilityFunctionImpl(ExecutionContext &exe_ctx) { + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TYPES)); + + LLDB_LOG(log, "Creating utility function {0}", + g_get_shared_cache_class_info_name); + + TypeSystemClang *ast = + ScratchTypeSystemClang::GetForTarget(exe_ctx.GetTargetRef()); + if (!ast) + return {}; + + // If the inferior objc.dylib has the class_getNameRaw function, use that in + // our jitted expression. Else fall back to the old class_getName. + static ConstString g_class_getName_symbol_name("class_getName"); + static ConstString g_class_getNameRaw_symbol_name( + "objc_debug_class_getNameRaw"); + + ConstString class_name_getter_function_name = + m_runtime.HasSymbol(g_class_getNameRaw_symbol_name) + ? g_class_getNameRaw_symbol_name + : g_class_getName_symbol_name; + + // Substitute in the correct class_getName / class_getNameRaw function name, + // concatenate the two parts of our expression text. The format string has + // two %s's, so provide the name twice. + std::string shared_class_expression; + llvm::raw_string_ostream(shared_class_expression) + << llvm::format(g_shared_cache_class_name_funcptr, + class_name_getter_function_name.AsCString(), + class_name_getter_function_name.AsCString()); + + shared_class_expression += g_get_shared_cache_class_info_body; + + auto utility_fn_or_error = exe_ctx.GetTargetRef().CreateUtilityFunction( + std::move(shared_class_expression), g_get_shared_cache_class_info_name, + eLanguageTypeC, exe_ctx); + + if (!utility_fn_or_error) { + LLDB_LOG_ERROR( + log, utility_fn_or_error.takeError(), + "Failed to get utility function for implementation lookup: {0}"); + return nullptr; + } + + // Make some types for our arguments. + CompilerType clang_uint32_t_type = + ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32); + CompilerType clang_void_pointer_type = + ast->GetBasicType(eBasicTypeVoid).GetPointerType(); + CompilerType clang_uint64_t_pointer_type = + ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 64) + .GetPointerType(); + + // Next make the function caller for our implementation utility function. + ValueList arguments; + Value value; + value.SetValueType(Value::ValueType::Scalar); + value.SetCompilerType(clang_void_pointer_type); + arguments.PushValue(value); + arguments.PushValue(value); + arguments.PushValue(value); + + value.SetValueType(Value::ValueType::Scalar); + value.SetCompilerType(clang_uint64_t_pointer_type); + arguments.PushValue(value); + + value.SetValueType(Value::ValueType::Scalar); + value.SetCompilerType(clang_uint32_t_type); + arguments.PushValue(value); + arguments.PushValue(value); + + std::unique_ptr<UtilityFunction> utility_fn = std::move(*utility_fn_or_error); + + Status error; + utility_fn->MakeFunctionCaller(clang_uint32_t_type, arguments, + exe_ctx.GetThreadSP(), error); + + if (error.Fail()) { + LLDB_LOG(log, + "Failed to make function caller for implementation lookup: {0}.", + error.AsCString()); + return {}; + } + + return utility_fn; +} + +UtilityFunction * +AppleObjCRuntimeV2::SharedCacheClassInfoExtractor::GetClassInfoUtilityFunction( + ExecutionContext &exe_ctx) { + if (!m_utility_function) + m_utility_function = GetClassInfoUtilityFunctionImpl(exe_ctx); + return m_utility_function.get(); +} + AppleObjCRuntimeV2::DescriptorMapUpdateResult -AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic( +AppleObjCRuntimeV2::DynamicClassInfoExtractor::UpdateISAToDescriptorMap( RemoteNXMapTable &hash_table) { - Process *process = GetProcess(); - + Process *process = m_runtime.GetProcess(); if (process == nullptr) return DescriptorMapUpdateResult::Fail(); @@ -1316,65 +1759,36 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic( Status err; + // Compute which helper we're going to use for this update. + const DynamicClassInfoExtractor::Helper helper = ComputeHelper(); + // Read the total number of classes from the hash table - const uint32_t num_classes = hash_table.GetCount(); + const uint32_t num_classes = + helper == DynamicClassInfoExtractor::gdb_objc_realized_classes + ? hash_table.GetCount() + : m_runtime.m_realized_class_generation_count; if (num_classes == 0) { - LLDB_LOGF(log, "No dynamic classes found in gdb_objc_realized_classes."); + LLDB_LOGF(log, "No dynamic classes found."); return DescriptorMapUpdateResult::Success(0); } - // Make some types for our arguments - CompilerType clang_uint32_t_type = - ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32); - CompilerType clang_void_pointer_type = - ast->GetBasicType(eBasicTypeVoid).GetPointerType(); - - ValueList arguments; - FunctionCaller *get_class_info_function = nullptr; - - if (!m_get_class_info_code) { - auto utility_fn_or_error = GetTargetRef().CreateUtilityFunction( - g_get_dynamic_class_info_body, g_get_dynamic_class_info_name, - eLanguageTypeC, exe_ctx); - if (!utility_fn_or_error) { - LLDB_LOG_ERROR( - log, utility_fn_or_error.takeError(), - "Failed to get utility function for implementation lookup: {0}"); - return DescriptorMapUpdateResult::Fail(); - } - m_get_class_info_code = std::move(*utility_fn_or_error); - - // Next make the runner function for our implementation utility function. - Value value; - value.SetValueType(Value::eValueTypeScalar); - value.SetCompilerType(clang_void_pointer_type); - arguments.PushValue(value); - arguments.PushValue(value); - - value.SetValueType(Value::eValueTypeScalar); - value.SetCompilerType(clang_uint32_t_type); - arguments.PushValue(value); - arguments.PushValue(value); + UtilityFunction *get_class_info_code = + GetClassInfoUtilityFunction(exe_ctx, helper); + if (!get_class_info_code) { + // The callee will have already logged a useful error message. + return DescriptorMapUpdateResult::Fail(); + } - Status error; - get_class_info_function = m_get_class_info_code->MakeFunctionCaller( - clang_uint32_t_type, arguments, thread_sp, error); + FunctionCaller *get_class_info_function = + get_class_info_code->GetFunctionCaller(); - if (error.Fail()) { - LLDB_LOGF(log, - "Failed to make function caller for implementation lookup: %s.", - error.AsCString()); - return DescriptorMapUpdateResult::Fail(); - } - } else { - get_class_info_function = m_get_class_info_code->GetFunctionCaller(); - if (!get_class_info_function) { - LLDB_LOGF(log, "Failed to get implementation lookup function caller."); - return DescriptorMapUpdateResult::Fail(); - } - arguments = get_class_info_function->GetArgumentValues(); + if (!get_class_info_function) { + LLDB_LOGF(log, "Failed to get implementation lookup function caller."); + return DescriptorMapUpdateResult::Fail(); } + ValueList arguments = get_class_info_function->GetArgumentValues(); + DiagnosticManager diagnostics; const uint32_t class_info_byte_size = addr_size + 4; @@ -1390,18 +1804,18 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic( return DescriptorMapUpdateResult::Fail(); } - std::lock_guard<std::mutex> guard(m_get_class_info_args_mutex); + std::lock_guard<std::mutex> guard(m_mutex); // Fill in our function argument values arguments.GetValueAtIndex(0)->GetScalar() = hash_table.GetTableLoadAddress(); arguments.GetValueAtIndex(1)->GetScalar() = class_infos_addr; arguments.GetValueAtIndex(2)->GetScalar() = class_infos_byte_size; - + // Only dump the runtime classes from the expression evaluation if the log is // verbose: Log *type_log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES); bool dump_log = type_log && type_log->GetVerbose(); - + arguments.GetValueAtIndex(3)->GetScalar() = dump_log ? 1 : 0; bool success = false; @@ -1410,7 +1824,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic( // Write our function arguments into the process so we can run our function if (get_class_info_function->WriteFunctionArguments( - exe_ctx, m_get_class_info_args, arguments, diagnostics)) { + exe_ctx, GetClassInfoArgs(helper), arguments, diagnostics)) { EvaluateExpressionOptions options; options.SetUnwindOnError(true); options.SetTryAllThreads(false); @@ -1419,8 +1833,11 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic( options.SetTimeout(process->GetUtilityExpressionTimeout()); options.SetIsForUtilityExpr(true); + CompilerType clang_uint32_t_type = + ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32); + Value return_value; - return_value.SetValueType(Value::eValueTypeScalar); + return_value.SetValueType(Value::ValueType::Scalar); return_value.SetCompilerType(clang_uint32_t_type); return_value.GetScalar() = 0; @@ -1428,12 +1845,12 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic( // Run the function ExpressionResults results = get_class_info_function->ExecuteFunction( - exe_ctx, &m_get_class_info_args, options, diagnostics, return_value); + exe_ctx, &GetClassInfoArgs(helper), options, diagnostics, return_value); if (results == eExpressionCompleted) { // The result is the number of ClassInfo structures that were filled in num_class_infos = return_value.GetScalar().ULong(); - LLDB_LOGF(log, "Discovered %u ObjC classes\n", num_class_infos); + LLDB_LOG(log, "Discovered {0} Objective-C classes", num_class_infos); if (num_class_infos > 0) { // Read the ClassInfo structures DataBufferHeap buffer(num_class_infos * class_info_byte_size, 0); @@ -1443,7 +1860,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic( DataExtractor class_infos_data(buffer.GetBytes(), buffer.GetByteSize(), process->GetByteOrder(), addr_size); - ParseClassInfoArray(class_infos_data, num_class_infos); + m_runtime.ParseClassInfoArray(class_infos_data, num_class_infos); } } success = true; @@ -1507,15 +1924,16 @@ uint32_t AppleObjCRuntimeV2::ParseClassInfoArray(const DataExtractor &data, ClassDescriptorSP descriptor_sp( new ClassDescriptorV2(*this, isa, nullptr)); - // The code in g_get_shared_cache_class_info_body sets the value of the hash - // to 0 to signal a demangled symbol. We use class_getName() in that code to - // find the class name, but this returns a demangled name for Swift symbols. - // For those symbols, recompute the hash here by reading their name from the - // runtime. + // The code in g_get_shared_cache_class_info_body sets the value of the + // hash to 0 to signal a demangled symbol. We use class_getName() in that + // code to find the class name, but this returns a demangled name for + // Swift symbols. For those symbols, recompute the hash here by reading + // their name from the runtime. if (name_hash) AddClass(isa, descriptor_sp, name_hash); else - AddClass(isa, descriptor_sp, descriptor_sp->GetClassName().AsCString(nullptr)); + AddClass(isa, descriptor_sp, + descriptor_sp->GetClassName().AsCString(nullptr)); num_parsed++; if (should_log) LLDB_LOGF(log, @@ -1531,10 +1949,20 @@ uint32_t AppleObjCRuntimeV2::ParseClassInfoArray(const DataExtractor &data, return num_parsed; } -AppleObjCRuntimeV2::DescriptorMapUpdateResult -AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() { - Process *process = GetProcess(); +bool AppleObjCRuntimeV2::HasSymbol(ConstString Name) { + if (!m_objc_module_sp) + return false; + if (const Symbol *symbol = m_objc_module_sp->FindFirstSymbolWithNameAndType( + Name, lldb::eSymbolTypeCode)) { + if (symbol->ValueIsAddress() || symbol->GetAddressRef().IsValid()) + return true; + } + return false; +} +AppleObjCRuntimeV2::DescriptorMapUpdateResult +AppleObjCRuntimeV2::SharedCacheClassInfoExtractor::UpdateISAToDescriptorMap() { + Process *process = m_runtime.GetProcess(); if (process == nullptr) return DescriptorMapUpdateResult::Fail(); @@ -1562,103 +1990,38 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() { uint32_t num_class_infos = 0; - const lldb::addr_t objc_opt_ptr = GetSharedCacheReadOnlyAddress(); + const lldb::addr_t objc_opt_ptr = m_runtime.GetSharedCacheReadOnlyAddress(); + const lldb::addr_t shared_cache_base_addr = + m_runtime.GetSharedCacheBaseAddress(); - if (objc_opt_ptr == LLDB_INVALID_ADDRESS) + if (objc_opt_ptr == LLDB_INVALID_ADDRESS || + shared_cache_base_addr == LLDB_INVALID_ADDRESS) return DescriptorMapUpdateResult::Fail(); const uint32_t num_classes = 128 * 1024; - // Make some types for our arguments - CompilerType clang_uint32_t_type = - ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32); - CompilerType clang_void_pointer_type = - ast->GetBasicType(eBasicTypeVoid).GetPointerType(); - - ValueList arguments; - FunctionCaller *get_shared_cache_class_info_function = nullptr; - - if (!m_get_shared_cache_class_info_code) { - Status error; - - // If the inferior objc.dylib has the class_getNameRaw function, - // use that in our jitted expression. Else fall back to the old - // class_getName. - static ConstString g_class_getName_symbol_name("class_getName"); - static ConstString g_class_getNameRaw_symbol_name("objc_debug_class_getNameRaw"); - ConstString class_name_getter_function_name = g_class_getName_symbol_name; - - ObjCLanguageRuntime *objc_runtime = ObjCLanguageRuntime::Get(*process); - if (objc_runtime) { - for (lldb::ModuleSP mod_sp : process->GetTarget().GetImages().Modules()) { - if (objc_runtime->IsModuleObjCLibrary(mod_sp)) { - const Symbol *symbol = - mod_sp->FindFirstSymbolWithNameAndType(g_class_getNameRaw_symbol_name, - lldb::eSymbolTypeCode); - if (symbol && - (symbol->ValueIsAddress() || symbol->GetAddressRef().IsValid())) { - class_name_getter_function_name = g_class_getNameRaw_symbol_name; - } - } - } - } - - // Substitute in the correct class_getName / class_getNameRaw function name, - // concatenate the two parts of our expression text. The format string - // has two %s's, so provide the name twice. - std::string shared_class_expression; - llvm::raw_string_ostream(shared_class_expression) << llvm::format( - g_shared_cache_class_name_funcptr, - class_name_getter_function_name.AsCString(), - class_name_getter_function_name.AsCString()); - - shared_class_expression += g_get_shared_cache_class_info_body; - - auto utility_fn_or_error = exe_ctx.GetTargetRef().CreateUtilityFunction( - std::move(shared_class_expression), g_get_shared_cache_class_info_name, - eLanguageTypeC, exe_ctx); - if (!utility_fn_or_error) { - LLDB_LOG_ERROR( - log, utility_fn_or_error.takeError(), - "Failed to get utility function for implementation lookup: {0}"); - return DescriptorMapUpdateResult::Fail(); - } - - m_get_shared_cache_class_info_code = std::move(*utility_fn_or_error); + UtilityFunction *get_class_info_code = GetClassInfoUtilityFunction(exe_ctx); + FunctionCaller *get_shared_cache_class_info_function = + get_class_info_code->GetFunctionCaller(); - // Next make the function caller for our implementation utility function. - Value value; - value.SetValueType(Value::eValueTypeScalar); - value.SetCompilerType(clang_void_pointer_type); - arguments.PushValue(value); - arguments.PushValue(value); - - value.SetValueType(Value::eValueTypeScalar); - value.SetCompilerType(clang_uint32_t_type); - arguments.PushValue(value); - arguments.PushValue(value); - - get_shared_cache_class_info_function = - m_get_shared_cache_class_info_code->MakeFunctionCaller( - clang_uint32_t_type, arguments, thread_sp, error); - - if (get_shared_cache_class_info_function == nullptr) - return DescriptorMapUpdateResult::Fail(); - - } else { - get_shared_cache_class_info_function = - m_get_shared_cache_class_info_code->GetFunctionCaller(); - if (get_shared_cache_class_info_function == nullptr) - return DescriptorMapUpdateResult::Fail(); - arguments = get_shared_cache_class_info_function->GetArgumentValues(); + if (!get_shared_cache_class_info_function) { + LLDB_LOGF(log, "Failed to get implementation lookup function caller."); + return DescriptorMapUpdateResult::Fail(); } + ValueList arguments = + get_shared_cache_class_info_function->GetArgumentValues(); + DiagnosticManager diagnostics; const uint32_t class_info_byte_size = addr_size + 4; const uint32_t class_infos_byte_size = num_classes * class_info_byte_size; lldb::addr_t class_infos_addr = process->AllocateMemory( class_infos_byte_size, ePermissionsReadable | ePermissionsWritable, err); + const uint32_t relative_selector_offset_addr_size = 64; + lldb::addr_t relative_selector_offset_addr = + process->AllocateMemory(relative_selector_offset_addr_size, + ePermissionsReadable | ePermissionsWritable, err); if (class_infos_addr == LLDB_INVALID_ADDRESS) { LLDB_LOGF(log, @@ -1668,18 +2031,20 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() { return DescriptorMapUpdateResult::Fail(); } - std::lock_guard<std::mutex> guard(m_get_shared_cache_class_info_args_mutex); + std::lock_guard<std::mutex> guard(m_mutex); // Fill in our function argument values arguments.GetValueAtIndex(0)->GetScalar() = objc_opt_ptr; - arguments.GetValueAtIndex(1)->GetScalar() = class_infos_addr; - arguments.GetValueAtIndex(2)->GetScalar() = class_infos_byte_size; + arguments.GetValueAtIndex(1)->GetScalar() = shared_cache_base_addr; + arguments.GetValueAtIndex(2)->GetScalar() = class_infos_addr; + arguments.GetValueAtIndex(3)->GetScalar() = relative_selector_offset_addr; + arguments.GetValueAtIndex(4)->GetScalar() = class_infos_byte_size; // Only dump the runtime classes from the expression evaluation if the log is // verbose: Log *type_log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES); bool dump_log = type_log && type_log->GetVerbose(); - - arguments.GetValueAtIndex(3)->GetScalar() = dump_log ? 1 : 0; + + arguments.GetValueAtIndex(5)->GetScalar() = dump_log ? 1 : 0; bool success = false; @@ -1687,8 +2052,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() { // Write our function arguments into the process so we can run our function if (get_shared_cache_class_info_function->WriteFunctionArguments( - exe_ctx, m_get_shared_cache_class_info_args, arguments, - diagnostics)) { + exe_ctx, m_args, arguments, diagnostics)) { EvaluateExpressionOptions options; options.SetUnwindOnError(true); options.SetTryAllThreads(false); @@ -1697,8 +2061,11 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() { options.SetTimeout(process->GetUtilityExpressionTimeout()); options.SetIsForUtilityExpr(true); + CompilerType clang_uint32_t_type = + ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32); + Value return_value; - return_value.SetValueType(Value::eValueTypeScalar); + return_value.SetValueType(Value::ValueType::Scalar); return_value.SetCompilerType(clang_uint32_t_type); return_value.GetScalar() = 0; @@ -1707,14 +2074,13 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() { // Run the function ExpressionResults results = get_shared_cache_class_info_function->ExecuteFunction( - exe_ctx, &m_get_shared_cache_class_info_args, options, diagnostics, - return_value); + exe_ctx, &m_args, options, diagnostics, return_value); if (results == eExpressionCompleted) { // The result is the number of ClassInfo structures that were filled in num_class_infos = return_value.GetScalar().ULong(); - LLDB_LOGF(log, "Discovered %u ObjC classes in shared cache\n", - num_class_infos); + LLDB_LOG(log, "Discovered {0} Objective-C classes in the shared cache", + num_class_infos); assert(num_class_infos <= num_classes); if (num_class_infos > 0) { if (num_class_infos > num_classes) { @@ -1725,16 +2091,38 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() { success = true; } + // Read the relative selector offset. + DataBufferHeap relative_selector_offset_buffer(64, 0); + if (process->ReadMemory(relative_selector_offset_addr, + relative_selector_offset_buffer.GetBytes(), + relative_selector_offset_buffer.GetByteSize(), + err) == + relative_selector_offset_buffer.GetByteSize()) { + DataExtractor relative_selector_offset_data( + relative_selector_offset_buffer.GetBytes(), + relative_selector_offset_buffer.GetByteSize(), + process->GetByteOrder(), addr_size); + lldb::offset_t offset = 0; + uint64_t relative_selector_offset = + relative_selector_offset_data.GetU64(&offset); + if (relative_selector_offset > 0) { + // The offset is relative to the objc_opt struct. + m_runtime.SetRelativeSelectorBaseAddr(objc_opt_ptr + + relative_selector_offset); + } + } + // Read the ClassInfo structures - DataBufferHeap buffer(num_class_infos * class_info_byte_size, 0); - if (process->ReadMemory(class_infos_addr, buffer.GetBytes(), - buffer.GetByteSize(), - err) == buffer.GetByteSize()) { - DataExtractor class_infos_data(buffer.GetBytes(), - buffer.GetByteSize(), + DataBufferHeap class_infos_buffer( + num_class_infos * class_info_byte_size, 0); + if (process->ReadMemory(class_infos_addr, class_infos_buffer.GetBytes(), + class_infos_buffer.GetByteSize(), + err) == class_infos_buffer.GetByteSize()) { + DataExtractor class_infos_data(class_infos_buffer.GetBytes(), + class_infos_buffer.GetByteSize(), process->GetByteOrder(), addr_size); - ParseClassInfoArray(class_infos_data, num_class_infos); + m_runtime.ParseClassInfoArray(class_infos_data, num_class_infos); } } else { success = true; @@ -1758,42 +2146,6 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() { return DescriptorMapUpdateResult(success, num_class_infos); } -bool AppleObjCRuntimeV2::UpdateISAToDescriptorMapFromMemory( - RemoteNXMapTable &hash_table) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TYPES)); - - Process *process = GetProcess(); - - if (process == nullptr) - return false; - - uint32_t num_map_table_isas = 0; - - ModuleSP objc_module_sp(GetObjCModule()); - - if (objc_module_sp) { - for (RemoteNXMapTable::element elt : hash_table) { - ++num_map_table_isas; - - if (ISAIsCached(elt.second)) - continue; - - ClassDescriptorSP descriptor_sp = ClassDescriptorSP( - new ClassDescriptorV2(*this, elt.second, elt.first.AsCString())); - - if (log && log->GetVerbose()) - LLDB_LOGF(log, - "AppleObjCRuntimeV2 added (ObjCISA)0x%" PRIx64 - " (%s) from dynamic table to isa->descriptor cache", - elt.second, elt.first.AsCString()); - - AddClass(elt.second, descriptor_sp, elt.first.AsCString()); - } - } - - return num_map_table_isas > 0; -} - lldb::addr_t AppleObjCRuntimeV2::GetSharedCacheReadOnlyAddress() { Process *process = GetProcess(); @@ -1827,6 +2179,19 @@ lldb::addr_t AppleObjCRuntimeV2::GetSharedCacheReadOnlyAddress() { return LLDB_INVALID_ADDRESS; } +lldb::addr_t AppleObjCRuntimeV2::GetSharedCacheBaseAddress() { + StructuredData::ObjectSP info = m_process->GetSharedCacheInfo(); + if (!info) + return LLDB_INVALID_ADDRESS; + + StructuredData::Dictionary *info_dict = info->GetAsDictionary(); + if (!info_dict) + return LLDB_INVALID_ADDRESS; + + return info_dict->GetValueForKey("shared_cache_base_address") + ->GetIntegerValue(LLDB_INVALID_ADDRESS); +} + void AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded() { LLDB_SCOPED_TIMER(); @@ -1842,14 +2207,19 @@ void AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded() { // map, whether it was successful or not. m_isa_to_descriptor_stop_id = process->GetStopID(); - if (!m_hash_signature.NeedsUpdate(process, this, hash_table)) + // Ask the runtime is the realized class generation count changed. Unlike + // the hash table, this accounts for lazily named classes. + const bool class_count_changed = RealizedClassGenerationCountChanged(); + + if (!m_hash_signature.NeedsUpdate(process, this, hash_table) && + !class_count_changed) return; m_hash_signature.UpdateSignature(hash_table); - // Grab the dynamically loaded objc classes from the hash table in memory + // Grab the dynamically loaded Objective-C classes from memory. DescriptorMapUpdateResult dynamic_update_result = - UpdateISAToDescriptorMapDynamic(hash_table); + m_dynamic_class_info_extractor.UpdateISAToDescriptorMap(hash_table); // Now get the objc classes that are baked into the Objective-C runtime in // the shared cache, but only once per process as this data never changes @@ -1865,7 +2235,7 @@ void AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded() { const uint32_t num_classes_to_warn_at = 500; DescriptorMapUpdateResult shared_cache_update_result = - UpdateISAToDescriptorMapSharedCache(); + m_shared_cache_class_info_extractor.UpdateISAToDescriptorMap(); LLDB_LOGF(log, "attempted to read objc class data - results: " @@ -1895,6 +2265,35 @@ void AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded() { } } +bool AppleObjCRuntimeV2::RealizedClassGenerationCountChanged() { + Process *process = GetProcess(); + if (!process) + return false; + + Status error; + uint64_t objc_debug_realized_class_generation_count = + ExtractRuntimeGlobalSymbol( + process, ConstString("objc_debug_realized_class_generation_count"), + GetObjCModule(), error); + if (error.Fail()) + return false; + + if (m_realized_class_generation_count == + objc_debug_realized_class_generation_count) + return false; + + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TYPES)); + LLDB_LOG(log, + "objc_debug_realized_class_generation_count changed from {0} to {1}", + m_realized_class_generation_count, + objc_debug_realized_class_generation_count); + + m_realized_class_generation_count = + objc_debug_realized_class_generation_count; + + return true; +} + static bool DoesProcessHaveSharedCache(Process &process) { PlatformSP platform_sp = process.GetTarget().GetPlatform(); if (!platform_sp) @@ -1975,9 +2374,10 @@ lldb::addr_t AppleObjCRuntimeV2::LookupRuntimeSymbol(ConstString name) { const ConstString ivar_name_cs(class_and_ivar.second); const char *ivar_name_cstr = ivar_name_cs.AsCString(); - auto ivar_func = [&ret, ivar_name_cstr]( - const char *name, const char *type, lldb::addr_t offset_addr, - uint64_t size) -> lldb::addr_t { + auto ivar_func = [&ret, + ivar_name_cstr](const char *name, const char *type, + lldb::addr_t offset_addr, + uint64_t size) -> lldb::addr_t { if (!strcmp(name, ivar_name_cstr)) { ret = offset_addr; return true; @@ -2279,7 +2679,6 @@ ObjCLanguageRuntime::ClassDescriptorSP AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::GetClassDescriptor( lldb::addr_t ptr) { ClassDescriptorSP actual_class_descriptor_sp; - uint64_t data_payload; uint64_t unobfuscated = (ptr) ^ m_runtime.GetTaggedPointerObfuscator(); if (!IsPossibleTaggedPointer(unobfuscated)) @@ -2307,12 +2706,15 @@ AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::GetClassDescriptor( m_cache[slot] = actual_class_descriptor_sp; } - data_payload = + uint64_t data_payload = (((uint64_t)unobfuscated << m_objc_debug_taggedpointer_payload_lshift) >> m_objc_debug_taggedpointer_payload_rshift); - - return ClassDescriptorSP( - new ClassDescriptorV2Tagged(actual_class_descriptor_sp, data_payload)); + int64_t data_payload_signed = + ((int64_t)((int64_t)unobfuscated + << m_objc_debug_taggedpointer_payload_lshift) >> + m_objc_debug_taggedpointer_payload_rshift); + return ClassDescriptorSP(new ClassDescriptorV2Tagged( + actual_class_descriptor_sp, data_payload, data_payload_signed)); } AppleObjCRuntimeV2::TaggedPointerVendorExtended::TaggedPointerVendorExtended( @@ -2364,7 +2766,6 @@ ObjCLanguageRuntime::ClassDescriptorSP AppleObjCRuntimeV2::TaggedPointerVendorExtended::GetClassDescriptor( lldb::addr_t ptr) { ClassDescriptorSP actual_class_descriptor_sp; - uint64_t data_payload; uint64_t unobfuscated = (ptr) ^ m_runtime.GetTaggedPointerObfuscator(); if (!IsPossibleTaggedPointer(unobfuscated)) @@ -2395,12 +2796,16 @@ AppleObjCRuntimeV2::TaggedPointerVendorExtended::GetClassDescriptor( m_ext_cache[slot] = actual_class_descriptor_sp; } - data_payload = - (((uint64_t)unobfuscated << m_objc_debug_taggedpointer_ext_payload_lshift) >> + uint64_t data_payload = (((uint64_t)unobfuscated + << m_objc_debug_taggedpointer_ext_payload_lshift) >> + m_objc_debug_taggedpointer_ext_payload_rshift); + int64_t data_payload_signed = + ((int64_t)((int64_t)unobfuscated + << m_objc_debug_taggedpointer_ext_payload_lshift) >> m_objc_debug_taggedpointer_ext_payload_rshift); - return ClassDescriptorSP( - new ClassDescriptorV2Tagged(actual_class_descriptor_sp, data_payload)); + return ClassDescriptorSP(new ClassDescriptorV2Tagged( + actual_class_descriptor_sp, data_payload, data_payload_signed)); } AppleObjCRuntimeV2::NonPointerISACache::NonPointerISACache( @@ -2552,8 +2957,8 @@ lldb_private::AppleObjCRuntime::ObjCISA AppleObjCRuntimeV2::GetPointerISA(ObjCISA isa) { ObjCISA ret = isa; - if (m_non_pointer_isa_cache_up) - m_non_pointer_isa_cache_up->EvaluateNonPointerISA(isa, ret); + if (auto *non_pointer_isa_cache = GetNonPointerIsaCache()) + non_pointer_isa_cache->EvaluateNonPointerISA(isa, ret); return ret; } @@ -2598,13 +3003,14 @@ void AppleObjCRuntimeV2::GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true, #pragma mark Frame recognizers class ObjCExceptionRecognizedStackFrame : public RecognizedStackFrame { - public: +public: ObjCExceptionRecognizedStackFrame(StackFrameSP frame_sp) { ThreadSP thread_sp = frame_sp->GetThread(); ProcessSP process_sp = thread_sp->GetProcess(); const lldb::ABISP &abi = process_sp->GetABI(); - if (!abi) return; + if (!abi) + return; TypeSystemClang *clang_ast_context = ScratchTypeSystemClang::GetForTarget(process_sp->GetTarget()); @@ -2618,7 +3024,8 @@ class ObjCExceptionRecognizedStackFrame : public RecognizedStackFrame { input_value.SetCompilerType(voidstar); args.PushValue(input_value); - if (!abi->GetArgumentValues(*thread_sp, args)) return; + if (!abi->GetArgumentValues(*thread_sp, args)) + return; addr_t exception_addr = args.GetValueAtIndex(0)->GetScalar().ULongLong(); diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h index c6fb6ea26b98..d0caa2969115 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h @@ -26,7 +26,6 @@ class AppleObjCRuntimeV2 : public AppleObjCRuntime { public: ~AppleObjCRuntimeV2() override = default; - // Static Functions static void Initialize(); static void Terminate(); @@ -46,7 +45,6 @@ public: return runtime->isA(&ID); } - // These are generic runtime functions: bool GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic, TypeAndOrName &class_type_or_name, @@ -56,7 +54,6 @@ public: llvm::Expected<std::unique_ptr<UtilityFunction>> CreateObjectChecker(std::string name, ExecutionContext &exe_ctx) override; - // PluginInterface protocol ConstString GetPluginName() override; uint32_t GetPluginVersion() override; @@ -88,6 +85,15 @@ public: lldb::addr_t GetTaggedPointerObfuscator(); + /// Returns the base address for relative method list selector strings. + lldb::addr_t GetRelativeSelectorBaseAddr() { + return m_relative_selector_base; + } + + void SetRelativeSelectorBaseAddr(lldb::addr_t relative_selector_base) { + m_relative_selector_base = relative_selector_base; + } + void GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true, lldb::addr_t &cf_false) override; @@ -105,8 +111,8 @@ public: protected: lldb::BreakpointResolverSP - CreateExceptionResolver(const lldb::BreakpointSP &bkpt, - bool catch_bp, bool throw_bp) override; + CreateExceptionResolver(const lldb::BreakpointSP &bkpt, bool catch_bp, + bool throw_bp) override; private: class HashTableSignature { @@ -119,9 +125,9 @@ private: void UpdateSignature(const RemoteNXMapTable &hash_table); protected: - uint32_t m_count; - uint32_t m_num_buckets; - lldb::addr_t m_buckets_ptr; + uint32_t m_count = 0; + uint32_t m_num_buckets = 0; + lldb::addr_t m_buckets_ptr = 0; }; class NonPointerISACache { @@ -296,22 +302,99 @@ private: } }; + /// Abstraction to read the Objective-C class info. + class ClassInfoExtractor { + public: + ClassInfoExtractor(AppleObjCRuntimeV2 &runtime) : m_runtime(runtime) {} + std::mutex &GetMutex() { return m_mutex; } + + protected: + /// The lifetime of this object is tied to that of the runtime. + AppleObjCRuntimeV2 &m_runtime; + std::mutex m_mutex; + }; + + /// We can read the class info from the Objective-C runtime using + /// gdb_objc_realized_classes or objc_copyRealizedClassList. The latter is + /// preferred because it includes lazily named classes, but it's not always + /// available or safe to call. + /// + /// We potentially need both for the same process, because we may need to use + /// gdb_objc_realized_classes until dyld is initialized and then switch over + /// to objc_copyRealizedClassList for lazily named classes. + class DynamicClassInfoExtractor : public ClassInfoExtractor { + public: + DynamicClassInfoExtractor(AppleObjCRuntimeV2 &runtime) + : ClassInfoExtractor(runtime) {} + + DescriptorMapUpdateResult + UpdateISAToDescriptorMap(RemoteNXMapTable &hash_table); + + private: + enum Helper { gdb_objc_realized_classes, objc_copyRealizedClassList }; + + /// Compute which helper to use. Prefer objc_copyRealizedClassList if it's + /// available and it's safe to call (i.e. dyld is fully initialized). Use + /// gdb_objc_realized_classes otherwise. + Helper ComputeHelper() const; + + UtilityFunction *GetClassInfoUtilityFunction(ExecutionContext &exe_ctx, + Helper helper); + lldb::addr_t &GetClassInfoArgs(Helper helper); + + std::unique_ptr<UtilityFunction> + GetClassInfoUtilityFunctionImpl(ExecutionContext &exe_ctx, std::string code, + std::string name); + + /// Helper to read class info using the gdb_objc_realized_classes. + struct gdb_objc_realized_classes_helper { + std::unique_ptr<UtilityFunction> utility_function; + lldb::addr_t args = LLDB_INVALID_ADDRESS; + }; + + /// Helper to read class info using objc_copyRealizedClassList. + struct objc_copyRealizedClassList_helper { + std::unique_ptr<UtilityFunction> utility_function; + lldb::addr_t args = LLDB_INVALID_ADDRESS; + }; + + gdb_objc_realized_classes_helper m_gdb_objc_realized_classes_helper; + objc_copyRealizedClassList_helper m_objc_copyRealizedClassList_helper; + }; + + /// Abstraction to read the Objective-C class info from the shared cache. + class SharedCacheClassInfoExtractor : public ClassInfoExtractor { + public: + SharedCacheClassInfoExtractor(AppleObjCRuntimeV2 &runtime) + : ClassInfoExtractor(runtime) {} + + DescriptorMapUpdateResult UpdateISAToDescriptorMap(); + + private: + UtilityFunction *GetClassInfoUtilityFunction(ExecutionContext &exe_ctx); + + std::unique_ptr<UtilityFunction> + GetClassInfoUtilityFunctionImpl(ExecutionContext &exe_ctx); + + std::unique_ptr<UtilityFunction> m_utility_function; + lldb::addr_t m_args = LLDB_INVALID_ADDRESS; + }; + AppleObjCRuntimeV2(Process *process, const lldb::ModuleSP &objc_module_sp); ObjCISA GetPointerISA(ObjCISA isa); lldb::addr_t GetISAHashTablePointer(); - bool UpdateISAToDescriptorMapFromMemory(RemoteNXMapTable &hash_table); - - DescriptorMapUpdateResult - UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table); + /// Update the generation count of realized classes. This is not an exact + /// count but rather a value that is incremented when new classes are realized + /// or destroyed. Unlike the count in gdb_objc_realized_classes, it will + /// change when lazily named classes get realized. + bool RealizedClassGenerationCountChanged(); uint32_t ParseClassInfoArray(const lldb_private::DataExtractor &data, uint32_t num_class_infos); - DescriptorMapUpdateResult UpdateISAToDescriptorMapSharedCache(); - enum class SharedCacheWarningReason { eExpressionExecutionFailure, eNotEnoughClassesRead @@ -320,30 +403,40 @@ private: void WarnIfNoClassesCached(SharedCacheWarningReason reason); lldb::addr_t GetSharedCacheReadOnlyAddress(); + lldb::addr_t GetSharedCacheBaseAddress(); bool GetCFBooleanValuesIfNeeded(); + bool HasSymbol(ConstString Name); + + NonPointerISACache *GetNonPointerIsaCache() { + if (!m_non_pointer_isa_cache_up) + m_non_pointer_isa_cache_up.reset( + NonPointerISACache::CreateInstance(*this, m_objc_module_sp)); + return m_non_pointer_isa_cache_up.get(); + } + friend class ClassDescriptorV2; - std::unique_ptr<UtilityFunction> m_get_class_info_code; - lldb::addr_t m_get_class_info_args; - std::mutex m_get_class_info_args_mutex; + lldb::ModuleSP m_objc_module_sp; - std::unique_ptr<UtilityFunction> m_get_shared_cache_class_info_code; - lldb::addr_t m_get_shared_cache_class_info_args; - std::mutex m_get_shared_cache_class_info_args_mutex; + DynamicClassInfoExtractor m_dynamic_class_info_extractor; + SharedCacheClassInfoExtractor m_shared_cache_class_info_extractor; std::unique_ptr<DeclVendor> m_decl_vendor_up; lldb::addr_t m_tagged_pointer_obfuscator; lldb::addr_t m_isa_hash_table_ptr; + lldb::addr_t m_relative_selector_base; HashTableSignature m_hash_signature; bool m_has_object_getClass; + bool m_has_objc_copyRealizedClassList; bool m_loaded_objc_opt; std::unique_ptr<NonPointerISACache> m_non_pointer_isa_cache_up; std::unique_ptr<TaggedPointerVendor> m_tagged_pointer_vendor_up; EncodingToTypeSP m_encoding_to_type_sp; bool m_noclasses_warning_emitted; llvm::Optional<std::pair<lldb::addr_t, lldb::addr_t>> m_CFBoolean_values; + uint64_t m_realized_class_generation_count; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp index bcc1f6fd339f..aa6306bef8b9 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp @@ -285,7 +285,7 @@ AppleObjCTrampolineHandler::AppleObjCVTables::VTableRegion::VTableRegion( SetUpRegion(); } -AppleObjCTrampolineHandler::~AppleObjCTrampolineHandler() {} +AppleObjCTrampolineHandler::~AppleObjCTrampolineHandler() = default; void AppleObjCTrampolineHandler::AppleObjCVTables::VTableRegion::SetUpRegion() { // The header looks like: @@ -526,7 +526,7 @@ bool AppleObjCTrampolineHandler::AppleObjCVTables::RefreshTrampolines( CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); - input_value.SetValueType(Value::eValueTypeScalar); + input_value.SetValueType(Value::ValueType::Scalar); // input_value.SetContext (Value::eContextTypeClangType, // clang_void_ptr_type); input_value.SetCompilerType(clang_void_ptr_type); @@ -936,7 +936,7 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, Value void_ptr_value; CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); - void_ptr_value.SetValueType(Value::eValueTypeScalar); + void_ptr_value.SetValueType(Value::ValueType::Scalar); // void_ptr_value.SetContext (Value::eContextTypeClangType, // clang_void_ptr_type); void_ptr_value.SetCompilerType(clang_void_ptr_type); @@ -1048,7 +1048,7 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, Value isa_value(*(argument_values.GetValueAtIndex(obj_index))); - isa_value.SetValueType(Value::eValueTypeLoadAddress); + isa_value.SetValueType(Value::ValueType::LoadAddress); isa_value.ResolveValue(&exe_ctx); if (isa_value.GetScalar().IsValid()) { isa_addr = isa_value.GetScalar().ULongLong(); @@ -1110,7 +1110,7 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, CompilerType clang_int_type = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize( lldb::eEncodingSint, 32); - flag_value.SetValueType(Value::eValueTypeScalar); + flag_value.SetValueType(Value::ValueType::Scalar); // flag_value.SetContext (Value::eContextTypeClangType, clang_int_type); flag_value.SetCompilerType(clang_int_type); @@ -1157,13 +1157,8 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, flag_value.GetScalar() = 0; // FIXME - Set to 0 when debugging is done. dispatch_values.PushValue(flag_value); - // The step through code might have to fill in the cache, so it - // is not safe to run only one thread. So we override the - // stop_others value passed in to us here: - const bool trampoline_stop_others = false; ret_plan_sp = std::make_shared<AppleThreadPlanStepThroughObjCTrampoline>( - thread, *this, dispatch_values, isa_addr, sel_addr, - trampoline_stop_others); + thread, *this, dispatch_values, isa_addr, sel_addr); if (log) { StreamString s; ret_plan_sp->GetDescription(&s, eDescriptionLevelFull); @@ -1182,13 +1177,9 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, MsgsendMap::iterator pos; pos = m_opt_dispatch_map.find(curr_pc); if (pos != m_opt_dispatch_map.end()) { - const char *opt_name = g_opt_dispatch_names[(*pos).second]; - - bool trampoline_stop_others = false; - LazyBool step_in_should_stop = eLazyBoolCalculate; - ret_plan_sp = std::make_shared<AppleThreadPlanStepThroughDirectDispatch> ( - thread, *this, opt_name, trampoline_stop_others, step_in_should_stop); + ret_plan_sp = std::make_shared<AppleThreadPlanStepThroughDirectDispatch>( + thread, *this, opt_name); } } diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h index 27aebd8594df..546b500b4529 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h @@ -76,10 +76,7 @@ private: class VTableRegion { public: - VTableRegion() - : m_valid(false), m_owner(nullptr), - m_header_addr(LLDB_INVALID_ADDRESS), m_code_start_addr(0), - m_code_end_addr(0), m_next_region(0) {} + VTableRegion() = default; VTableRegion(AppleObjCVTables *owner, lldb::addr_t header_addr); @@ -99,13 +96,13 @@ private: void Dump(Stream &s); - bool m_valid; - AppleObjCVTables *m_owner; - lldb::addr_t m_header_addr; - lldb::addr_t m_code_start_addr; - lldb::addr_t m_code_end_addr; + bool m_valid = false; + AppleObjCVTables *m_owner = nullptr; + lldb::addr_t m_header_addr = LLDB_INVALID_ADDRESS; + lldb::addr_t m_code_start_addr = 0; + lldb::addr_t m_code_end_addr = 0; std::vector<VTableDescriptor> m_descriptors; - lldb::addr_t m_next_region; + lldb::addr_t m_next_region = 0; }; public: diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp index b19d3d90d4b7..7b0121503bc4 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp @@ -59,7 +59,7 @@ uint32_t AppleObjCTypeEncodingParser::ReadNumber(StringLexer &type) { // "{CGRect=\"origin\"{CGPoint=\"x\"d\"y\"d}\"size\"{CGSize=\"width\"d\"height\"d}}" AppleObjCTypeEncodingParser::StructElement::StructElement() - : name(""), type(clang::QualType()), bitfield(0) {} + : name(""), type(clang::QualType()) {} AppleObjCTypeEncodingParser::StructElement AppleObjCTypeEncodingParser::ReadStructElement(TypeSystemClang &ast_ctx, diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h index 9a108967e1ab..6e533b591eca 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h @@ -29,7 +29,7 @@ private: struct StructElement { std::string name; clang::QualType type; - uint32_t bitfield; + uint32_t bitfield = 0; StructElement(); ~StructElement() = default; diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp index 653e007c7b5f..1dc8034c537a 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp @@ -30,19 +30,17 @@ using namespace lldb_private; AppleThreadPlanStepThroughObjCTrampoline:: AppleThreadPlanStepThroughObjCTrampoline( Thread &thread, AppleObjCTrampolineHandler &trampoline_handler, - ValueList &input_values, lldb::addr_t isa_addr, lldb::addr_t sel_addr, - bool stop_others) + ValueList &input_values, lldb::addr_t isa_addr, lldb::addr_t sel_addr) : ThreadPlan(ThreadPlan::eKindGeneric, "MacOSX Step through ObjC Trampoline", thread, eVoteNoOpinion, eVoteNoOpinion), m_trampoline_handler(trampoline_handler), m_args_addr(LLDB_INVALID_ADDRESS), m_input_values(input_values), - m_isa_addr(isa_addr), m_sel_addr(sel_addr), m_impl_function(nullptr), - m_stop_others(stop_others) {} + m_isa_addr(isa_addr), m_sel_addr(sel_addr), m_impl_function(nullptr) {} // Destructor AppleThreadPlanStepThroughObjCTrampoline:: - ~AppleThreadPlanStepThroughObjCTrampoline() {} + ~AppleThreadPlanStepThroughObjCTrampoline() = default; void AppleThreadPlanStepThroughObjCTrampoline::DidPush() { // Setting up the memory space for the called function text might require @@ -66,7 +64,7 @@ bool AppleThreadPlanStepThroughObjCTrampoline::InitializeFunctionCaller() { EvaluateExpressionOptions options; options.SetUnwindOnError(true); options.SetIgnoreBreakpoints(true); - options.SetStopOthers(m_stop_others); + options.SetStopOthers(false); GetThread().CalculateExecutionContext(exc_ctx); m_func_sp = m_impl_function->GetThreadPlanToCallFunction( exc_ctx, m_args_addr, options, diagnostics); @@ -157,7 +155,7 @@ bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) { const bool first_insn = true; const uint32_t frame_idx = 0; m_run_to_sp = GetThread().QueueThreadPlanForStepOutNoShouldStop( - abort_other_plans, &sc, first_insn, m_stop_others, eVoteNoOpinion, + abort_other_plans, &sc, first_insn, false, eVoteNoOpinion, eVoteNoOpinion, frame_idx, status); if (m_run_to_sp && status.Success()) m_run_to_sp->SetPrivate(true); @@ -179,7 +177,7 @@ bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) { // Extract the target address from the value: m_run_to_sp = std::make_shared<ThreadPlanRunToAddress>( - GetThread(), target_so_addr, m_stop_others); + GetThread(), target_so_addr, false); PushPlan(m_run_to_sp); return false; } else if (GetThread().IsThreadPlanDone(m_run_to_sp.get())) { @@ -222,10 +220,9 @@ bool AppleThreadPlanStepThroughObjCTrampoline::WillStop() { return true; } AppleThreadPlanStepThroughDirectDispatch :: AppleThreadPlanStepThroughDirectDispatch( Thread &thread, AppleObjCTrampolineHandler &handler, - llvm::StringRef dispatch_func_name, bool stop_others, - LazyBool step_in_avoids_code_without_debug_info) - : ThreadPlanStepOut(thread, nullptr, true /* first instruction */, - stop_others, eVoteNoOpinion, eVoteNoOpinion, + llvm::StringRef dispatch_func_name) + : ThreadPlanStepOut(thread, nullptr, true /* first instruction */, false, + eVoteNoOpinion, eVoteNoOpinion, 0 /* Step out of zeroth frame */, eLazyBoolNo /* Our parent plan will decide this when we are done */ @@ -234,7 +231,7 @@ AppleThreadPlanStepThroughDirectDispatch :: false /* Don't gather the return value */), m_trampoline_handler(handler), m_dispatch_func_name(std::string(dispatch_func_name)), - m_at_msg_send(false), m_stop_others(stop_others) { + m_at_msg_send(false) { // Set breakpoints on the dispatch functions: auto bkpt_callback = [&] (lldb::addr_t addr, const AppleObjCTrampolineHandler @@ -249,20 +246,7 @@ AppleThreadPlanStepThroughDirectDispatch :: // We'll set the step-out plan in the DidPush so it gets queued in the right // order. - bool avoid_nodebug = true; - - switch (step_in_avoids_code_without_debug_info) { - case eLazyBoolYes: - avoid_nodebug = true; - break; - case eLazyBoolNo: - avoid_nodebug = false; - break; - case eLazyBoolCalculate: - avoid_nodebug = GetThread().GetStepInAvoidsNoDebug(); - break; - } - if (avoid_nodebug) + if (GetThread().GetStepInAvoidsNoDebug()) GetFlags().Set(ThreadPlanShouldStopHere::eStepInAvoidNoDebug); else GetFlags().Clear(ThreadPlanShouldStopHere::eStepInAvoidNoDebug); @@ -398,8 +382,8 @@ bool AppleThreadPlanStepThroughDirectDispatch::ShouldStop(Event *event_ptr) { // There's no way we could have gotten here without an ObjC language // runtime. assert(objc_runtime); - m_objc_step_through_sp - = objc_runtime->GetStepThroughTrampolinePlan(GetThread(), m_stop_others); + m_objc_step_through_sp = + objc_runtime->GetStepThroughTrampolinePlan(GetThread(), false); // If we failed to find the target for this dispatch, just keep going and // let the step out complete. if (!m_objc_step_through_sp) { diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h index 89aed89f1ab1..b5b45079094c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h @@ -24,8 +24,7 @@ class AppleThreadPlanStepThroughObjCTrampoline : public ThreadPlan { public: AppleThreadPlanStepThroughObjCTrampoline( Thread &thread, AppleObjCTrampolineHandler &trampoline_handler, - ValueList &values, lldb::addr_t isa_addr, lldb::addr_t sel_addr, - bool stop_others); + ValueList &values, lldb::addr_t isa_addr, lldb::addr_t sel_addr); ~AppleThreadPlanStepThroughObjCTrampoline() override; @@ -39,7 +38,9 @@ public: bool ShouldStop(Event *event_ptr) override; - bool StopOthers() override { return m_stop_others; } + // The step through code might have to fill in the cache, so it is not safe + // to run only one thread. + bool StopOthers() override { return false; } // The base class MischiefManaged does some cleanup - so you have to call it // in your MischiefManaged derived class. @@ -69,15 +70,13 @@ private: FunctionCaller *m_impl_function; /// This is a pointer to a impl function that /// is owned by the client that pushes this /// plan. - bool m_stop_others; /// Whether we should stop other threads. }; class AppleThreadPlanStepThroughDirectDispatch: public ThreadPlanStepOut { public: - AppleThreadPlanStepThroughDirectDispatch( - Thread &thread, AppleObjCTrampolineHandler &handler, - llvm::StringRef dispatch_func_name, bool stop_others, - LazyBool step_in_avoids_code_without_debug_info); + AppleThreadPlanStepThroughDirectDispatch(Thread &thread, + AppleObjCTrampolineHandler &handler, + llvm::StringRef dispatch_func_name); ~AppleThreadPlanStepThroughDirectDispatch() override; @@ -85,7 +84,7 @@ public: bool ShouldStop(Event *event_ptr) override; - bool StopOthers() override { return m_stop_others; } + bool StopOthers() override { return false; } bool MischiefManaged() override; @@ -107,7 +106,6 @@ protected: std::vector<lldb::BreakpointSP> m_msgSend_bkpts; /// Breakpoints on the objc /// dispatch functions. bool m_at_msg_send; /// Are we currently handling an msg_send - bool m_stop_others; /// Whether we should stop other threads. }; diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp index 2ccf9b33f9d8..65bf3e6af626 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp @@ -32,7 +32,7 @@ using namespace lldb_private; char ObjCLanguageRuntime::ID = 0; // Destructor -ObjCLanguageRuntime::~ObjCLanguageRuntime() {} +ObjCLanguageRuntime::~ObjCLanguageRuntime() = default; ObjCLanguageRuntime::ObjCLanguageRuntime(Process *process) : LanguageRuntime(process), m_impl_cache(), @@ -305,7 +305,7 @@ ObjCLanguageRuntime::EncodingToType::RealizeType(const char *name, return CompilerType(); } -ObjCLanguageRuntime::EncodingToType::~EncodingToType() {} +ObjCLanguageRuntime::EncodingToType::~EncodingToType() = default; ObjCLanguageRuntime::EncodingToTypeSP ObjCLanguageRuntime::GetEncodingToType() { return nullptr; @@ -363,7 +363,8 @@ void ObjCLanguageRuntime::ObjCExceptionPrecondition::AddClassName( m_class_names.insert(class_name); } -ObjCLanguageRuntime::ObjCExceptionPrecondition::ObjCExceptionPrecondition() {} +ObjCLanguageRuntime::ObjCExceptionPrecondition::ObjCExceptionPrecondition() = + default; bool ObjCLanguageRuntime::ObjCExceptionPrecondition::EvaluatePrecondition( StoppointCallbackContext &context) { diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h index 683eff777728..15fce04ea465 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h @@ -49,9 +49,7 @@ public: // implementations of the runtime, and more might come class ClassDescriptor { public: - ClassDescriptor() - : m_is_kvo(eLazyBoolCalculate), m_is_cf(eLazyBoolCalculate), - m_type_wp() {} + ClassDescriptor() : m_type_wp() {} virtual ~ClassDescriptor() = default; @@ -87,10 +85,20 @@ public: virtual bool IsValid() = 0; + /// There are two routines in the ObjC runtime that tagged pointer clients + /// can call to get the value from their tagged pointer, one that retrieves + /// it as an unsigned value and one a signed value. These two + /// GetTaggedPointerInfo methods mirror those two ObjC runtime calls. + /// @{ virtual bool GetTaggedPointerInfo(uint64_t *info_bits = nullptr, uint64_t *value_bits = nullptr, uint64_t *payload = nullptr) = 0; + virtual bool GetTaggedPointerInfoSigned(uint64_t *info_bits = nullptr, + int64_t *value_bits = nullptr, + uint64_t *payload = nullptr) = 0; + /// @} + virtual uint64_t GetInstanceSize() = 0; // use to implement version-specific additional constraints on pointers @@ -135,8 +143,8 @@ public: bool check_version_specific = false) const; private: - LazyBool m_is_kvo; - LazyBool m_is_cf; + LazyBool m_is_kvo = eLazyBoolCalculate; + LazyBool m_is_cf = eLazyBoolCalculate; lldb::TypeWP m_type_wp; }; diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp index 6858c7134d33..08a752eaa888 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp @@ -185,7 +185,7 @@ RSIRPasses::RSIRPasses(Process *process) { EarlyPasses->add(new RenderScriptRuntimeModulePass(process)); } -RSIRPasses::~RSIRPasses() {} +RSIRPasses::~RSIRPasses() = default; } // namespace lldb_renderscript } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp index dd9312234d8b..10ff5aa72b52 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp @@ -61,7 +61,7 @@ namespace { template <typename type_t> class empirical_type { public: // Ctor. Contents is invalid when constructed. - empirical_type() : valid(false) {} + empirical_type() = default; // Return true and copy contents to out if valid, else return false. bool get(type_t &out) const { @@ -99,7 +99,7 @@ public: } protected: - bool valid; + bool valid = false; type_t data; }; @@ -2228,7 +2228,7 @@ bool RenderScriptRuntime::RefreshAllocation(AllocationDetails *alloc, return JITAllocationSize(alloc, frame_ptr); } -// Function attempts to set the type_name member of the paramaterised Element +// Function attempts to set the type_name member of the parameterised Element // object. This string should be the name of the struct type the Element // represents. We need this string for pretty printing the Element to users. void RenderScriptRuntime::FindStructTypeName(Element &elem, @@ -4087,9 +4087,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() - : Options(), - m_kernel_types(RSReduceBreakpointResolver::eKernelTypeAll) {} + CommandOptions() : Options() {} ~CommandOptions() override = default; @@ -4175,7 +4173,7 @@ public: return true; } - int m_kernel_types; + int m_kernel_types = RSReduceBreakpointResolver::eKernelTypeAll; llvm::StringRef m_reduce_name; RSCoordinate m_coord; bool m_have_coord; @@ -4189,7 +4187,6 @@ public: result.AppendErrorWithFormat("'%s' takes 1 argument of reduction name, " "and an optional kernel type list", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -4203,7 +4200,6 @@ public: auto coord = m_options.m_have_coord ? &m_options.m_coord : nullptr; if (!runtime->PlaceBreakpointOnReduction(target, outstream, name, coord, m_options.m_kernel_types)) { - result.SetStatus(eReturnStatusFailed); result.AppendError("Error: unable to place breakpoint on reduction"); return false; } @@ -4291,7 +4287,6 @@ public: result.AppendErrorWithFormat( "'%s' takes 1 argument of kernel name, and an optional coordinate.", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -4304,7 +4299,6 @@ public: auto name = command.GetArgumentAtIndex(0); auto coord = m_options.m_have_coord ? &m_options.m_coord : nullptr; if (!runtime->PlaceBreakpointOnKernel(target, outstream, name, coord)) { - result.SetStatus(eReturnStatusFailed); result.AppendErrorWithFormat( "Error: unable to set breakpoint on kernel '%s'", name); return false; @@ -4342,7 +4336,6 @@ public: if (argc != 1) { result.AppendErrorWithFormat( "'%s' takes 1 argument of 'enable' or 'disable'", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -4361,7 +4354,6 @@ public: } else { result.AppendErrorWithFormat( "Argument must be either 'enable' or 'disable'"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -4568,7 +4560,6 @@ public: result.AppendErrorWithFormat("'%s' takes 1 argument, an allocation ID. " "As well as an optional -f argument", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -4583,7 +4574,6 @@ public: if (!success) { result.AppendErrorWithFormat("invalid allocation id argument '%s'", id_cstr); - result.SetStatus(eReturnStatusFailed); return false; } @@ -4608,7 +4598,6 @@ public: std::string error = llvm::toString(file.takeError()); result.AppendErrorWithFormat("Couldn't open file '%s': %s", path.c_str(), error.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } } else @@ -4653,7 +4642,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() : Options(), m_id(0) {} + CommandOptions() : Options() {} ~CommandOptions() override = default; @@ -4681,7 +4670,7 @@ public: return llvm::makeArrayRef(g_renderscript_runtime_alloc_list_options); } - uint32_t m_id; + uint32_t m_id = 0; }; bool DoExecute(Args &command, CommandReturnObject &result) override { @@ -4717,7 +4706,6 @@ public: result.AppendErrorWithFormat( "'%s' takes 2 arguments, an allocation ID and filename to read from.", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -4732,7 +4720,6 @@ public: if (!success) { result.AppendErrorWithFormat("invalid allocation id argument '%s'", id_cstr); - result.SetStatus(eReturnStatusFailed); return false; } @@ -4768,7 +4755,6 @@ public: result.AppendErrorWithFormat( "'%s' takes 2 arguments, an allocation ID and filename to read from.", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -4783,7 +4769,6 @@ public: if (!success) { result.AppendErrorWithFormat("invalid allocation id argument '%s'", id_cstr); - result.SetStatus(eReturnStatusFailed); return false; } diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h index 5e3726548369..2785c3b08125 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h @@ -44,9 +44,9 @@ typedef std::shared_ptr<RSKernelDescriptor> RSKernelDescriptorSP; typedef std::shared_ptr<RSScriptGroupDescriptor> RSScriptGroupDescriptorSP; struct RSCoordinate { - uint32_t x, y, z; + uint32_t x = 0, y = 0, z = 0; - RSCoordinate() : x(), y(), z(){}; + RSCoordinate() = default; bool operator==(const lldb_renderscript::RSCoordinate &rhs) { return x == rhs.x && y == rhs.y && z == rhs.z; diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp index 211eb9ce0d3a..7ff917518b64 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp @@ -42,9 +42,7 @@ using namespace lldb_private; LLDB_PLUGIN_DEFINE(ObjectContainerBSDArchive) -ObjectContainerBSDArchive::Object::Object() - : ar_name(), modification_time(0), uid(0), gid(0), mode(0), size(0), - file_offset(0), file_size(0) {} +ObjectContainerBSDArchive::Object::Object() : ar_name() {} void ObjectContainerBSDArchive::Object::Clear() { ar_name.Clear(); @@ -142,7 +140,7 @@ ObjectContainerBSDArchive::Archive::Archive(const lldb_private::ArchSpec &arch, : m_arch(arch), m_modification_time(time), m_file_offset(file_offset), m_objects(), m_data(data) {} -ObjectContainerBSDArchive::Archive::~Archive() {} +ObjectContainerBSDArchive::Archive::~Archive() = default; size_t ObjectContainerBSDArchive::Archive::ParseObjects() { DataExtractor &data = m_data; @@ -375,7 +373,7 @@ void ObjectContainerBSDArchive::SetArchive(Archive::shared_ptr &archive_sp) { m_archive_sp = archive_sp; } -ObjectContainerBSDArchive::~ObjectContainerBSDArchive() {} +ObjectContainerBSDArchive::~ObjectContainerBSDArchive() = default; bool ObjectContainerBSDArchive::ParseHeader() { if (m_archive_sp.get() == nullptr) { diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h b/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h index f6862afff8a0..9830e9b5d1b2 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h @@ -84,25 +84,25 @@ protected: lldb_private::ConstString ar_name; /// Object modification time in the archive. - uint32_t modification_time; + uint32_t modification_time = 0; /// Object user id in the archive. - uint16_t uid; + uint16_t uid = 0; /// Object group id in the archive. - uint16_t gid; + uint16_t gid = 0; /// Object octal file permissions in the archive. - uint16_t mode; + uint16_t mode = 0; /// Object size in bytes in the archive. - uint32_t size; + uint32_t size = 0; /// File offset in bytes from the beginning of the file of the object data. - lldb::offset_t file_offset; + lldb::offset_t file_offset = 0; /// Length of the object data. - lldb::offset_t file_size; + lldb::offset_t file_size = 0; }; class Archive { diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index cad9ce218b10..a5e86f0c2c1b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -16,6 +16,7 @@ #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" +#include "lldb/Core/Progress.h" #include "lldb/Core/Section.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/LZMA.h" @@ -37,6 +38,7 @@ #include "llvm/Object/Decompressor.h" #include "llvm/Support/ARMBuildAttributes.h" #include "llvm/Support/CRC.h" +#include "llvm/Support/FormatVariadic.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/MipsABIFlags.h" @@ -857,8 +859,7 @@ Address ObjectFileELF::GetImageInfoAddress(Target *target) { if (symbol.d_tag == DT_MIPS_RLD_MAP) { // DT_MIPS_RLD_MAP tag stores an absolute address of the debug pointer. Address addr; - if (target->ReadPointerFromMemory(dyn_base + offset, false, error, - addr)) + if (target->ReadPointerFromMemory(dyn_base + offset, error, addr, true)) return addr; } if (symbol.d_tag == DT_MIPS_RLD_MAP_REL) { @@ -866,7 +867,7 @@ Address ObjectFileELF::GetImageInfoAddress(Target *target) { // relative to the address of the tag. uint64_t rel_offset; rel_offset = target->ReadUnsignedIntegerFromMemory( - dyn_base + offset, false, GetAddressByteSize(), UINT64_MAX, error); + dyn_base + offset, GetAddressByteSize(), UINT64_MAX, error, true); if (error.Success() && rel_offset != UINT64_MAX) { Address addr; addr_t debug_ptr_address = @@ -1861,7 +1862,7 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) { // unified section list. if (GetType() != eTypeDebugInfo) unified_section_list = *m_sections_up; - + // If there's a .gnu_debugdata section, we'll try to read the .symtab that's // embedded in there and replace the one in the original object file (if any). // If there's none in the orignal object file, we add it to it. @@ -1879,7 +1880,7 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) { unified_section_list.AddSection(symtab_section_sp); } } - } + } } std::shared_ptr<ObjectFileELF> ObjectFileELF::GetGnuDebugDataObjectFile() { @@ -1923,7 +1924,7 @@ std::shared_ptr<ObjectFileELF> ObjectFileELF::GetGnuDebugDataObjectFile() { ArchSpec spec = m_gnu_debug_data_object_file->GetArchitecture(); if (spec && m_gnu_debug_data_object_file->SetModulesArchitecture(spec)) return m_gnu_debug_data_object_file; - + return nullptr; } @@ -2707,6 +2708,9 @@ Symtab *ObjectFileELF::GetSymtab() { if (!module_sp) return nullptr; + Progress progress(llvm::formatv("Parsing symbol table for {0}", + m_file.GetFilename().AsCString("<Unknown>"))); + // We always want to use the main object file so we (hopefully) only have one // cached copy of our symtab, dynamic sections, etc. ObjectFile *module_obj_file = module_sp->GetObjectFile(); @@ -2770,14 +2774,14 @@ Symtab *ObjectFileELF::GetSymtab() { user_id_t reloc_id = reloc_section->GetID(); const ELFSectionHeaderInfo *reloc_header = GetSectionHeaderByIndex(reloc_id); - assert(reloc_header); - - if (m_symtab_up == nullptr) - m_symtab_up = - std::make_unique<Symtab>(reloc_section->GetObjectFile()); + if (reloc_header) { + if (m_symtab_up == nullptr) + m_symtab_up = + std::make_unique<Symtab>(reloc_section->GetObjectFile()); - ParseTrampolineSymbols(m_symtab_up.get(), symbol_id, reloc_header, - reloc_id); + ParseTrampolineSymbols(m_symtab_up.get(), symbol_id, reloc_header, + reloc_id); + } } } @@ -2809,31 +2813,37 @@ Symtab *ObjectFileELF::GetSymtab() { if (is_valid_entry_point && !m_symtab_up->FindSymbolContainingFileAddress( entry_point_file_addr)) { uint64_t symbol_id = m_symtab_up->GetNumSymbols(); - Symbol symbol(symbol_id, - GetNextSyntheticSymbolName().GetCString(), // Symbol name. - eSymbolTypeCode, // Type of this symbol. - true, // Is this globally visible? - false, // Is this symbol debug info? - false, // Is this symbol a trampoline? - true, // Is this symbol artificial? - entry_point_addr.GetSection(), // Section where this - // symbol is defined. - 0, // Offset in section or symbol value. - 0, // Size. - false, // Size is valid. - false, // Contains linker annotations? - 0); // Symbol flags. - m_symtab_up->AddSymbol(symbol); + // Don't set the name for any synthetic symbols, the Symbol + // object will generate one if needed when the name is accessed + // via accessors. + SectionSP section_sp = entry_point_addr.GetSection(); + Symbol symbol( + /*symID=*/symbol_id, + /*name=*/llvm::StringRef(), // Name will be auto generated. + /*type=*/eSymbolTypeCode, + /*external=*/true, + /*is_debug=*/false, + /*is_trampoline=*/false, + /*is_artificial=*/true, + /*section_sp=*/section_sp, + /*offset=*/0, + /*size=*/0, // FDE can span multiple symbols so don't use its size. + /*size_is_valid=*/false, + /*contains_linker_annotations=*/false, + /*flags=*/0); // When the entry point is arm thumb we need to explicitly set its // class address to reflect that. This is important because expression // evaluation relies on correctly setting a breakpoint at this // address. if (arch.GetMachine() == llvm::Triple::arm && - (entry_point_file_addr & 1)) + (entry_point_file_addr & 1)) { + symbol.GetAddressRef().SetOffset(entry_point_addr.GetOffset() ^ 1); m_address_class_map[entry_point_file_addr ^ 1] = AddressClass::eCodeAlternateISA; - else + } else { m_address_class_map[entry_point_file_addr] = AddressClass::eCode; + } + m_symtab_up->AddSymbol(symbol); } } @@ -2897,8 +2907,11 @@ void ObjectFileELF::ParseUnwindSymbols(Symtab *symbol_table, // recalculate the index first. std::vector<Symbol> new_symbols; - eh_frame->ForEachFDEEntries([this, symbol_table, section_list, &new_symbols]( - lldb::addr_t file_addr, uint32_t size, dw_offset_t) { + size_t num_symbols = symbol_table->GetNumSymbols(); + uint64_t last_symbol_id = + num_symbols ? symbol_table->SymbolAtIndex(num_symbols - 1)->GetID() : 0; + eh_frame->ForEachFDEEntries([&](lldb::addr_t file_addr, uint32_t size, + dw_offset_t) { Symbol *symbol = symbol_table->FindSymbolAtFileAddress(file_addr); if (symbol) { if (!symbol->GetByteSizeIsValid()) { @@ -2910,22 +2923,24 @@ void ObjectFileELF::ParseUnwindSymbols(Symtab *symbol_table, section_list->FindSectionContainingFileAddress(file_addr); if (section_sp) { addr_t offset = file_addr - section_sp->GetFileAddress(); - const char *symbol_name = GetNextSyntheticSymbolName().GetCString(); - uint64_t symbol_id = symbol_table->GetNumSymbols(); + uint64_t symbol_id = ++last_symbol_id; + // Don't set the name for any synthetic symbols, the Symbol + // object will generate one if needed when the name is accessed + // via accessors. Symbol eh_symbol( - symbol_id, // Symbol table index. - symbol_name, // Symbol name. - eSymbolTypeCode, // Type of this symbol. - true, // Is this globally visible? - false, // Is this symbol debug info? - false, // Is this symbol a trampoline? - true, // Is this symbol artificial? - section_sp, // Section in which this symbol is defined or null. - offset, // Offset in section or symbol value. - 0, // Size: Don't specify the size as an FDE can - false, // Size is valid: cover multiple symbols. - false, // Contains linker annotations? - 0); // Symbol flags. + /*symID=*/symbol_id, + /*name=*/llvm::StringRef(), // Name will be auto generated. + /*type=*/eSymbolTypeCode, + /*external=*/true, + /*is_debug=*/false, + /*is_trampoline=*/false, + /*is_artificial=*/true, + /*section_sp=*/section_sp, + /*offset=*/offset, + /*size=*/0, // FDE can span multiple symbols so don't use its size. + /*size_is_valid=*/false, + /*contains_linker_annotations=*/false, + /*flags=*/0); new_symbols.push_back(eh_symbol); } } diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h index 062271f1caf0..e678c2f5f011 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h @@ -9,7 +9,7 @@ #ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_OBJECTFILEELF_H #define LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_OBJECTFILEELF_H -#include <stdint.h> +#include <cstdint> #include <vector> @@ -22,13 +22,13 @@ #include "ELFHeader.h" struct ELFNote { - elf::elf_word n_namesz; - elf::elf_word n_descsz; - elf::elf_word n_type; + elf::elf_word n_namesz = 0; + elf::elf_word n_descsz = 0; + elf::elf_word n_type = 0; std::string n_name; - ELFNote() : n_namesz(0), n_descsz(0), n_type(0) {} + ELFNote() = default; /// Parse an ELFNote entry from the given DataExtractor starting at position /// \p offset. diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp index 93c2c9f945fe..f93ac9261afd 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp @@ -100,7 +100,7 @@ ObjectFileJIT::ObjectFileJIT(const lldb::ModuleSP &module_sp, } } -ObjectFileJIT::~ObjectFileJIT() {} +ObjectFileJIT::~ObjectFileJIT() = default; bool ObjectFileJIT::ParseHeader() { // JIT code is never in a file, nor is it required to have any header diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp index 35a823e9a28f..cb7bbeeca054 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp @@ -173,7 +173,7 @@ ObjectFilePDB::loadPDBFile(std::string PdbPath, if (ec || magic != llvm::file_magic::pdb) return nullptr; llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ErrorOrBuffer = - llvm::MemoryBuffer::getFile(PdbPath, /*FileSize=*/-1, + llvm::MemoryBuffer::getFile(PdbPath, /*IsText=*/false, /*RequiresNullTerminator=*/false); if (!ErrorOrBuffer) return nullptr; diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp index 6c29c2326212..5272da9ab33a 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp @@ -196,7 +196,7 @@ bool ObjectFileWasm::DecodeNextSection(lldb::offset_t *offset_ptr) { m_sect_infos.push_back(section_info{*offset_ptr + c.tell(), section_length, section_id, *sect_name}); *offset_ptr += (c.tell() + section_length); - } else if (section_id <= llvm::wasm::WASM_SEC_EVENT) { + } else if (section_id <= llvm::wasm::WASM_SEC_TAG) { m_sect_infos.push_back(section_info{*offset_ptr + c.tell(), static_cast<uint32_t>(payload_len), section_id, ConstString()}); diff --git a/contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp b/contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp index 4350010f0296..730c88f96e13 100644 --- a/contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp @@ -91,13 +91,13 @@ OperatingSystemPython::OperatingSystemPython(lldb_private::Process *process, std::string os_plugin_class_name( python_module_path.GetFilename().AsCString("")); if (!os_plugin_class_name.empty()) { - const bool init_session = false; + LoadScriptOptions options; char python_module_path_cstr[PATH_MAX]; python_module_path.GetPath(python_module_path_cstr, sizeof(python_module_path_cstr)); Status error; - if (m_interpreter->LoadScriptingModule(python_module_path_cstr, - init_session, error)) { + if (m_interpreter->LoadScriptingModule(python_module_path_cstr, options, + error)) { // Strip the ".py" extension if there is one size_t py_extension_pos = os_plugin_class_name.rfind(".py"); if (py_extension_pos != std::string::npos) @@ -115,7 +115,7 @@ OperatingSystemPython::OperatingSystemPython(lldb_private::Process *process, } } -OperatingSystemPython::~OperatingSystemPython() {} +OperatingSystemPython::~OperatingSystemPython() = default; DynamicRegisterInfo *OperatingSystemPython::GetDynamicRegisterInfo() { if (m_register_info_up == nullptr) { diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp index 6b39a83fd668..7b3d8a375bf6 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp @@ -9,7 +9,7 @@ #include "PlatformFreeBSD.h" #include "lldb/Host/Config.h" -#include <stdio.h> +#include <cstdio> #if LLDB_ENABLE_POSIX #include <sys/utsname.h> #endif diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp index a5d73c942830..e3682b44e141 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp @@ -9,7 +9,7 @@ #include "PlatformNetBSD.h" #include "lldb/Host/Config.h" -#include <stdio.h> +#include <cstdio> #if LLDB_ENABLE_POSIX #include <sys/utsname.h> #endif diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp index 2cd024f56ec9..012b688231a0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp @@ -9,7 +9,7 @@ #include "PlatformOpenBSD.h" #include "lldb/Host/Config.h" -#include <stdio.h> +#include <cstdio> #if LLDB_ENABLE_POSIX #include <sys/utsname.h> #endif diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp index 3628b0a2ce5e..7353132cd96f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp @@ -46,7 +46,7 @@ PlatformPOSIX::PlatformPOSIX(bool is_host) /// /// The destructor is virtual since this class is designed to be /// inherited from by the plug-in instance. -PlatformPOSIX::~PlatformPOSIX() {} +PlatformPOSIX::~PlatformPOSIX() = default; lldb_private::OptionGroupOptions *PlatformPOSIX::GetConnectionOptions( lldb_private::CommandInterpreter &interpreter) { @@ -578,7 +578,19 @@ PlatformPOSIX::MakeLoadImageUtilityFunction(ExecutionContext &exe_ctx, // __lldb_dlopen_result for consistency. The wrapper returns a void * but // doesn't use it because UtilityFunctions don't work with void returns at // present. + // + // Use lazy binding so as to not make dlopen()'s success conditional on + // forcing every symbol in the library. + // + // In general, the debugger should allow programs to load & run with + // libraries as far as they can, instead of defaulting to being super-picky + // about unavailable symbols. + // + // The value "1" appears to imply lazy binding (RTLD_LAZY) on both Darwin + // and other POSIX OSes. static const char *dlopen_wrapper_code = R"( + const int RTLD_LAZY = 1; + struct __lldb_dlopen_result { void *image_ptr; const char *error_str; @@ -595,7 +607,7 @@ PlatformPOSIX::MakeLoadImageUtilityFunction(ExecutionContext &exe_ctx, { // This is the case where the name is the full path: if (!path_strings) { - result_ptr->image_ptr = dlopen(name, 2); + result_ptr->image_ptr = dlopen(name, RTLD_LAZY); if (result_ptr->image_ptr) result_ptr->error_str = nullptr; return nullptr; @@ -609,7 +621,7 @@ PlatformPOSIX::MakeLoadImageUtilityFunction(ExecutionContext &exe_ctx, buffer[path_len] = '/'; char *target_ptr = buffer+path_len+1; memcpy((void *) target_ptr, (void *) name, name_len + 1); - result_ptr->image_ptr = dlopen(buffer, 2); + result_ptr->image_ptr = dlopen(buffer, RTLD_LAZY); if (result_ptr->image_ptr) { result_ptr->error_str = nullptr; break; @@ -659,7 +671,7 @@ PlatformPOSIX::MakeLoadImageUtilityFunction(ExecutionContext &exe_ctx, // We are passing four arguments, the basename, the list of places to look, // a buffer big enough for all the path + name combos, and // a pointer to the storage we've made for the result: - value.SetValueType(Value::eValueTypeScalar); + value.SetValueType(Value::ValueType::Scalar); value.SetCompilerType(clang_void_pointer_type); arguments.PushValue(value); value.SetCompilerType(clang_char_pointer_type); @@ -994,13 +1006,6 @@ PlatformPOSIX::GetLibdlFunctionDeclarations(lldb_private::Process *process) { )"; } -size_t PlatformPOSIX::ConnectToWaitingProcesses(Debugger &debugger, - Status &error) { - if (m_remote_platform_sp) - return m_remote_platform_sp->ConnectToWaitingProcesses(debugger, error); - return Platform::ConnectToWaitingProcesses(debugger, error); -} - ConstString PlatformPOSIX::GetFullNameForDylib(ConstString basename) { if (basename.IsEmpty()) return basename; diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h b/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h index 72c54f4147c2..1cba4c5eb2e9 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h +++ b/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h @@ -71,9 +71,6 @@ public: lldb_private::Status UnloadImage(lldb_private::Process *process, uint32_t image_token) override; - size_t ConnectToWaitingProcesses(lldb_private::Debugger &debugger, - lldb_private::Status &error) override; - lldb_private::ConstString GetFullNameForDylib(lldb_private::ConstString basename) override; protected: diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp index 6a4275d249f6..528208665a4e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp @@ -30,6 +30,7 @@ #include "lldb/Utility/UriParser.h" #include "Plugins/Process/Utility/GDBRemoteSignals.h" +#include "Plugins/Process/gdb-remote/ProcessGDBRemote.h" using namespace lldb; using namespace lldb_private; @@ -202,13 +203,16 @@ Status PlatformRemoteGDBServer::GetFileWithUUID(const FileSpec &platform_file, /// Default Constructor PlatformRemoteGDBServer::PlatformRemoteGDBServer() : Platform(false), // This is a remote platform - m_gdb_client() {} + m_gdb_client() { + m_gdb_client.SetPacketTimeout( + process_gdb_remote::ProcessGDBRemote::GetPacketTimeout()); +} /// Destructor. /// /// The destructor is virtual since this class is designed to be /// inherited from by the plug-in instance. -PlatformRemoteGDBServer::~PlatformRemoteGDBServer() {} +PlatformRemoteGDBServer::~PlatformRemoteGDBServer() = default; bool PlatformRemoteGDBServer::GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) { @@ -736,8 +740,8 @@ const UnixSignalsSP &PlatformRemoteGDBServer::GetRemoteUnixSignals() { m_remote_signals_sp = UnixSignals::Create(GetRemoteSystemArchitecture()); StringExtractorGDBRemote response; - auto result = m_gdb_client.SendPacketAndWaitForResponse("jSignalsInfo", - response, false); + auto result = + m_gdb_client.SendPacketAndWaitForResponse("jSignalsInfo", response); if (result != decltype(result)::Success || response.GetResponseType() != response.eResponse) @@ -839,7 +843,7 @@ size_t PlatformRemoteGDBServer::ConnectToWaitingProcesses(Debugger &debugger, GetPendingGdbServerList(connection_urls); for (size_t i = 0; i < connection_urls.size(); ++i) { - ConnectProcess(connection_urls[i].c_str(), "", debugger, nullptr, error); + ConnectProcess(connection_urls[i].c_str(), "gdb-remote", debugger, nullptr, error); if (error.Fail()) return i; // We already connected to i process succsessfully } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp index 5961ff4439db..d6426b3d2367 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp @@ -128,13 +128,20 @@ NativeProcessFreeBSD::Factory::Attach( return std::move(process_up); } +NativeProcessFreeBSD::Extension +NativeProcessFreeBSD::Factory::GetSupportedExtensions() const { + return Extension::multiprocess | Extension::fork | Extension::vfork | + Extension::pass_signals | Extension::auxv | Extension::libraries_svr4; +} + // Public Instance Methods NativeProcessFreeBSD::NativeProcessFreeBSD(::pid_t pid, int terminal_fd, NativeDelegate &delegate, const ArchSpec &arch, MainLoop &mainloop) - : NativeProcessELF(pid, terminal_fd, delegate), m_arch(arch) { + : NativeProcessELF(pid, terminal_fd, delegate), m_arch(arch), + m_main_loop(mainloop) { if (m_terminal_fd != -1) { Status status = EnsureFDFlags(m_terminal_fd, O_NONBLOCK); assert(status.Success()); @@ -258,6 +265,26 @@ void NativeProcessFreeBSD::MonitorSIGTRAP(lldb::pid_t pid) { info.pl_lwpid); } + if (info.pl_flags & PL_FLAG_FORKED) { + assert(thread); + MonitorClone(info.pl_child_pid, info.pl_flags & PL_FLAG_VFORKED, *thread); + return; + } + + if (info.pl_flags & PL_FLAG_VFORK_DONE) { + assert(thread); + if ((m_enabled_extensions & Extension::vfork) == Extension::vfork) { + thread->SetStoppedByVForkDone(); + SetState(StateType::eStateStopped, true); + } else { + Status error = + PtraceWrapper(PT_CONTINUE, pid, reinterpret_cast<void *>(1), 0); + if (error.Fail()) + SetState(StateType::eStateInvalid); + } + return; + } + if (info.pl_flags & PL_FLAG_SI) { assert(info.pl_siginfo.si_signo == SIGTRAP); LLDB_LOG(log, "SIGTRAP siginfo: si_code = {0}, pid = {1}", @@ -705,17 +732,17 @@ NativeProcessFreeBSD::GetFileLoadAddress(const llvm::StringRef &file_name, void NativeProcessFreeBSD::SigchldHandler() { Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); - // Process all pending waitpid notifications. int status; ::pid_t wait_pid = llvm::sys::RetryAfterSignal(-1, waitpid, GetID(), &status, WNOHANG); if (wait_pid == 0) - return; // We are done. + return; if (wait_pid == -1) { Status error(errno, eErrorTypePOSIX); LLDB_LOG(log, "waitpid ({0}, &status, _) failed: {1}", GetID(), error); + return; } WaitStatus wait_status = WaitStatus::Decode(status); @@ -885,7 +912,7 @@ Status NativeProcessFreeBSD::SetupTrace() { PtraceWrapper(PT_GET_EVENT_MASK, GetID(), &events, sizeof(events)); if (status.Fail()) return status; - events |= PTRACE_LWP; + events |= PTRACE_LWP | PTRACE_FORK | PTRACE_VFORK; status = PtraceWrapper(PT_SET_EVENT_MASK, GetID(), &events, sizeof(events)); if (status.Fail()) return status; @@ -919,3 +946,66 @@ Status NativeProcessFreeBSD::ReinitializeThreads() { bool NativeProcessFreeBSD::SupportHardwareSingleStepping() const { return !m_arch.IsMIPS(); } + +void NativeProcessFreeBSD::MonitorClone(::pid_t child_pid, bool is_vfork, + NativeThreadFreeBSD &parent_thread) { + Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); + LLDB_LOG(log, "fork, child_pid={0}", child_pid); + + int status; + ::pid_t wait_pid = + llvm::sys::RetryAfterSignal(-1, ::waitpid, child_pid, &status, 0); + if (wait_pid != child_pid) { + LLDB_LOG(log, + "waiting for pid {0} failed. Assuming the pid has " + "disappeared in the meantime", + child_pid); + return; + } + if (WIFEXITED(status)) { + LLDB_LOG(log, + "waiting for pid {0} returned an 'exited' event. Not " + "tracking it.", + child_pid); + return; + } + + struct ptrace_lwpinfo info; + const auto siginfo_err = PtraceWrapper(PT_LWPINFO, child_pid, &info, sizeof(info)); + if (siginfo_err.Fail()) { + LLDB_LOG(log, "PT_LWPINFO failed {0}", siginfo_err); + return; + } + assert(info.pl_event == PL_EVENT_SIGNAL); + lldb::tid_t child_tid = info.pl_lwpid; + + std::unique_ptr<NativeProcessFreeBSD> child_process{ + new NativeProcessFreeBSD(static_cast<::pid_t>(child_pid), m_terminal_fd, + m_delegate, m_arch, m_main_loop)}; + if (!is_vfork) + child_process->m_software_breakpoints = m_software_breakpoints; + + Extension expected_ext = is_vfork ? Extension::vfork : Extension::fork; + if ((m_enabled_extensions & expected_ext) == expected_ext) { + child_process->SetupTrace(); + for (const auto &thread : child_process->m_threads) + static_cast<NativeThreadFreeBSD &>(*thread).SetStoppedBySignal(SIGSTOP); + child_process->SetState(StateType::eStateStopped, false); + + m_delegate.NewSubprocess(this, std::move(child_process)); + if (is_vfork) + parent_thread.SetStoppedByVFork(child_pid, child_tid); + else + parent_thread.SetStoppedByFork(child_pid, child_tid); + SetState(StateType::eStateStopped, true); + } else { + child_process->Detach(); + Status pt_error = + PtraceWrapper(PT_CONTINUE, GetID(), reinterpret_cast<void *>(1), 0); + if (pt_error.Fail()) { + LLDB_LOG_ERROR(log, pt_error.ToError(), + "unable to resume parent process {1}: {0}", GetID()); + SetState(StateType::eStateInvalid); + } + } +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h index ceffc370ca33..7ec9d17d4cf4 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h @@ -39,6 +39,8 @@ public: llvm::Expected<std::unique_ptr<NativeProcessProtocol>> Attach(lldb::pid_t pid, NativeDelegate &native_delegate, MainLoop &mainloop) const override; + + Extension GetSupportedExtensions() const override; }; // NativeProcessProtocol Interface @@ -96,6 +98,7 @@ protected: private: MainLoop::SignalHandleUP m_sigchld_handle; ArchSpec m_arch; + MainLoop& m_main_loop; LazyBool m_supports_mem_region = eLazyBoolCalculate; std::vector<std::pair<MemoryRegionInfo, FileSpec>> m_mem_region_cache; @@ -113,6 +116,8 @@ private: void MonitorSIGSTOP(lldb::pid_t pid); void MonitorSIGTRAP(lldb::pid_t pid); void MonitorSignal(lldb::pid_t pid, int signal); + void MonitorClone(::pid_t child_pid, bool is_vfork, + NativeThreadFreeBSD &parent_thread); Status PopulateMemoryRegionCache(); void SigchldHandler(); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp index e98e0a8a0caa..4578138a89b3 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp @@ -37,14 +37,12 @@ NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD( NativeRegisterContextFreeBSD_arm64::NativeRegisterContextFreeBSD_arm64( const ArchSpec &target_arch, NativeThreadProtocol &native_thread) : NativeRegisterContextRegisterInfo( - native_thread, new RegisterInfoPOSIX_arm64(target_arch)) + native_thread, new RegisterInfoPOSIX_arm64(target_arch, 0)) #ifdef LLDB_HAS_FREEBSD_WATCHPOINT , m_read_dbreg(false) #endif { - GetRegisterInfo().ConfigureVectorRegisterInfos( - RegisterInfoPOSIX_arm64::eVectorQuadwordAArch64); ::memset(&m_hwp_regs, 0, sizeof(m_hwp_regs)); ::memset(&m_hbp_regs, 0, sizeof(m_hbp_regs)); } @@ -79,8 +77,6 @@ Status NativeRegisterContextFreeBSD_arm64::ReadRegisterSet(uint32_t set) { return NativeProcessFreeBSD::PtraceWrapper( PT_GETFPREGS, m_thread.GetID(), m_reg_data.data() + sizeof(RegisterInfoPOSIX_arm64::GPR)); - case RegisterInfoPOSIX_arm64::SVERegSet: - return Status("not supported"); } llvm_unreachable("NativeRegisterContextFreeBSD_arm64::ReadRegisterSet"); } @@ -94,8 +90,6 @@ Status NativeRegisterContextFreeBSD_arm64::WriteRegisterSet(uint32_t set) { return NativeProcessFreeBSD::PtraceWrapper( PT_SETFPREGS, m_thread.GetID(), m_reg_data.data() + sizeof(RegisterInfoPOSIX_arm64::GPR)); - case RegisterInfoPOSIX_arm64::SVERegSet: - return Status("not supported"); } llvm_unreachable("NativeRegisterContextFreeBSD_arm64::WriteRegisterSet"); } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp index d5052e7d1b3a..9328d606ad26 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp @@ -260,7 +260,7 @@ NativeRegisterContextFreeBSD_x86_64::NativeRegisterContextFreeBSD_x86_64( const ArchSpec &target_arch, NativeThreadProtocol &native_thread) : NativeRegisterContextRegisterInfo( native_thread, CreateRegisterInfoInterface(target_arch)), - m_regset_offsets({0}) { + NativeRegisterContextDBReg_x86(native_thread), m_regset_offsets({0}) { assert(m_gpr.size() == GetRegisterInfoInterface().GetGPRSize()); std::array<uint32_t, MaxRegSet + 1> first_regnos; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp index 63be12fc7b2b..80b3527aebce 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp @@ -130,6 +130,30 @@ void NativeThreadFreeBSD::SetStoppedByWatchpoint(uint32_t wp_index) { m_stop_info.details.signal.signo = SIGTRAP; } +void NativeThreadFreeBSD::SetStoppedByFork(lldb::pid_t child_pid, + lldb::tid_t child_tid) { + SetStopped(); + + m_stop_info.reason = StopReason::eStopReasonFork; + m_stop_info.details.fork.child_pid = child_pid; + m_stop_info.details.fork.child_tid = child_tid; +} + +void NativeThreadFreeBSD::SetStoppedByVFork(lldb::pid_t child_pid, + lldb::tid_t child_tid) { + SetStopped(); + + m_stop_info.reason = StopReason::eStopReasonVFork; + m_stop_info.details.fork.child_pid = child_pid; + m_stop_info.details.fork.child_tid = child_tid; +} + +void NativeThreadFreeBSD::SetStoppedByVForkDone() { + SetStopped(); + + m_stop_info.reason = StopReason::eStopReasonVForkDone; +} + void NativeThreadFreeBSD::SetStoppedWithNoReason() { SetStopped(); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h index 249d2486b4f7..3ec6daa409e4 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h @@ -59,6 +59,9 @@ private: void SetStoppedByTrace(); void SetStoppedByExec(); void SetStoppedByWatchpoint(uint32_t wp_index); + void SetStoppedByFork(lldb::pid_t child_pid, lldb::tid_t child_tid); + void SetStoppedByVFork(lldb::pid_t child_pid, lldb::tid_t child_tid); + void SetStoppedByVForkDone(); void SetStoppedWithNoReason(); void SetStopped(); void SetRunning(); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp index 57f0eb3cceb6..9ea1a16b8785 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp @@ -133,13 +133,20 @@ NativeProcessNetBSD::Factory::Attach( return std::move(process_up); } +NativeProcessNetBSD::Extension +NativeProcessNetBSD::Factory::GetSupportedExtensions() const { + return Extension::multiprocess | Extension::fork | Extension::vfork | + Extension::pass_signals | Extension::auxv | Extension::libraries_svr4; +} + // Public Instance Methods NativeProcessNetBSD::NativeProcessNetBSD(::pid_t pid, int terminal_fd, NativeDelegate &delegate, const ArchSpec &arch, MainLoop &mainloop) - : NativeProcessELF(pid, terminal_fd, delegate), m_arch(arch) { + : NativeProcessELF(pid, terminal_fd, delegate), m_arch(arch), + m_main_loop(mainloop) { if (m_terminal_fd != -1) { Status status = EnsureFDFlags(m_terminal_fd, O_NONBLOCK); assert(status.Success()); @@ -256,6 +263,33 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) { SetState(StateType::eStateStopped, true); return; } + case TRAP_CHLD: { + ptrace_state_t pst; + Status error = PtraceWrapper(PT_GET_PROCESS_STATE, pid, &pst, sizeof(pst)); + if (error.Fail()) { + SetState(StateType::eStateInvalid); + return; + } + + assert(thread); + if (pst.pe_report_event == PTRACE_VFORK_DONE) { + if ((m_enabled_extensions & Extension::vfork) == Extension::vfork) { + thread->SetStoppedByVForkDone(); + SetState(StateType::eStateStopped, true); + } else { + Status error = + PtraceWrapper(PT_CONTINUE, pid, reinterpret_cast<void *>(1), 0); + if (error.Fail()) + SetState(StateType::eStateInvalid); + } + } else { + assert(pst.pe_report_event == PTRACE_FORK || + pst.pe_report_event == PTRACE_VFORK); + MonitorClone(pst.pe_other_pid, pst.pe_report_event == PTRACE_VFORK, + *thread); + } + return; + } case TRAP_LWP: { ptrace_state_t pst; Status error = PtraceWrapper(PT_GET_PROCESS_STATE, pid, &pst, sizeof(pst)); @@ -510,7 +544,7 @@ Status NativeProcessNetBSD::Detach() { if (GetID() == LLDB_INVALID_PROCESS_ID) return error; - return PtraceWrapper(PT_DETACH, GetID()); + return PtraceWrapper(PT_DETACH, GetID(), reinterpret_cast<void *>(1)); } Status NativeProcessNetBSD::Signal(int signo) { @@ -738,17 +772,17 @@ Status NativeProcessNetBSD::GetFileLoadAddress(const llvm::StringRef &file_name, void NativeProcessNetBSD::SigchldHandler() { Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); - // Process all pending waitpid notifications. int status; ::pid_t wait_pid = llvm::sys::RetryAfterSignal(-1, waitpid, GetID(), &status, WALLSIG | WNOHANG); if (wait_pid == 0) - return; // We are done. + return; if (wait_pid == -1) { Status error(errno, eErrorTypePOSIX); LLDB_LOG(log, "waitpid ({0}, &status, _) failed: {1}", GetID(), error); + return; } WaitStatus wait_status = WaitStatus::Decode(status); @@ -936,8 +970,9 @@ Status NativeProcessNetBSD::SetupTrace() { PtraceWrapper(PT_GET_EVENT_MASK, GetID(), &events, sizeof(events)); if (status.Fail()) return status; - // TODO: PTRACE_FORK | PTRACE_VFORK | PTRACE_POSIX_SPAWN? - events.pe_set_event |= PTRACE_LWP_CREATE | PTRACE_LWP_EXIT; + // TODO: PTRACE_POSIX_SPAWN? + events.pe_set_event |= PTRACE_LWP_CREATE | PTRACE_LWP_EXIT | PTRACE_FORK | + PTRACE_VFORK | PTRACE_VFORK_DONE; status = PtraceWrapper(PT_SET_EVENT_MASK, GetID(), &events, sizeof(events)); if (status.Fail()) return status; @@ -974,3 +1009,67 @@ Status NativeProcessNetBSD::ReinitializeThreads() { return error; } + +void NativeProcessNetBSD::MonitorClone(::pid_t child_pid, bool is_vfork, + NativeThreadNetBSD &parent_thread) { + Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); + LLDB_LOG(log, "clone, child_pid={0}", child_pid); + + int status; + ::pid_t wait_pid = + llvm::sys::RetryAfterSignal(-1, ::waitpid, child_pid, &status, 0); + if (wait_pid != child_pid) { + LLDB_LOG(log, + "waiting for pid {0} failed. Assuming the pid has " + "disappeared in the meantime", + child_pid); + return; + } + if (WIFEXITED(status)) { + LLDB_LOG(log, + "waiting for pid {0} returned an 'exited' event. Not " + "tracking it.", + child_pid); + return; + } + + ptrace_siginfo_t info; + const auto siginfo_err = + PtraceWrapper(PT_GET_SIGINFO, child_pid, &info, sizeof(info)); + if (siginfo_err.Fail()) { + LLDB_LOG(log, "PT_GET_SIGINFO failed {0}", siginfo_err); + return; + } + assert(info.psi_lwpid >= 0); + lldb::tid_t child_tid = info.psi_lwpid; + + std::unique_ptr<NativeProcessNetBSD> child_process{ + new NativeProcessNetBSD(static_cast<::pid_t>(child_pid), m_terminal_fd, + m_delegate, m_arch, m_main_loop)}; + if (!is_vfork) + child_process->m_software_breakpoints = m_software_breakpoints; + + Extension expected_ext = is_vfork ? Extension::vfork : Extension::fork; + if ((m_enabled_extensions & expected_ext) == expected_ext) { + child_process->SetupTrace(); + for (const auto &thread : child_process->m_threads) + static_cast<NativeThreadNetBSD &>(*thread).SetStoppedBySignal(SIGSTOP); + child_process->SetState(StateType::eStateStopped, false); + + m_delegate.NewSubprocess(this, std::move(child_process)); + if (is_vfork) + parent_thread.SetStoppedByVFork(child_pid, child_tid); + else + parent_thread.SetStoppedByFork(child_pid, child_tid); + SetState(StateType::eStateStopped, true); + } else { + child_process->Detach(); + Status pt_error = + PtraceWrapper(PT_CONTINUE, GetID(), reinterpret_cast<void *>(1), 0); + if (pt_error.Fail()) { + LLDB_LOG_ERROR(log, std::move(pt_error.ToError()), + "unable to resume parent process {1}: {0}", GetID()); + SetState(StateType::eStateInvalid); + } + } +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h index 3d59a4f72e94..90d32aa6069d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h @@ -36,6 +36,8 @@ public: llvm::Expected<std::unique_ptr<NativeProcessProtocol>> Attach(lldb::pid_t pid, NativeDelegate &native_delegate, MainLoop &mainloop) const override; + + Extension GetSupportedExtensions() const override; }; // NativeProcessProtocol Interface @@ -89,6 +91,7 @@ public: private: MainLoop::SignalHandleUP m_sigchld_handle; ArchSpec m_arch; + MainLoop& m_main_loop; LazyBool m_supports_mem_region = eLazyBoolCalculate; std::vector<std::pair<MemoryRegionInfo, FileSpec>> m_mem_region_cache; @@ -106,6 +109,8 @@ private: void MonitorSIGSTOP(lldb::pid_t pid); void MonitorSIGTRAP(lldb::pid_t pid); void MonitorSignal(lldb::pid_t pid, int signal); + void MonitorClone(::pid_t child_pid, bool is_vfork, + NativeThreadNetBSD &parent_thread); Status PopulateMemoryRegionCache(); void SigchldHandler(); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp index ed1884c94a4b..3d164eadbea7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp @@ -29,8 +29,8 @@ #include <x86/specialreg.h> #include <elf.h> #include <err.h> -#include <stdint.h> -#include <stdlib.h> +#include <cstdint> +#include <cstdlib> // clang-format on using namespace lldb_private; @@ -267,7 +267,7 @@ NativeRegisterContextNetBSD_x86_64::NativeRegisterContextNetBSD_x86_64( const ArchSpec &target_arch, NativeThreadProtocol &native_thread) : NativeRegisterContextRegisterInfo( native_thread, CreateRegisterInfoInterface(target_arch)), - m_regset_offsets({0}) { + NativeRegisterContextDBReg_x86(native_thread), m_regset_offsets({0}) { assert(m_gpr.size() == GetRegisterInfoInterface().GetGPRSize()); std::array<uint32_t, MaxRegularRegSet + 1> first_regnos; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp index 1a3fd4d646ae..400b89a5fddf 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp @@ -130,6 +130,30 @@ void NativeThreadNetBSD::SetStoppedByWatchpoint(uint32_t wp_index) { m_stop_info.details.signal.signo = SIGTRAP; } +void NativeThreadNetBSD::SetStoppedByFork(lldb::pid_t child_pid, + lldb::tid_t child_tid) { + SetStopped(); + + m_stop_info.reason = StopReason::eStopReasonFork; + m_stop_info.details.fork.child_pid = child_pid; + m_stop_info.details.fork.child_tid = child_tid; +} + +void NativeThreadNetBSD::SetStoppedByVFork(lldb::pid_t child_pid, + lldb::tid_t child_tid) { + SetStopped(); + + m_stop_info.reason = StopReason::eStopReasonVFork; + m_stop_info.details.fork.child_pid = child_pid; + m_stop_info.details.fork.child_tid = child_tid; +} + +void NativeThreadNetBSD::SetStoppedByVForkDone() { + SetStopped(); + + m_stop_info.reason = StopReason::eStopReasonVForkDone; +} + void NativeThreadNetBSD::SetStoppedWithNoReason() { SetStopped(); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h index d4e21bd2bdaa..ee9305337fda 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h @@ -59,6 +59,9 @@ private: void SetStoppedByTrace(); void SetStoppedByExec(); void SetStoppedByWatchpoint(uint32_t wp_index); + void SetStoppedByFork(lldb::pid_t child_pid, lldb::tid_t child_tid); + void SetStoppedByVFork(lldb::pid_t child_pid, lldb::tid_t child_tid); + void SetStoppedByVForkDone(); void SetStoppedWithNoReason(); void SetStopped(); void SetRunning(); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.h b/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.h index f5213891d976..24acdc08e900 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.h @@ -11,7 +11,7 @@ #include "lldb/lldb-types.h" -#include <signal.h> +#include <csignal> #include <string> diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h b/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h index dcfa9290ff50..c01409940daa 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h @@ -21,6 +21,9 @@ namespace lldb_private { class NativeProcessELF : public NativeProcessProtocol { using NativeProcessProtocol::NativeProcessProtocol; +public: + llvm::Optional<uint64_t> GetAuxValue(enum AuxVector::EntryType type); + protected: template <typename T> struct ELFLinkMap { T l_addr; @@ -30,8 +33,6 @@ protected: T l_prev; }; - llvm::Optional<uint64_t> GetAuxValue(enum AuxVector::EntryType type); - lldb::addr_t GetSharedLibraryInfoAddress() override; template <typename ELF_EHDR, typename ELF_PHDR, typename ELF_DYN> diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp index 5463a071503c..a85d7bd6f525 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp @@ -697,6 +697,14 @@ RegisterInfo *DynamicRegisterInfo::GetRegisterInfoAtIndex(uint32_t i) { return nullptr; } +const RegisterInfo *DynamicRegisterInfo::GetRegisterInfo(uint32_t kind, + uint32_t num) const { + uint32_t reg_index = ConvertRegisterKindToRegisterNumber(kind, num); + if (reg_index != LLDB_INVALID_REGNUM) + return &m_regs[reg_index]; + return nullptr; +} + const RegisterSet *DynamicRegisterInfo::GetRegisterSet(uint32_t i) const { if (i < m_sets.size()) return &m_sets[i]; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h index fbf9db685b71..7e90454c6d9d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h @@ -60,6 +60,9 @@ public: uint32_t ConvertRegisterKindToRegisterNumber(uint32_t kind, uint32_t num) const; + const lldb_private::RegisterInfo *GetRegisterInfo(uint32_t kind, + uint32_t num) const; + void Dump() const; void Clear(); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp index 9b9522955de9..7749dc6f5d51 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp @@ -30,7 +30,7 @@ HistoryUnwind::HistoryUnwind(Thread &thread, std::vector<lldb::addr_t> pcs, // Destructor -HistoryUnwind::~HistoryUnwind() {} +HistoryUnwind::~HistoryUnwind() = default; void HistoryUnwind::DoClear() { std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxPTraceDefines_arm64sve.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxPTraceDefines_arm64sve.h index 7f6f7cf5832d..817dca336de7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxPTraceDefines_arm64sve.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxPTraceDefines_arm64sve.h @@ -9,7 +9,7 @@ #ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXPTRACEDEFINES_ARM64SVE_H #define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXPTRACEDEFINES_ARM64SVE_H -#include <stdint.h> +#include <cstdint> namespace lldb_private { namespace sve { @@ -65,7 +65,7 @@ const uint16_t sve_context_size = 16; * The same convention applies when returning from a signal: a caller * will need to remove or resize the sve_context block if it wants to * make the SVE registers live when they were previously non-live or - * vice-versa. This may require the the caller to allocate fresh + * vice-versa. This may require the caller to allocate fresh * memory and/or move other context blocks in the signal frame. * * Changing the vector length during signal return is not permitted: diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.cpp new file mode 100644 index 000000000000..d74b66b58afc --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.cpp @@ -0,0 +1,200 @@ +//===-- MemoryTagManagerAArch64MTE.cpp --------------------------*- 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 +// +//===----------------------------------------------------------------------===// + +#include "MemoryTagManagerAArch64MTE.h" + +using namespace lldb_private; + +static const unsigned MTE_START_BIT = 56; +static const unsigned MTE_TAG_MAX = 0xf; +static const unsigned MTE_GRANULE_SIZE = 16; + +lldb::addr_t +MemoryTagManagerAArch64MTE::GetLogicalTag(lldb::addr_t addr) const { + return (addr >> MTE_START_BIT) & MTE_TAG_MAX; +} + +lldb::addr_t +MemoryTagManagerAArch64MTE::RemoveNonAddressBits(lldb::addr_t addr) const { + // Here we're ignoring the whole top byte. If you've got MTE + // you must also have TBI (top byte ignore). + // The other 4 bits could contain other extension bits or + // user metadata. + return addr & ~((lldb::addr_t)0xFF << MTE_START_BIT); +} + +ptrdiff_t MemoryTagManagerAArch64MTE::AddressDiff(lldb::addr_t addr1, + lldb::addr_t addr2) const { + return RemoveNonAddressBits(addr1) - RemoveNonAddressBits(addr2); +} + +lldb::addr_t MemoryTagManagerAArch64MTE::GetGranuleSize() const { + return MTE_GRANULE_SIZE; +} + +int32_t MemoryTagManagerAArch64MTE::GetAllocationTagType() const { + return eMTE_allocation; +} + +size_t MemoryTagManagerAArch64MTE::GetTagSizeInBytes() const { return 1; } + +MemoryTagManagerAArch64MTE::TagRange +MemoryTagManagerAArch64MTE::ExpandToGranule(TagRange range) const { + // Ignore reading a length of 0 + if (!range.IsValid()) + return range; + + const size_t granule = GetGranuleSize(); + + // Align start down to granule start + lldb::addr_t new_start = range.GetRangeBase(); + lldb::addr_t align_down_amount = new_start % granule; + new_start -= align_down_amount; + + // Account for the distance we moved the start above + size_t new_len = range.GetByteSize() + align_down_amount; + // Then align up to the end of the granule + size_t align_up_amount = granule - (new_len % granule); + if (align_up_amount != granule) + new_len += align_up_amount; + + return TagRange(new_start, new_len); +} + +llvm::Expected<MemoryTagManager::TagRange> +MemoryTagManagerAArch64MTE::MakeTaggedRange( + lldb::addr_t addr, lldb::addr_t end_addr, + const lldb_private::MemoryRegionInfos &memory_regions) const { + // First check that the range is not inverted. + // We must remove tags here otherwise an address with a higher + // tag value will always be > the other. + ptrdiff_t len = AddressDiff(end_addr, addr); + if (len <= 0) { + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "End address (0x%" PRIx64 + ") must be greater than the start address (0x%" PRIx64 ")", + end_addr, addr); + } + + // Region addresses will not have memory tags. So when searching + // we must use an untagged address. + MemoryRegionInfo::RangeType tag_range(RemoveNonAddressBits(addr), len); + tag_range = ExpandToGranule(tag_range); + + // Make a copy so we can use the original for errors and the final return. + MemoryRegionInfo::RangeType remaining_range(tag_range); + + // While there are parts of the range that don't have a matching tagged memory + // region + while (remaining_range.IsValid()) { + // Search for a region that contains the start of the range + MemoryRegionInfos::const_iterator region = std::find_if( + memory_regions.cbegin(), memory_regions.cend(), + [&remaining_range](const MemoryRegionInfo ®ion) { + return region.GetRange().Contains(remaining_range.GetRangeBase()); + }); + + if (region == memory_regions.cend() || + region->GetMemoryTagged() != MemoryRegionInfo::eYes) { + // Some part of this range is untagged (or unmapped) so error + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Address range 0x%" PRIx64 ":0x%" PRIx64 + " is not in a memory tagged region", + tag_range.GetRangeBase(), + tag_range.GetRangeEnd()); + } + + // We've found some part of the range so remove that part and continue + // searching for the rest. Moving the base "slides" the range so we need to + // save/restore the original end. If old_end is less than the new base, the + // range will be set to have 0 size and we'll exit the while. + lldb::addr_t old_end = remaining_range.GetRangeEnd(); + remaining_range.SetRangeBase(region->GetRange().GetRangeEnd()); + remaining_range.SetRangeEnd(old_end); + } + + // Every part of the range is contained within a tagged memory region. + return tag_range; +} + +llvm::Expected<std::vector<lldb::addr_t>> +MemoryTagManagerAArch64MTE::UnpackTagsData(const std::vector<uint8_t> &tags, + size_t granules /*=0*/) const { + // 0 means don't check the number of tags before unpacking + if (granules) { + size_t num_tags = tags.size() / GetTagSizeInBytes(); + if (num_tags != granules) { + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Packed tag data size does not match expected number of tags. " + "Expected %zu tag(s) for %zu granule(s), got %zu tag(s).", + granules, granules, num_tags); + } + } + + // (if bytes per tag was not 1, we would reconstruct them here) + + std::vector<lldb::addr_t> unpacked; + unpacked.reserve(tags.size()); + for (auto it = tags.begin(); it != tags.end(); ++it) { + // Check all tags are in range + if (*it > MTE_TAG_MAX) { + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Found tag 0x%x which is > max MTE tag value of 0x%x.", *it, + MTE_TAG_MAX); + } + unpacked.push_back(*it); + } + + return unpacked; +} + +llvm::Expected<std::vector<uint8_t>> MemoryTagManagerAArch64MTE::PackTags( + const std::vector<lldb::addr_t> &tags) const { + std::vector<uint8_t> packed; + packed.reserve(tags.size() * GetTagSizeInBytes()); + + for (auto tag : tags) { + if (tag > MTE_TAG_MAX) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Found tag 0x%" PRIx64 + " which is > max MTE tag value of 0x%x.", + tag, MTE_TAG_MAX); + } + packed.push_back(static_cast<uint8_t>(tag)); + } + + return packed; +} + +llvm::Expected<std::vector<lldb::addr_t>> +MemoryTagManagerAArch64MTE::RepeatTagsForRange( + const std::vector<lldb::addr_t> &tags, TagRange range) const { + std::vector<lldb::addr_t> new_tags; + + // If the range is not empty + if (range.IsValid()) { + if (tags.empty()) { + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Expected some tags to cover given range, got zero."); + } + + // We assume that this range has already been expanded/aligned to granules + size_t granules = range.GetByteSize() / GetGranuleSize(); + new_tags.reserve(granules); + for (size_t to_copy = 0; granules > 0; granules -= to_copy) { + to_copy = granules > tags.size() ? tags.size() : granules; + new_tags.insert(new_tags.end(), tags.begin(), tags.begin() + to_copy); + } + } + + return new_tags; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h new file mode 100644 index 000000000000..d4e8249da93f --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h @@ -0,0 +1,53 @@ +//===-- MemoryTagManagerAArch64MTE.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_SOURCE_PLUGINS_PROCESS_UTILITY_MEMORYTAGMANAGERAARCH64MTE_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_MEMORYTAGMANAGERAARCH64MTE_H + +#include "lldb/Target/MemoryTagManager.h" + +namespace lldb_private { + +class MemoryTagManagerAArch64MTE : public MemoryTagManager { +public: + // This enum is supposed to be shared for all of AArch64 but until + // there are more tag types than MTE, it will live here. + enum MTETagTypes { + eMTE_logical = 0, + eMTE_allocation = 1, + }; + + lldb::addr_t GetGranuleSize() const override; + int32_t GetAllocationTagType() const override; + size_t GetTagSizeInBytes() const override; + + lldb::addr_t GetLogicalTag(lldb::addr_t addr) const override; + lldb::addr_t RemoveNonAddressBits(lldb::addr_t addr) const override; + ptrdiff_t AddressDiff(lldb::addr_t addr1, lldb::addr_t addr2) const override; + + TagRange ExpandToGranule(TagRange range) const override; + + llvm::Expected<TagRange> MakeTaggedRange( + lldb::addr_t addr, lldb::addr_t end_addr, + const lldb_private::MemoryRegionInfos &memory_regions) const override; + + llvm::Expected<std::vector<lldb::addr_t>> + UnpackTagsData(const std::vector<uint8_t> &tags, + size_t granules = 0) const override; + + llvm::Expected<std::vector<uint8_t>> + PackTags(const std::vector<lldb::addr_t> &tags) const override; + + llvm::Expected<std::vector<lldb::addr_t>> + RepeatTagsForRange(const std::vector<lldb::addr_t> &tags, + TagRange range) const override; +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_MEMORYTAGMANAGERAARCH64MTE_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.cpp index 5c05baf71764..feee857cfe5f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.cpp @@ -421,6 +421,9 @@ Status NativeRegisterContextDBReg_arm64::GetWatchpointHitIndex( if (error) return Status(std::move(error)); + // Mask off ignored bits from watchpoint trap address. + trap_addr = FixWatchpointHitAddress(trap_addr); + uint32_t watch_size; lldb::addr_t watch_addr; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h index 12ef5571f64c..3da0b0407ce6 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h @@ -72,6 +72,9 @@ protected: virtual llvm::Error ReadHardwareDebugInfo() = 0; virtual llvm::Error WriteHardwareDebugRegs(DREGType hwbType) = 0; + virtual lldb::addr_t FixWatchpointHitAddress(lldb::addr_t hit_addr) { + return hit_addr; + } }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h index c0c6ce29eab5..a4ed8bfb97ea 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h @@ -16,6 +16,12 @@ namespace lldb_private { class NativeRegisterContextDBReg_x86 : public virtual NativeRegisterContextRegisterInfo { public: + // NB: This constructor is here only because gcc<=6.5 requires a virtual base + // class initializer on abstract class (even though it is never used). It can + // be deleted once we move to gcc>=7.0. + NativeRegisterContextDBReg_x86(NativeThreadProtocol &thread) + : NativeRegisterContextRegisterInfo(thread, nullptr) {} + Status IsWatchpointHit(uint32_t wp_index, bool &is_hit) override; Status GetWatchpointHitIndex(uint32_t &wp_index, diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp index eef4541e7edd..7e38091738e3 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp @@ -922,7 +922,7 @@ RegisterContextDarwin_arm::RegisterContextDarwin_arm( } } -RegisterContextDarwin_arm::~RegisterContextDarwin_arm() {} +RegisterContextDarwin_arm::~RegisterContextDarwin_arm() = default; void RegisterContextDarwin_arm::InvalidateAllRegisters() { InvalidateAllRegisterStates(); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp index 9fc275276699..b98b2f35c23e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp @@ -104,7 +104,7 @@ RegisterContextDarwin_arm64::RegisterContextDarwin_arm64( } } -RegisterContextDarwin_arm64::~RegisterContextDarwin_arm64() {} +RegisterContextDarwin_arm64::~RegisterContextDarwin_arm64() = default; void RegisterContextDarwin_arm64::InvalidateAllRegisters() { InvalidateAllRegisterStates(); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp index c5ebddc56b6c..95f8132a990c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp @@ -15,7 +15,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Compiler.h" -#include <stddef.h> +#include <cstddef> #include <memory> @@ -405,7 +405,7 @@ RegisterContextDarwin_i386::RegisterContextDarwin_i386( } } -RegisterContextDarwin_i386::~RegisterContextDarwin_i386() {} +RegisterContextDarwin_i386::~RegisterContextDarwin_i386() = default; void RegisterContextDarwin_i386::InvalidateAllRegisters() { InvalidateAllRegisterStates(); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp index 38cd00aea9cc..03e5ea424e39 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp @@ -6,9 +6,9 @@ // //===----------------------------------------------------------------------===// -#include <inttypes.h> -#include <stdarg.h> -#include <stddef.h> +#include <cinttypes> +#include <cstdarg> +#include <cstddef> #include <memory> @@ -467,7 +467,7 @@ RegisterContextDarwin_x86_64::RegisterContextDarwin_x86_64( } } -RegisterContextDarwin_x86_64::~RegisterContextDarwin_x86_64() {} +RegisterContextDarwin_x86_64::~RegisterContextDarwin_x86_64() = default; void RegisterContextDarwin_x86_64::InvalidateAllRegisters() { InvalidateAllRegisterStates(); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp index 9fe6255d698e..2991bd3c5f2c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp @@ -178,7 +178,7 @@ RegisterContextFreeBSD_powerpc::RegisterContextFreeBSD_powerpc( const ArchSpec &target_arch) : RegisterInfoInterface(target_arch) {} -RegisterContextFreeBSD_powerpc::~RegisterContextFreeBSD_powerpc() {} +RegisterContextFreeBSD_powerpc::~RegisterContextFreeBSD_powerpc() = default; size_t RegisterContextFreeBSD_powerpc::GetGPRSize() const { // This is an 'abstract' base, so no GPR struct. @@ -197,7 +197,7 @@ RegisterContextFreeBSD_powerpc32::RegisterContextFreeBSD_powerpc32( const ArchSpec &target_arch) : RegisterContextFreeBSD_powerpc(target_arch) {} -RegisterContextFreeBSD_powerpc32::~RegisterContextFreeBSD_powerpc32() {} +RegisterContextFreeBSD_powerpc32::~RegisterContextFreeBSD_powerpc32() = default; size_t RegisterContextFreeBSD_powerpc32::GetGPRSize() const { return sizeof(GPR32); @@ -217,7 +217,7 @@ RegisterContextFreeBSD_powerpc64::RegisterContextFreeBSD_powerpc64( const ArchSpec &target_arch) : RegisterContextFreeBSD_powerpc(target_arch) {} -RegisterContextFreeBSD_powerpc64::~RegisterContextFreeBSD_powerpc64() {} +RegisterContextFreeBSD_powerpc64::~RegisterContextFreeBSD_powerpc64() = default; size_t RegisterContextFreeBSD_powerpc64::GetGPRSize() const { return sizeof(GPR64); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp deleted file mode 100644 index 837549e2a495..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp +++ /dev/null @@ -1,149 +0,0 @@ -//===-- RegisterContextLinux_mips.cpp -------------------------------------===// -// -// 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 -// -//===---------------------------------------------------------------------===// - -#include <stddef.h> -#include <vector> - -// For eh_frame and DWARF Register numbers -#include "RegisterContextLinux_mips.h" - -// Internal codes for mips registers -#include "lldb-mips-linux-register-enums.h" - -// For GP and FP buffers -#include "RegisterContext_mips.h" - -using namespace lldb_private; -using namespace lldb; - -// Include RegisterInfos_mips to declare our g_register_infos_mips structure. -#define DECLARE_REGISTER_INFOS_MIPS_STRUCT -#include "RegisterInfos_mips.h" -#undef DECLARE_REGISTER_INFOS_MIPS_STRUCT - -// mips general purpose registers. -const uint32_t g_gp_regnums_mips[] = { - gpr_zero_mips, gpr_r1_mips, gpr_r2_mips, gpr_r3_mips, - gpr_r4_mips, gpr_r5_mips, gpr_r6_mips, gpr_r7_mips, - gpr_r8_mips, gpr_r9_mips, gpr_r10_mips, gpr_r11_mips, - gpr_r12_mips, gpr_r13_mips, gpr_r14_mips, gpr_r15_mips, - gpr_r16_mips, gpr_r17_mips, gpr_r18_mips, gpr_r19_mips, - gpr_r20_mips, gpr_r21_mips, gpr_r22_mips, gpr_r23_mips, - gpr_r24_mips, gpr_r25_mips, gpr_r26_mips, gpr_r27_mips, - gpr_gp_mips, gpr_sp_mips, gpr_r30_mips, gpr_ra_mips, - gpr_sr_mips, gpr_mullo_mips, gpr_mulhi_mips, gpr_badvaddr_mips, - gpr_cause_mips, gpr_pc_mips, gpr_config5_mips, - LLDB_INVALID_REGNUM // register sets need to end with this flag -}; - -static_assert((sizeof(g_gp_regnums_mips) / sizeof(g_gp_regnums_mips[0])) - 1 == - k_num_gpr_registers_mips, - "g_gp_regnums_mips has wrong number of register infos"); -// mips floating point registers. -const uint32_t g_fp_regnums_mips[] = { - fpr_f0_mips, fpr_f1_mips, fpr_f2_mips, fpr_f3_mips, - fpr_f4_mips, fpr_f5_mips, fpr_f6_mips, fpr_f7_mips, - fpr_f8_mips, fpr_f9_mips, fpr_f10_mips, fpr_f11_mips, - fpr_f12_mips, fpr_f13_mips, fpr_f14_mips, fpr_f15_mips, - fpr_f16_mips, fpr_f17_mips, fpr_f18_mips, fpr_f19_mips, - fpr_f20_mips, fpr_f21_mips, fpr_f22_mips, fpr_f23_mips, - fpr_f24_mips, fpr_f25_mips, fpr_f26_mips, fpr_f27_mips, - fpr_f28_mips, fpr_f29_mips, fpr_f30_mips, fpr_f31_mips, - fpr_fcsr_mips, fpr_fir_mips, fpr_config5_mips, - LLDB_INVALID_REGNUM // register sets need to end with this flag -}; - -static_assert((sizeof(g_fp_regnums_mips) / sizeof(g_fp_regnums_mips[0])) - 1 == - k_num_fpr_registers_mips, - "g_fp_regnums_mips has wrong number of register infos"); - -// mips MSA registers. -const uint32_t g_msa_regnums_mips[] = { - msa_w0_mips, msa_w1_mips, msa_w2_mips, msa_w3_mips, - msa_w4_mips, msa_w5_mips, msa_w6_mips, msa_w7_mips, - msa_w8_mips, msa_w9_mips, msa_w10_mips, msa_w11_mips, - msa_w12_mips, msa_w13_mips, msa_w14_mips, msa_w15_mips, - msa_w16_mips, msa_w17_mips, msa_w18_mips, msa_w19_mips, - msa_w20_mips, msa_w21_mips, msa_w22_mips, msa_w23_mips, - msa_w24_mips, msa_w25_mips, msa_w26_mips, msa_w27_mips, - msa_w28_mips, msa_w29_mips, msa_w30_mips, msa_w31_mips, - msa_fcsr_mips, msa_fir_mips, msa_mcsr_mips, msa_mir_mips, - msa_config5_mips, - LLDB_INVALID_REGNUM // register sets need to end with this flag -}; - -static_assert((sizeof(g_msa_regnums_mips) / sizeof(g_msa_regnums_mips[0])) - - 1 == - k_num_msa_registers_mips, - "g_msa_regnums_mips has wrong number of register infos"); - -// Number of register sets provided by this context. -constexpr size_t k_num_register_sets = 3; - -// Register sets for mips. -static const RegisterSet g_reg_sets_mips[k_num_register_sets] = { - {"General Purpose Registers", "gpr", k_num_gpr_registers_mips, - g_gp_regnums_mips}, - {"Floating Point Registers", "fpu", k_num_fpr_registers_mips, - g_fp_regnums_mips}, - {"MSA Registers", "msa", k_num_msa_registers_mips, g_msa_regnums_mips}}; - -uint32_t GetUserRegisterInfoCount(bool msa_present) { - if (msa_present) - return static_cast<uint32_t>(k_num_user_registers_mips); - return static_cast<uint32_t>(k_num_user_registers_mips - - k_num_msa_registers_mips); -} - -RegisterContextLinux_mips::RegisterContextLinux_mips( - const ArchSpec &target_arch, bool msa_present) - : RegisterInfoInterface(target_arch), - m_user_register_count(GetUserRegisterInfoCount(msa_present)) {} - -size_t RegisterContextLinux_mips::GetGPRSize() const { - return sizeof(GPR_linux_mips); -} - -const RegisterInfo *RegisterContextLinux_mips::GetRegisterInfo() const { - switch (m_target_arch.GetMachine()) { - case llvm::Triple::mips: - case llvm::Triple::mipsel: - return g_register_infos_mips; - default: - assert(false && "Unhandled target architecture."); - return nullptr; - } -} - -const RegisterSet * -RegisterContextLinux_mips::GetRegisterSet(size_t set) const { - if (set >= k_num_register_sets) - return nullptr; - switch (m_target_arch.GetMachine()) { - case llvm::Triple::mips: - case llvm::Triple::mipsel: - return &g_reg_sets_mips[set]; - default: - assert(false && "Unhandled target architecture."); - return nullptr; - } -} - -size_t -RegisterContextLinux_mips::GetRegisterSetCount() const { - return k_num_register_sets; -} - -uint32_t RegisterContextLinux_mips::GetRegisterCount() const { - return static_cast<uint32_t>(sizeof(g_register_infos_mips) / - sizeof(g_register_infos_mips[0])); -} - -uint32_t RegisterContextLinux_mips::GetUserRegisterCount() const { - return static_cast<uint32_t>(m_user_register_count); -} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.h deleted file mode 100644 index 9b59ab421ff4..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.h +++ /dev/null @@ -1,36 +0,0 @@ -//===-- RegisterContextLinux_mips.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_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_MIPS_H -#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_MIPS_H - -#include "RegisterInfoInterface.h" -#include "lldb/lldb-private.h" - -class RegisterContextLinux_mips : public lldb_private::RegisterInfoInterface { -public: - RegisterContextLinux_mips(const lldb_private::ArchSpec &target_arch, - bool msa_present = true); - - size_t GetGPRSize() const override; - - const lldb_private::RegisterInfo *GetRegisterInfo() const override; - - const lldb_private::RegisterSet *GetRegisterSet(size_t set) const; - - size_t GetRegisterSetCount() const; - - uint32_t GetRegisterCount() const override; - - uint32_t GetUserRegisterCount() const override; - -private: - uint32_t m_user_register_count; -}; - -#endif diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp deleted file mode 100644 index 432a78129fde..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp +++ /dev/null @@ -1,207 +0,0 @@ -//===-- RegisterContextLinux_mips64.cpp -----------------------------------===// -// -// 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 -// -//===---------------------------------------------------------------------===// - - -#include <stddef.h> -#include <vector> - -// For eh_frame and DWARF Register numbers -#include "RegisterContextLinux_mips64.h" - -// For GP and FP buffers -#include "RegisterContext_mips.h" - -// Internal codes for all mips32 and mips64 registers -#include "lldb-mips-linux-register-enums.h" - -using namespace lldb; -using namespace lldb_private; - -// Include RegisterInfos_mips64 to declare our g_register_infos_mips64 -// structure. -#define DECLARE_REGISTER_INFOS_MIPS64_STRUCT -#define LINUX_MIPS64 -#include "RegisterInfos_mips64.h" -#undef LINUX_MIPS64 -#undef DECLARE_REGISTER_INFOS_MIPS64_STRUCT - -// Include RegisterInfos_mips to declare our g_register_infos_mips structure. -#define DECLARE_REGISTER_INFOS_MIPS_STRUCT -#include "RegisterInfos_mips.h" -#undef DECLARE_REGISTER_INFOS_MIPS_STRUCT - -// mips64 general purpose registers. -const uint32_t g_gp_regnums_mips64[] = { - gpr_zero_mips64, gpr_r1_mips64, gpr_r2_mips64, - gpr_r3_mips64, gpr_r4_mips64, gpr_r5_mips64, - gpr_r6_mips64, gpr_r7_mips64, gpr_r8_mips64, - gpr_r9_mips64, gpr_r10_mips64, gpr_r11_mips64, - gpr_r12_mips64, gpr_r13_mips64, gpr_r14_mips64, - gpr_r15_mips64, gpr_r16_mips64, gpr_r17_mips64, - gpr_r18_mips64, gpr_r19_mips64, gpr_r20_mips64, - gpr_r21_mips64, gpr_r22_mips64, gpr_r23_mips64, - gpr_r24_mips64, gpr_r25_mips64, gpr_r26_mips64, - gpr_r27_mips64, gpr_gp_mips64, gpr_sp_mips64, - gpr_r30_mips64, gpr_ra_mips64, gpr_sr_mips64, - gpr_mullo_mips64, gpr_mulhi_mips64, gpr_badvaddr_mips64, - gpr_cause_mips64, gpr_pc_mips64, gpr_config5_mips64, - LLDB_INVALID_REGNUM // register sets need to end with this flag -}; - -static_assert((sizeof(g_gp_regnums_mips64) / sizeof(g_gp_regnums_mips64[0])) - - 1 == - k_num_gpr_registers_mips64, - "g_gp_regnums_mips64 has wrong number of register infos"); - -// mips64 floating point registers. -const uint32_t g_fp_regnums_mips64[] = { - fpr_f0_mips64, fpr_f1_mips64, fpr_f2_mips64, fpr_f3_mips64, - fpr_f4_mips64, fpr_f5_mips64, fpr_f6_mips64, fpr_f7_mips64, - fpr_f8_mips64, fpr_f9_mips64, fpr_f10_mips64, fpr_f11_mips64, - fpr_f12_mips64, fpr_f13_mips64, fpr_f14_mips64, fpr_f15_mips64, - fpr_f16_mips64, fpr_f17_mips64, fpr_f18_mips64, fpr_f19_mips64, - fpr_f20_mips64, fpr_f21_mips64, fpr_f22_mips64, fpr_f23_mips64, - fpr_f24_mips64, fpr_f25_mips64, fpr_f26_mips64, fpr_f27_mips64, - fpr_f28_mips64, fpr_f29_mips64, fpr_f30_mips64, fpr_f31_mips64, - fpr_fcsr_mips64, fpr_fir_mips64, fpr_config5_mips64, - LLDB_INVALID_REGNUM // register sets need to end with this flag -}; - -static_assert((sizeof(g_fp_regnums_mips64) / sizeof(g_fp_regnums_mips64[0])) - - 1 == - k_num_fpr_registers_mips64, - "g_fp_regnums_mips64 has wrong number of register infos"); - -// mips64 MSA registers. -const uint32_t g_msa_regnums_mips64[] = { - msa_w0_mips64, msa_w1_mips64, msa_w2_mips64, msa_w3_mips64, - msa_w4_mips64, msa_w5_mips64, msa_w6_mips64, msa_w7_mips64, - msa_w8_mips64, msa_w9_mips64, msa_w10_mips64, msa_w11_mips64, - msa_w12_mips64, msa_w13_mips64, msa_w14_mips64, msa_w15_mips64, - msa_w16_mips64, msa_w17_mips64, msa_w18_mips64, msa_w19_mips64, - msa_w20_mips64, msa_w21_mips64, msa_w22_mips64, msa_w23_mips64, - msa_w24_mips64, msa_w25_mips64, msa_w26_mips64, msa_w27_mips64, - msa_w28_mips64, msa_w29_mips64, msa_w30_mips64, msa_w31_mips64, - msa_fcsr_mips64, msa_fir_mips64, msa_mcsr_mips64, msa_mir_mips64, - msa_config5_mips64, - LLDB_INVALID_REGNUM // register sets need to end with this flag -}; - -static_assert((sizeof(g_msa_regnums_mips64) / sizeof(g_msa_regnums_mips64[0])) - - 1 == - k_num_msa_registers_mips64, - "g_msa_regnums_mips64 has wrong number of register infos"); - -// Number of register sets provided by this context. -constexpr size_t k_num_register_sets = 3; - -// Register sets for mips64. -static const RegisterSet g_reg_sets_mips64[k_num_register_sets] = { - {"General Purpose Registers", "gpr", k_num_gpr_registers_mips64, - g_gp_regnums_mips64}, - {"Floating Point Registers", "fpu", k_num_fpr_registers_mips64, - g_fp_regnums_mips64}, - {"MSA Registers", "msa", k_num_msa_registers_mips64, g_msa_regnums_mips64}, -}; - -const RegisterSet * -RegisterContextLinux_mips64::GetRegisterSet(size_t set) const { - if (set >= k_num_register_sets) - return nullptr; - - switch (m_target_arch.GetMachine()) { - case llvm::Triple::mips64: - case llvm::Triple::mips64el: - return &g_reg_sets_mips64[set]; - default: - assert(false && "Unhandled target architecture."); - return nullptr; - } - return nullptr; -} - -size_t -RegisterContextLinux_mips64::GetRegisterSetCount() const { - return k_num_register_sets; -} - -static const RegisterInfo *GetRegisterInfoPtr(const ArchSpec &target_arch) { - switch (target_arch.GetMachine()) { - case llvm::Triple::mips64: - case llvm::Triple::mips64el: - return g_register_infos_mips64; - case llvm::Triple::mips: - case llvm::Triple::mipsel: - return g_register_infos_mips; - default: - assert(false && "Unhandled target architecture."); - return nullptr; - } -} - -static uint32_t GetRegisterInfoCount(const ArchSpec &target_arch) { - switch (target_arch.GetMachine()) { - case llvm::Triple::mips64: - case llvm::Triple::mips64el: - return static_cast<uint32_t>(sizeof(g_register_infos_mips64) / - sizeof(g_register_infos_mips64[0])); - case llvm::Triple::mips: - case llvm::Triple::mipsel: - return static_cast<uint32_t>(sizeof(g_register_infos_mips) / - sizeof(g_register_infos_mips[0])); - default: - assert(false && "Unhandled target architecture."); - return 0; - } -} - -uint32_t GetUserRegisterInfoCount(const ArchSpec &target_arch, - bool msa_present) { - switch (target_arch.GetMachine()) { - case llvm::Triple::mips: - case llvm::Triple::mipsel: - if (msa_present) - return static_cast<uint32_t>(k_num_user_registers_mips); - return static_cast<uint32_t>(k_num_user_registers_mips - - k_num_msa_registers_mips); - case llvm::Triple::mips64el: - case llvm::Triple::mips64: - if (msa_present) - return static_cast<uint32_t>(k_num_user_registers_mips64); - return static_cast<uint32_t>(k_num_user_registers_mips64 - - k_num_msa_registers_mips64); - default: - assert(false && "Unhandled target architecture."); - return 0; - } -} - -RegisterContextLinux_mips64::RegisterContextLinux_mips64( - const ArchSpec &target_arch, bool msa_present) - : lldb_private::RegisterInfoInterface(target_arch), - m_register_info_p(GetRegisterInfoPtr(target_arch)), - m_register_info_count(GetRegisterInfoCount(target_arch)), - m_user_register_count( - GetUserRegisterInfoCount(target_arch, msa_present)) {} - -size_t RegisterContextLinux_mips64::GetGPRSize() const { - return sizeof(GPR_linux_mips); -} - -const RegisterInfo *RegisterContextLinux_mips64::GetRegisterInfo() const { - return m_register_info_p; -} - -uint32_t RegisterContextLinux_mips64::GetRegisterCount() const { - return m_register_info_count; -} - -uint32_t RegisterContextLinux_mips64::GetUserRegisterCount() const { - return m_user_register_count; -} - diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h deleted file mode 100644 index 899f0a40e4ae..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h +++ /dev/null @@ -1,39 +0,0 @@ -//===-- RegisterContextLinux_mips64.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_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_MIPS64_H -#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_MIPS64_H - -#include "RegisterInfoInterface.h" -#include "lldb/lldb-private.h" - -class RegisterContextLinux_mips64 : public lldb_private::RegisterInfoInterface { -public: - RegisterContextLinux_mips64(const lldb_private::ArchSpec &target_arch, - bool msa_present = true); - - size_t GetGPRSize() const override; - - const lldb_private::RegisterInfo *GetRegisterInfo() const override; - - const lldb_private::RegisterSet *GetRegisterSet(size_t set) const; - - size_t GetRegisterSetCount() const; - - uint32_t GetRegisterCount() const override; - - uint32_t GetUserRegisterCount() const override; - -private: - const lldb_private::RegisterInfo *m_register_info_p; - uint32_t m_register_info_count; - uint32_t m_user_register_count; -}; - -#endif - diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp index 1394cb7f00a1..067d1c3705e4 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp @@ -21,7 +21,7 @@ RegisterContextMach_arm::RegisterContextMach_arm(Thread &thread, uint32_t concrete_frame_idx) : RegisterContextDarwin_arm(thread, concrete_frame_idx) {} -RegisterContextMach_arm::~RegisterContextMach_arm() {} +RegisterContextMach_arm::~RegisterContextMach_arm() = default; int RegisterContextMach_arm::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) { mach_msg_type_number_t count = GPRWordCount; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp index b97166b6eebe..fe5cecef1b0c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp @@ -19,7 +19,7 @@ RegisterContextMach_i386::RegisterContextMach_i386(Thread &thread, uint32_t concrete_frame_idx) : RegisterContextDarwin_i386(thread, concrete_frame_idx) {} -RegisterContextMach_i386::~RegisterContextMach_i386() {} +RegisterContextMach_i386::~RegisterContextMach_i386() = default; int RegisterContextMach_i386::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) { mach_msg_type_number_t count = GPRWordCount; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp index 8933f136789f..a3d8c4f649d2 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp @@ -19,7 +19,7 @@ RegisterContextMach_x86_64::RegisterContextMach_x86_64( Thread &thread, uint32_t concrete_frame_idx) : RegisterContextDarwin_x86_64(thread, concrete_frame_idx) {} -RegisterContextMach_x86_64::~RegisterContextMach_x86_64() {} +RegisterContextMach_x86_64::~RegisterContextMach_x86_64() = default; int RegisterContextMach_x86_64::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) { diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp index f2d230b54053..c55ffebb03e7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp @@ -39,7 +39,7 @@ RegisterContextMemory::RegisterContextMemory(Thread &thread, } // Destructor -RegisterContextMemory::~RegisterContextMemory() {} +RegisterContextMemory::~RegisterContextMemory() = default; void RegisterContextMemory::InvalidateAllRegisters() { if (m_reg_data_addr != LLDB_INVALID_ADDRESS) diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp index 97a760396ba9..684176bccdf0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp @@ -6,9 +6,9 @@ // //===----------------------------------------------------------------------===// +#include <cerrno> +#include <cstdint> #include <cstring> -#include <errno.h> -#include <stdint.h> #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" @@ -45,7 +45,7 @@ RegisterContextPOSIX_arm::RegisterContextPOSIX_arm( : lldb_private::RegisterContext(thread, 0), m_register_info_up(std::move(register_info)) {} -RegisterContextPOSIX_arm::~RegisterContextPOSIX_arm() {} +RegisterContextPOSIX_arm::~RegisterContextPOSIX_arm() = default; void RegisterContextPOSIX_arm::Invalidate() {} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp index 3f52501c35f3..676e450c4846 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp @@ -6,9 +6,9 @@ // //===----------------------------------------------------------------------===// +#include <cerrno> +#include <cstdint> #include <cstring> -#include <errno.h> -#include <stdint.h> #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" @@ -40,10 +40,11 @@ bool RegisterContextPOSIX_arm64::IsFPR(unsigned reg) { } bool RegisterContextPOSIX_arm64::IsSVE(unsigned reg) const { - if (m_register_info_up->GetRegisterSetFromRegisterIndex(reg) == - RegisterInfoPOSIX_arm64::SVERegSet) - return true; - return false; + return m_register_info_up->IsSVEReg(reg); +} + +bool RegisterContextPOSIX_arm64::IsPAuth(unsigned reg) const { + return m_register_info_up->IsPAuthReg(reg); } RegisterContextPOSIX_arm64::RegisterContextPOSIX_arm64( @@ -52,7 +53,7 @@ RegisterContextPOSIX_arm64::RegisterContextPOSIX_arm64( : lldb_private::RegisterContext(thread, 0), m_register_info_up(std::move(register_info)) {} -RegisterContextPOSIX_arm64::~RegisterContextPOSIX_arm64() {} +RegisterContextPOSIX_arm64::~RegisterContextPOSIX_arm64() = default; void RegisterContextPOSIX_arm64::Invalidate() {} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h index a3f07bb2823b..7c301599d3af 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h @@ -54,6 +54,7 @@ protected: size_t GetFPUSize() { return sizeof(RegisterInfoPOSIX_arm64::FPU); } bool IsSVE(unsigned reg) const; + bool IsPAuth(unsigned reg) const; bool IsSVEZ(unsigned reg) const { return m_register_info_up->IsSVEZReg(reg); } bool IsSVEP(unsigned reg) const { return m_register_info_up->IsSVEPReg(reg); } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp index c41c4bd7a7ea..9e05737d8e62 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp @@ -6,9 +6,9 @@ // //===----------------------------------------------------------------------===// +#include <cerrno> +#include <cstdint> #include <cstring> -#include <errno.h> -#include <stdint.h> #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" @@ -22,8 +22,6 @@ #include "RegisterContextPOSIX_mips64.h" #include "RegisterContextFreeBSD_mips64.h" -#include "RegisterContextLinux_mips64.h" -#include "RegisterContextLinux_mips.h" using namespace lldb_private; using namespace lldb; @@ -60,7 +58,7 @@ RegisterContextPOSIX_mips64::RegisterContextPOSIX_mips64( m_registers_count[msa_registers_count])); } -RegisterContextPOSIX_mips64::~RegisterContextPOSIX_mips64() {} +RegisterContextPOSIX_mips64::~RegisterContextPOSIX_mips64() = default; void RegisterContextPOSIX_mips64::Invalidate() {} @@ -102,17 +100,6 @@ RegisterContextPOSIX_mips64::GetRegisterInfoAtIndex(size_t reg) { size_t RegisterContextPOSIX_mips64::GetRegisterSetCount() { ArchSpec target_arch = m_register_info_up->GetTargetArchitecture(); switch (target_arch.GetTriple().getOS()) { - case llvm::Triple::Linux: { - if ((target_arch.GetMachine() == llvm::Triple::mipsel) || - (target_arch.GetMachine() == llvm::Triple::mips)) { - const auto *context = static_cast<const RegisterContextLinux_mips *>( - m_register_info_up.get()); - return context->GetRegisterSetCount(); - } - const auto *context = static_cast<const RegisterContextLinux_mips64 *>( - m_register_info_up.get()); - return context->GetRegisterSetCount(); - } default: { const auto *context = static_cast<const RegisterContextFreeBSD_mips64 *>( m_register_info_up.get()); @@ -125,17 +112,6 @@ size_t RegisterContextPOSIX_mips64::GetRegisterSetCount() { const RegisterSet *RegisterContextPOSIX_mips64::GetRegisterSet(size_t set) { ArchSpec target_arch = m_register_info_up->GetTargetArchitecture(); switch (target_arch.GetTriple().getOS()) { - case llvm::Triple::Linux: { - if ((target_arch.GetMachine() == llvm::Triple::mipsel) || - (target_arch.GetMachine() == llvm::Triple::mips)) { - const auto *context = static_cast<const RegisterContextLinux_mips *>( - m_register_info_up.get()); - return context->GetRegisterSet(set); - } - const auto *context = static_cast<const RegisterContextLinux_mips64 *>( - m_register_info_up.get()); - return context->GetRegisterSet(set); - } default: { const auto *context = static_cast<const RegisterContextFreeBSD_mips64 *>( m_register_info_up.get()); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp index cd65b96d373e..cffd2865e385 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp @@ -6,9 +6,9 @@ // //===----------------------------------------------------------------------===// +#include <cerrno> +#include <cstdint> #include <cstring> -#include <errno.h> -#include <stdint.h> #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" @@ -95,7 +95,7 @@ RegisterContextPOSIX_powerpc::RegisterContextPOSIX_powerpc( m_register_info_up.reset(register_info); } -RegisterContextPOSIX_powerpc::~RegisterContextPOSIX_powerpc() {} +RegisterContextPOSIX_powerpc::~RegisterContextPOSIX_powerpc() = default; void RegisterContextPOSIX_powerpc::Invalidate() {} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp index f670be2ef3c4..f70ddeba209c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp @@ -6,9 +6,9 @@ // //===----------------------------------------------------------------------===// +#include <cerrno> +#include <cstdint> #include <cstring> -#include <errno.h> -#include <stdint.h> #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp index e746ec642b38..21c8160e5b41 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp @@ -6,9 +6,9 @@ // //===----------------------------------------------------------------------===// +#include <cerrno> +#include <cstdint> #include <cstring> -#include <errno.h> -#include <stdint.h> #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" @@ -98,7 +98,7 @@ RegisterContextPOSIX_s390x::RegisterContextPOSIX_s390x( } } -RegisterContextPOSIX_s390x::~RegisterContextPOSIX_s390x() {} +RegisterContextPOSIX_s390x::~RegisterContextPOSIX_s390x() = default; void RegisterContextPOSIX_s390x::Invalidate() {} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp index 2c7f63503d7c..67e03ff1ea39 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp @@ -6,9 +6,9 @@ // //===----------------------------------------------------------------------===// +#include <cerrno> +#include <cstdint> #include <cstring> -#include <errno.h> -#include <stdint.h> #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" @@ -448,7 +448,7 @@ RegisterContextPOSIX_x86::RegisterContextPOSIX_x86( m_fpr_type = eNotValid; } -RegisterContextPOSIX_x86::~RegisterContextPOSIX_x86() {} +RegisterContextPOSIX_x86::~RegisterContextPOSIX_x86() = default; RegisterContextPOSIX_x86::FPRType RegisterContextPOSIX_x86::GetFPRType() { if (m_fpr_type == eNotValid) { diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp index 31e2944084ed..4866cbd235e8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp @@ -22,7 +22,7 @@ RegisterContextThreadMemory::RegisterContextThreadMemory( : RegisterContext(thread, 0), m_thread_wp(thread.shared_from_this()), m_reg_ctx_sp(), m_register_data_addr(register_data_addr), m_stop_id(0) {} -RegisterContextThreadMemory::~RegisterContextThreadMemory() {} +RegisterContextThreadMemory::~RegisterContextThreadMemory() = default; void RegisterContextThreadMemory::UpdateRegisterContext() { ThreadSP thread_sp(m_thread_wp.lock()); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h index 88c2ae7c5010..c05438338c88 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h @@ -22,7 +22,7 @@ class RegisterInfoInterface { public: RegisterInfoInterface(const lldb_private::ArchSpec &target_arch) : m_target_arch(target_arch) {} - virtual ~RegisterInfoInterface() {} + virtual ~RegisterInfoInterface() = default; virtual size_t GetGPRSize() const = 0; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp index 17b96f944cda..63461f7ab2db 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp @@ -7,7 +7,7 @@ //===---------------------------------------------------------------------===// #include <cassert> -#include <stddef.h> +#include <cstddef> #include <vector> #include "lldb/lldb-defines.h" diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp index 515c9f44e1e2..b878534b39db 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp @@ -7,7 +7,7 @@ //===---------------------------------------------------------------------===// #include <cassert> -#include <stddef.h> +#include <cstddef> #include <vector> #include "lldb/lldb-defines.h" @@ -72,23 +72,14 @@ #include "RegisterInfos_arm64_sve.h" #undef DECLARE_REGISTER_INFOS_ARM64_STRUCT -static const lldb_private::RegisterInfo * -GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) { - switch (target_arch.GetMachine()) { - case llvm::Triple::aarch64: - case llvm::Triple::aarch64_32: - return g_register_infos_arm64_le; - default: - assert(false && "Unhandled target architecture."); - return nullptr; - } -} - // Number of register sets provided by this context. enum { k_num_gpr_registers = gpr_w28 - gpr_x0 + 1, k_num_fpr_registers = fpu_fpcr - fpu_v0 + 1, k_num_sve_registers = sve_ffr - sve_vg + 1, + k_num_mte_register = 1, + k_num_pauth_register = 2, + k_num_register_sets_default = 2, k_num_register_sets = 3 }; @@ -186,31 +177,66 @@ static const lldb_private::RegisterSet g_reg_sets_arm64[k_num_register_sets] = { {"Scalable Vector Extension Registers", "sve", k_num_sve_registers, g_sve_regnums_arm64}}; -static uint32_t -GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) { +static const lldb_private::RegisterSet g_reg_set_pauth_arm64 = { + "Pointer Authentication Registers", "pauth", k_num_pauth_register, NULL}; + +static const lldb_private::RegisterSet g_reg_set_mte_arm64 = { + "MTE Control Register", "mte", k_num_mte_register, NULL}; + +RegisterInfoPOSIX_arm64::RegisterInfoPOSIX_arm64( + const lldb_private::ArchSpec &target_arch, lldb_private::Flags opt_regsets) + : lldb_private::RegisterInfoAndSetInterface(target_arch), + m_opt_regsets(opt_regsets) { switch (target_arch.GetMachine()) { case llvm::Triple::aarch64: - case llvm::Triple::aarch64_32: - return static_cast<uint32_t>(sizeof(g_register_infos_arm64_le) / - sizeof(g_register_infos_arm64_le[0])); + case llvm::Triple::aarch64_32: { + m_register_set_p = g_reg_sets_arm64; + m_register_set_count = k_num_register_sets_default; + m_per_regset_regnum_range[GPRegSet] = std::make_pair(gpr_x0, gpr_w28 + 1); + m_per_regset_regnum_range[FPRegSet] = std::make_pair(fpu_v0, fpu_fpcr + 1); + + // Now configure register sets supported by current target. If we have a + // dynamic register set like MTE, Pointer Authentication regset then we need + // to create dynamic register infos and regset array. Push back all optional + // register infos and regset and calculate register offsets accordingly. + if (m_opt_regsets.AllSet(eRegsetMaskSVE)) { + m_register_info_p = g_register_infos_arm64_sve_le; + m_register_info_count = sve_ffr + 1; + m_per_regset_regnum_range[m_register_set_count++] = + std::make_pair(sve_vg, sve_ffr + 1); + } else { + m_register_info_p = g_register_infos_arm64_le; + m_register_info_count = fpu_fpcr + 1; + } + + if (m_opt_regsets.AnySet(eRegsetMaskDynamic)) { + llvm::ArrayRef<lldb_private::RegisterInfo> reg_infos_ref = + llvm::makeArrayRef(m_register_info_p, m_register_info_count); + llvm::ArrayRef<lldb_private::RegisterSet> reg_sets_ref = + llvm::makeArrayRef(m_register_set_p, m_register_set_count); + llvm::copy(reg_infos_ref, std::back_inserter(m_dynamic_reg_infos)); + llvm::copy(reg_sets_ref, std::back_inserter(m_dynamic_reg_sets)); + + if (m_opt_regsets.AllSet(eRegsetMaskPAuth)) + AddRegSetPAuth(); + + if (m_opt_regsets.AllSet(eRegsetMaskMTE)) + AddRegSetMTE(); + + m_register_info_count = m_dynamic_reg_infos.size(); + m_register_info_p = m_dynamic_reg_infos.data(); + m_register_set_p = m_dynamic_reg_sets.data(); + m_register_set_count = m_dynamic_reg_sets.size(); + } + break; + } default: assert(false && "Unhandled target architecture."); - return 0; } } -RegisterInfoPOSIX_arm64::RegisterInfoPOSIX_arm64( - const lldb_private::ArchSpec &target_arch) - : lldb_private::RegisterInfoAndSetInterface(target_arch), - m_register_info_p(GetRegisterInfoPtr(target_arch)), - m_register_info_count(GetRegisterInfoCount(target_arch)) { -} - uint32_t RegisterInfoPOSIX_arm64::GetRegisterCount() const { - if (IsSVEEnabled()) - return k_num_gpr_registers + k_num_fpr_registers + k_num_sve_registers; - - return k_num_gpr_registers + k_num_fpr_registers; + return m_register_info_count; } size_t RegisterInfoPOSIX_arm64::GetGPRSize() const { @@ -227,31 +253,60 @@ RegisterInfoPOSIX_arm64::GetRegisterInfo() const { } size_t RegisterInfoPOSIX_arm64::GetRegisterSetCount() const { - if (IsSVEEnabled()) - return k_num_register_sets; - return k_num_register_sets - 1; + return m_register_set_count; } size_t RegisterInfoPOSIX_arm64::GetRegisterSetFromRegisterIndex( uint32_t reg_index) const { - if (reg_index <= gpr_w28) - return GPRegSet; - if (reg_index <= fpu_fpcr) - return FPRegSet; - if (reg_index <= sve_ffr) - return SVERegSet; + for (const auto ®set_range : m_per_regset_regnum_range) { + if (reg_index >= regset_range.second.first && + reg_index < regset_range.second.second) + return regset_range.first; + } return LLDB_INVALID_REGNUM; } const lldb_private::RegisterSet * RegisterInfoPOSIX_arm64::GetRegisterSet(size_t set_index) const { if (set_index < GetRegisterSetCount()) - return &g_reg_sets_arm64[set_index]; + return &m_register_set_p[set_index]; return nullptr; } -uint32_t -RegisterInfoPOSIX_arm64::ConfigureVectorRegisterInfos(uint32_t sve_vq) { +void RegisterInfoPOSIX_arm64::AddRegSetPAuth() { + uint32_t pa_regnum = m_dynamic_reg_infos.size(); + for (uint32_t i = 0; i < k_num_pauth_register; i++) { + pauth_regnum_collection.push_back(pa_regnum + i); + m_dynamic_reg_infos.push_back(g_register_infos_pauth[i]); + m_dynamic_reg_infos[pa_regnum + i].byte_offset = + m_dynamic_reg_infos[pa_regnum + i - 1].byte_offset + + m_dynamic_reg_infos[pa_regnum + i - 1].byte_size; + m_dynamic_reg_infos[pa_regnum + i].kinds[lldb::eRegisterKindLLDB] = + pa_regnum + i; + } + + m_per_regset_regnum_range[m_register_set_count] = + std::make_pair(pa_regnum, m_dynamic_reg_infos.size()); + m_dynamic_reg_sets.push_back(g_reg_set_pauth_arm64); + m_dynamic_reg_sets.back().registers = pauth_regnum_collection.data(); +} + +void RegisterInfoPOSIX_arm64::AddRegSetMTE() { + uint32_t mte_regnum = m_dynamic_reg_infos.size(); + m_mte_regnum_collection.push_back(mte_regnum); + m_dynamic_reg_infos.push_back(g_register_infos_mte[0]); + m_dynamic_reg_infos[mte_regnum].byte_offset = + m_dynamic_reg_infos[mte_regnum - 1].byte_offset + + m_dynamic_reg_infos[mte_regnum - 1].byte_size; + m_dynamic_reg_infos[mte_regnum].kinds[lldb::eRegisterKindLLDB] = mte_regnum; + + m_per_regset_regnum_range[m_register_set_count] = + std::make_pair(mte_regnum, mte_regnum + 1); + m_dynamic_reg_sets.push_back(g_reg_set_mte_arm64); + m_dynamic_reg_sets.back().registers = m_mte_regnum_collection.data(); +} + +uint32_t RegisterInfoPOSIX_arm64::ConfigureVectorLength(uint32_t sve_vq) { // sve_vq contains SVE Quad vector length in context of AArch64 SVE. // SVE register infos if enabled cannot be disabled by selecting sve_vq = 0. // Also if an invalid or previously set vector length is passed to this @@ -266,28 +321,15 @@ RegisterInfoPOSIX_arm64::ConfigureVectorRegisterInfos(uint32_t sve_vq) { m_vector_reg_vq = sve_vq; - if (sve_vq == eVectorQuadwordAArch64) { - m_register_info_count = - static_cast<uint32_t>(sizeof(g_register_infos_arm64_le) / - sizeof(g_register_infos_arm64_le[0])); - m_register_info_p = g_register_infos_arm64_le; - + if (sve_vq == eVectorQuadwordAArch64) return m_vector_reg_vq; - } - - m_register_info_count = - static_cast<uint32_t>(sizeof(g_register_infos_arm64_sve_le) / - sizeof(g_register_infos_arm64_sve_le[0])); - std::vector<lldb_private::RegisterInfo> ®_info_ref = m_per_vq_reg_infos[sve_vq]; if (reg_info_ref.empty()) { - reg_info_ref = llvm::makeArrayRef(g_register_infos_arm64_sve_le, - m_register_info_count); + reg_info_ref = llvm::makeArrayRef(m_register_info_p, m_register_info_count); uint32_t offset = SVE_REGS_DEFAULT_OFFSET_LINUX; - reg_info_ref[fpu_fpsr].byte_offset = offset; reg_info_ref[fpu_fpcr].byte_offset = offset + 4; reg_info_ref[sve_vg].byte_offset = offset + 8; @@ -316,13 +358,25 @@ RegisterInfoPOSIX_arm64::ConfigureVectorRegisterInfos(uint32_t sve_vq) { offset += reg_info_ref[it].byte_size; } + for (uint32_t it = sve_ffr + 1; it < m_register_info_count; it++) { + reg_info_ref[it].byte_offset = offset; + offset += reg_info_ref[it].byte_size; + } + m_per_vq_reg_infos[sve_vq] = reg_info_ref; } - m_register_info_p = reg_info_ref.data(); + m_register_info_p = m_per_vq_reg_infos[sve_vq].data(); return m_vector_reg_vq; } +bool RegisterInfoPOSIX_arm64::IsSVEReg(unsigned reg) const { + if (m_vector_reg_vq > eVectorQuadwordAArch64) + return (sve_vg <= reg && reg <= sve_ffr); + else + return false; +} + bool RegisterInfoPOSIX_arm64::IsSVEZReg(unsigned reg) const { return (sve_z0 <= reg && reg <= sve_z31); } @@ -335,6 +389,18 @@ bool RegisterInfoPOSIX_arm64::IsSVERegVG(unsigned reg) const { return sve_vg == reg; } +bool RegisterInfoPOSIX_arm64::IsPAuthReg(unsigned reg) const { + return std::find(pauth_regnum_collection.begin(), + pauth_regnum_collection.end(), + reg) != pauth_regnum_collection.end(); +} + +bool RegisterInfoPOSIX_arm64::IsMTEReg(unsigned reg) const { + return std::find(m_mte_regnum_collection.begin(), + m_mte_regnum_collection.end(), + reg) != m_mte_regnum_collection.end(); +} + uint32_t RegisterInfoPOSIX_arm64::GetRegNumSVEZ0() const { return sve_z0; } uint32_t RegisterInfoPOSIX_arm64::GetRegNumSVEFFR() const { return sve_ffr; } @@ -344,3 +410,11 @@ uint32_t RegisterInfoPOSIX_arm64::GetRegNumFPCR() const { return fpu_fpcr; } uint32_t RegisterInfoPOSIX_arm64::GetRegNumFPSR() const { return fpu_fpsr; } uint32_t RegisterInfoPOSIX_arm64::GetRegNumSVEVG() const { return sve_vg; } + +uint32_t RegisterInfoPOSIX_arm64::GetPAuthOffset() const { + return m_register_info_p[pauth_regnum_collection[0]].byte_offset; +} + +uint32_t RegisterInfoPOSIX_arm64::GetMTEOffset() const { + return m_register_info_p[m_mte_regnum_collection[0]].byte_offset; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h index 2929f2009dd9..ba873ba4436b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h @@ -11,6 +11,7 @@ #include "RegisterInfoAndSetInterface.h" #include "lldb/Target/RegisterContext.h" +#include "lldb/Utility/Flags.h" #include "lldb/lldb-private.h" #include <map> @@ -19,7 +20,16 @@ enum class SVEState { Unknown, Disabled, FPSIMD, Full }; class RegisterInfoPOSIX_arm64 : public lldb_private::RegisterInfoAndSetInterface { public: - enum { GPRegSet = 0, FPRegSet, SVERegSet }; + enum { GPRegSet = 0, FPRegSet }; + + // AArch64 register set mask value + enum { + eRegsetMaskDefault = 0, + eRegsetMaskSVE = 1, + eRegsetMaskPAuth = 2, + eRegsetMaskMTE = 4, + eRegsetMaskDynamic = ~1, + }; // AArch64 Register set FP/SIMD feature configuration enum { @@ -68,7 +78,8 @@ public: uint64_t mdscr_el1; }; - RegisterInfoPOSIX_arm64(const lldb_private::ArchSpec &target_arch); + RegisterInfoPOSIX_arm64(const lldb_private::ArchSpec &target_arch, + lldb_private::Flags opt_regsets); size_t GetGPRSize() const override; @@ -85,7 +96,11 @@ public: size_t GetRegisterSetFromRegisterIndex(uint32_t reg_index) const override; - uint32_t ConfigureVectorRegisterInfos(uint32_t sve_vq); + void AddRegSetPAuth(); + + void AddRegSetMTE(); + + uint32_t ConfigureVectorLength(uint32_t sve_vq); bool VectorSizeIsValid(uint32_t vq) { if (vq >= eVectorQuadwordAArch64 && vq <= eVectorQuadwordAArch64SVEMax) @@ -93,17 +108,23 @@ public: return false; } - bool IsSVEEnabled() const { return m_vector_reg_vq > eVectorQuadwordAArch64; } + bool IsSVEEnabled() const { return m_opt_regsets.AnySet(eRegsetMaskSVE); } + bool IsPAuthEnabled() const { return m_opt_regsets.AnySet(eRegsetMaskPAuth); } + bool IsSVEReg(unsigned reg) const; bool IsSVEZReg(unsigned reg) const; bool IsSVEPReg(unsigned reg) const; bool IsSVERegVG(unsigned reg) const; + bool IsPAuthReg(unsigned reg) const; + bool IsMTEReg(unsigned reg) const; uint32_t GetRegNumSVEZ0() const; uint32_t GetRegNumSVEFFR() const; uint32_t GetRegNumFPCR() const; uint32_t GetRegNumFPSR() const; uint32_t GetRegNumSVEVG() const; + uint32_t GetPAuthOffset() const; + uint32_t GetMTEOffset() const; private: typedef std::map<uint32_t, std::vector<lldb_private::RegisterInfo>> @@ -115,6 +136,21 @@ private: const lldb_private::RegisterInfo *m_register_info_p; uint32_t m_register_info_count; + + const lldb_private::RegisterSet *m_register_set_p; + uint32_t m_register_set_count; + + // Contains pair of [start, end] register numbers of a register set with start + // and end included. + std::map<uint32_t, std::pair<uint32_t, uint32_t>> m_per_regset_regnum_range; + + lldb_private::Flags m_opt_regsets; + + std::vector<lldb_private::RegisterInfo> m_dynamic_reg_infos; + std::vector<lldb_private::RegisterSet> m_dynamic_reg_sets; + + std::vector<uint32_t> pauth_regnum_collection; + std::vector<uint32_t> m_mte_regnum_collection; }; #endif diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp index 3461d38a3901..159fd2856443 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp @@ -7,7 +7,7 @@ //===---------------------------------------------------------------------===// #include <cassert> -#include <stddef.h> +#include <cstddef> #include <vector> #include "lldb/lldb-defines.h" diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm.h index 74b9e3b2db32..4af0069eb6f3 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm.h @@ -8,7 +8,7 @@ #ifdef DECLARE_REGISTER_INFOS_ARM_STRUCT -#include <stddef.h> +#include <cstddef> #include "lldb/lldb-defines.h" #include "lldb/lldb-enumerations.h" diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h index 4aee55e7afba..47cedc31bcd7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h @@ -8,7 +8,7 @@ #ifdef DECLARE_REGISTER_INFOS_ARM64_STRUCT -#include <stddef.h> +#include <cstddef> #include "lldb/lldb-defines.h" #include "lldb/lldb-enumerations.h" @@ -470,6 +470,13 @@ static uint32_t g_d31_invalidates[] = {fpu_v31, fpu_s31, LLDB_INVALID_REGNUM}; LLDB_INVALID_REGNUM, lldb_kind \ } +// Generates register kinds array for registers with only lldb kind +#define KIND_ALL_INVALID \ + { \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM \ + } + // Generates register kinds array for vector registers #define GPR64_KIND(reg, generic_kind) MISC_KIND(reg, gpr, generic_kind) #define VREG_KIND(reg) MISC_KIND(reg, fpu, LLDB_INVALID_REGNUM) @@ -526,6 +533,13 @@ static uint32_t g_d31_invalidates[] = {fpu_v31, fpu_s31, LLDB_INVALID_REGNUM}; nullptr, 0 \ } +// Defines pointer authentication mask registers +#define DEFINE_EXTENSION_REG(reg) \ + { \ + #reg, nullptr, 8, 0, lldb::eEncodingUint, lldb::eFormatHex, \ + KIND_ALL_INVALID, nullptr, nullptr, nullptr, 0 \ + } + static lldb_private::RegisterInfo g_register_infos_arm64_le[] = { // DEFINE_GPR64(name, GENERIC KIND) DEFINE_GPR64(x0, LLDB_REGNUM_GENERIC_ARG1), @@ -772,7 +786,12 @@ static lldb_private::RegisterInfo g_register_infos_arm64_le[] = { {DEFINE_DBG(wcr, 13)}, {DEFINE_DBG(wcr, 14)}, {DEFINE_DBG(wcr, 15)} - // clang-format on }; +// clang-format on +static lldb_private::RegisterInfo g_register_infos_pauth[] = { + DEFINE_EXTENSION_REG(data_mask), DEFINE_EXTENSION_REG(code_mask)}; + +static lldb_private::RegisterInfo g_register_infos_mte[] = { + DEFINE_EXTENSION_REG(mte_ctrl)}; #endif // DECLARE_REGISTER_INFOS_ARM64_STRUCT diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips.h index 08201fd1191c..93f93d56fda2 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips.h @@ -6,7 +6,7 @@ // //===---------------------------------------------------------------------===// -#include <stddef.h> +#include <cstddef> #include "lldb/Core/dwarf.h" #include "llvm/Support/Compiler.h" diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h index b6e218ea4414..b28b91810e48 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include <stddef.h> +#include <cstddef> #include "lldb/Core/dwarf.h" #include "llvm/Support/Compiler.h" @@ -15,37 +15,11 @@ #ifdef DECLARE_REGISTER_INFOS_MIPS64_STRUCT // Computes the offset of the given GPR in the user data area. -#ifdef LINUX_MIPS64 -#define GPR_OFFSET(regname) \ - (LLVM_EXTENSION offsetof(UserArea, gpr) + \ - LLVM_EXTENSION offsetof(GPR_linux_mips, regname)) -#else #define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR_freebsd_mips, regname)) -#endif - -// Computes the offset of the given FPR in the extended data area. -#define FPR_OFFSET(regname) \ - (LLVM_EXTENSION offsetof(UserArea, fpr) + \ - LLVM_EXTENSION offsetof(FPR_linux_mips, regname)) - -// Computes the offset of the given MSA in the extended data area. -#define MSA_OFFSET(regname) \ - (LLVM_EXTENSION offsetof(UserArea, msa) + \ - LLVM_EXTENSION offsetof(MSA_linux_mips, regname)) // RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB // Note that the size and offset will be updated by platform-specific classes. -#ifdef LINUX_MIPS64 -#define DEFINE_GPR(reg, alt, kind1, kind2, kind3) \ - { \ - #reg, alt, sizeof(((GPR_linux_mips *) 0)->reg), \ - GPR_OFFSET(reg), eEncodingUint, eFormatHex, \ - {kind1, kind2, kind3, ptrace_##reg##_mips, \ - gpr_##reg##_mips64 }, \ - NULL, NULL, NULL, 0 \ - } -#else #define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \ { \ #reg, alt, sizeof(((GPR_freebsd_mips *) 0)->reg), \ @@ -54,63 +28,10 @@ gpr_##reg##_mips64 }, \ NULL, NULL, NULL, 0 \ } -#endif - -#define DEFINE_GPR_INFO(reg, alt, kind1, kind2, kind3) \ - { \ - #reg, alt, sizeof(((GPR_linux_mips *) 0)->reg) / 2, \ - GPR_OFFSET(reg), eEncodingUint, eFormatHex, \ - {kind1, kind2, kind3, ptrace_##reg##_mips, \ - gpr_##reg##_mips64 }, \ - NULL, NULL, NULL, 0 \ - } - -const uint8_t dwarf_opcode_mips64[] = { - llvm::dwarf::DW_OP_regx, dwarf_sr_mips64, llvm::dwarf::DW_OP_lit1, - llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shl, llvm::dwarf::DW_OP_and, - llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shr}; - -#define DEFINE_FPR(reg, alt, kind1, kind2, kind3) \ - { \ - #reg, alt, sizeof(((FPR_linux_mips *) 0)->reg), \ - FPR_OFFSET(reg), eEncodingIEEE754, eFormatFloat, \ - {kind1, kind2, kind3, ptrace_##reg##_mips, \ - fpr_##reg##_mips64 }, \ - NULL, NULL, dwarf_opcode_mips64, \ - sizeof(dwarf_opcode_mips64) \ - } - -#define DEFINE_FPR_INFO(reg, alt, kind1, kind2, kind3) \ - { \ - #reg, alt, sizeof(((FPR_linux_mips *) 0)->reg), \ - FPR_OFFSET(reg), eEncodingUint, eFormatHex, \ - {kind1, kind2, kind3, ptrace_##reg##_mips, \ - fpr_##reg##_mips64 }, \ - NULL, NULL, NULL, 0 \ - } - -#define DEFINE_MSA(reg, alt, kind1, kind2, kind3, kind4) \ - { \ - #reg, alt, sizeof(((MSA_linux_mips *) 0)->reg), \ - MSA_OFFSET(reg), eEncodingVector, eFormatVectorOfUInt8, \ - {kind1, kind2, kind3, kind4, \ - msa_##reg##_mips64 }, \ - NULL, NULL, NULL, 0 \ - } - -#define DEFINE_MSA_INFO(reg, alt, kind1, kind2, kind3, kind4) \ - { \ - #reg, alt, sizeof(((MSA_linux_mips *) 0)->reg), \ - MSA_OFFSET(reg), eEncodingUint, eFormatHex, \ - {kind1, kind2, kind3, kind4, \ - msa_##reg##_mips64 }, \ - NULL, NULL, NULL, 0 \ - } static RegisterInfo g_register_infos_mips64[] = { // General purpose registers. EH_Frame, DWARF, // Generic, Process Plugin -#ifndef LINUX_MIPS64 DEFINE_GPR(zero, "r0", dwarf_zero_mips64, dwarf_zero_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), DEFINE_GPR(r1, nullptr, dwarf_r1_mips64, dwarf_r1_mips64, @@ -191,231 +112,6 @@ static RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), DEFINE_GPR(dummy, nullptr, dwarf_dummy_mips64, dwarf_dummy_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), -#else - DEFINE_GPR(zero, "r0", dwarf_zero_mips64, dwarf_zero_mips64, - LLDB_INVALID_REGNUM), - DEFINE_GPR(r1, nullptr, dwarf_r1_mips64, dwarf_r1_mips64, - LLDB_INVALID_REGNUM), - DEFINE_GPR(r2, nullptr, dwarf_r2_mips64, dwarf_r2_mips64, - LLDB_INVALID_REGNUM), - DEFINE_GPR(r3, nullptr, dwarf_r3_mips64, dwarf_r3_mips64, - LLDB_INVALID_REGNUM), - DEFINE_GPR(r4, nullptr, dwarf_r4_mips64, dwarf_r4_mips64, - LLDB_REGNUM_GENERIC_ARG1), - DEFINE_GPR(r5, nullptr, dwarf_r5_mips64, dwarf_r5_mips64, - LLDB_REGNUM_GENERIC_ARG2), - DEFINE_GPR(r6, nullptr, dwarf_r6_mips64, dwarf_r6_mips64, - LLDB_REGNUM_GENERIC_ARG3), - DEFINE_GPR(r7, nullptr, dwarf_r7_mips64, dwarf_r7_mips64, - LLDB_REGNUM_GENERIC_ARG4), - DEFINE_GPR(r8, nullptr, dwarf_r8_mips64, dwarf_r8_mips64, - LLDB_REGNUM_GENERIC_ARG5), - DEFINE_GPR(r9, nullptr, dwarf_r9_mips64, dwarf_r9_mips64, - LLDB_REGNUM_GENERIC_ARG6), - DEFINE_GPR(r10, nullptr, dwarf_r10_mips64, dwarf_r10_mips64, - LLDB_REGNUM_GENERIC_ARG7), - DEFINE_GPR(r11, nullptr, dwarf_r11_mips64, dwarf_r11_mips64, - LLDB_REGNUM_GENERIC_ARG8), - DEFINE_GPR(r12, nullptr, dwarf_r12_mips64, dwarf_r12_mips64, - LLDB_INVALID_REGNUM), - DEFINE_GPR(r13, nullptr, dwarf_r13_mips64, dwarf_r13_mips64, - LLDB_INVALID_REGNUM), - DEFINE_GPR(r14, nullptr, dwarf_r14_mips64, dwarf_r14_mips64, - LLDB_INVALID_REGNUM), - DEFINE_GPR(r15, nullptr, dwarf_r15_mips64, dwarf_r15_mips64, - LLDB_INVALID_REGNUM), - DEFINE_GPR(r16, nullptr, dwarf_r16_mips64, dwarf_r16_mips64, - LLDB_INVALID_REGNUM), - DEFINE_GPR(r17, nullptr, dwarf_r17_mips64, dwarf_r17_mips64, - LLDB_INVALID_REGNUM), - DEFINE_GPR(r18, nullptr, dwarf_r18_mips64, dwarf_r18_mips64, - LLDB_INVALID_REGNUM), - DEFINE_GPR(r19, nullptr, dwarf_r19_mips64, dwarf_r19_mips64, - LLDB_INVALID_REGNUM), - DEFINE_GPR(r20, nullptr, dwarf_r20_mips64, dwarf_r20_mips64, - LLDB_INVALID_REGNUM), - DEFINE_GPR(r21, nullptr, dwarf_r21_mips64, dwarf_r21_mips64, - LLDB_INVALID_REGNUM), - DEFINE_GPR(r22, nullptr, dwarf_r22_mips64, dwarf_r22_mips64, - LLDB_INVALID_REGNUM), - DEFINE_GPR(r23, nullptr, dwarf_r23_mips64, dwarf_r23_mips64, - LLDB_INVALID_REGNUM), - DEFINE_GPR(r24, nullptr, dwarf_r24_mips64, dwarf_r24_mips64, - LLDB_INVALID_REGNUM), - DEFINE_GPR(r25, nullptr, dwarf_r25_mips64, dwarf_r25_mips64, - LLDB_INVALID_REGNUM), - DEFINE_GPR(r26, nullptr, dwarf_r26_mips64, dwarf_r26_mips64, - LLDB_INVALID_REGNUM), - DEFINE_GPR(r27, nullptr, dwarf_r27_mips64, dwarf_r27_mips64, - LLDB_INVALID_REGNUM), - DEFINE_GPR(gp, "r28", dwarf_gp_mips64, dwarf_gp_mips64, - LLDB_INVALID_REGNUM), - DEFINE_GPR(sp, "r29", dwarf_sp_mips64, dwarf_sp_mips64, - LLDB_REGNUM_GENERIC_SP), - DEFINE_GPR(r30, nullptr, dwarf_r30_mips64, dwarf_r30_mips64, - LLDB_REGNUM_GENERIC_FP), - DEFINE_GPR(ra, "r31", dwarf_ra_mips64, dwarf_ra_mips64, - LLDB_REGNUM_GENERIC_RA), - DEFINE_GPR_INFO(sr, nullptr, dwarf_sr_mips64, dwarf_sr_mips64, - LLDB_REGNUM_GENERIC_FLAGS), - DEFINE_GPR(mullo, nullptr, dwarf_lo_mips64, dwarf_lo_mips64, - LLDB_INVALID_REGNUM), - DEFINE_GPR(mulhi, nullptr, dwarf_hi_mips64, dwarf_hi_mips64, - LLDB_INVALID_REGNUM), - DEFINE_GPR(badvaddr, nullptr, dwarf_bad_mips64, dwarf_bad_mips64, - LLDB_INVALID_REGNUM), - DEFINE_GPR_INFO(cause, nullptr, dwarf_cause_mips64, dwarf_cause_mips64, - LLDB_INVALID_REGNUM), - DEFINE_GPR(pc, "pc", dwarf_pc_mips64, dwarf_pc_mips64, - LLDB_REGNUM_GENERIC_PC), - DEFINE_GPR_INFO(config5, nullptr, dwarf_config5_mips64, - dwarf_config5_mips64, LLDB_INVALID_REGNUM), - DEFINE_FPR(f0, nullptr, dwarf_f0_mips64, dwarf_f0_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f1, nullptr, dwarf_f1_mips64, dwarf_f1_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f2, nullptr, dwarf_f2_mips64, dwarf_f2_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f3, nullptr, dwarf_f3_mips64, dwarf_f3_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f4, nullptr, dwarf_f4_mips64, dwarf_f4_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f5, nullptr, dwarf_f5_mips64, dwarf_f5_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f6, nullptr, dwarf_f6_mips64, dwarf_f6_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f7, nullptr, dwarf_f7_mips64, dwarf_f7_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f8, nullptr, dwarf_f8_mips64, dwarf_f8_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f9, nullptr, dwarf_f9_mips64, dwarf_f9_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f10, nullptr, dwarf_f10_mips64, dwarf_f10_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f11, nullptr, dwarf_f11_mips64, dwarf_f11_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f12, nullptr, dwarf_f12_mips64, dwarf_f12_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f13, nullptr, dwarf_f13_mips64, dwarf_f13_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f14, nullptr, dwarf_f14_mips64, dwarf_f14_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f15, nullptr, dwarf_f15_mips64, dwarf_f15_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f16, nullptr, dwarf_f16_mips64, dwarf_f16_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f17, nullptr, dwarf_f17_mips64, dwarf_f17_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f18, nullptr, dwarf_f18_mips64, dwarf_f18_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f19, nullptr, dwarf_f19_mips64, dwarf_f19_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f20, nullptr, dwarf_f20_mips64, dwarf_f20_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f21, nullptr, dwarf_f21_mips64, dwarf_f21_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f22, nullptr, dwarf_f22_mips64, dwarf_f22_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f23, nullptr, dwarf_f23_mips64, dwarf_f23_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f24, nullptr, dwarf_f24_mips64, dwarf_f24_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f25, nullptr, dwarf_f25_mips64, dwarf_f25_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f26, nullptr, dwarf_f26_mips64, dwarf_f26_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f27, nullptr, dwarf_f27_mips64, dwarf_f27_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f28, nullptr, dwarf_f28_mips64, dwarf_f28_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f29, nullptr, dwarf_f29_mips64, dwarf_f29_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f30, nullptr, dwarf_f30_mips64, dwarf_f30_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR(f31, nullptr, dwarf_f31_mips64, dwarf_f31_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR_INFO(fcsr, nullptr, dwarf_fcsr_mips64, dwarf_fcsr_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR_INFO(fir, nullptr, dwarf_fir_mips64, dwarf_fir_mips64, - LLDB_INVALID_REGNUM), - DEFINE_FPR_INFO(config5, nullptr, dwarf_config5_mips64, - dwarf_config5_mips64, LLDB_INVALID_REGNUM), - DEFINE_MSA(w0, nullptr, dwarf_w0_mips64, dwarf_w0_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w1, nullptr, dwarf_w1_mips64, dwarf_w1_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w2, nullptr, dwarf_w2_mips64, dwarf_w2_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w3, nullptr, dwarf_w3_mips64, dwarf_w3_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w4, nullptr, dwarf_w4_mips64, dwarf_w4_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w5, nullptr, dwarf_w5_mips64, dwarf_w5_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w6, nullptr, dwarf_w6_mips64, dwarf_w6_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w7, nullptr, dwarf_w7_mips64, dwarf_w7_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w8, nullptr, dwarf_w8_mips64, dwarf_w8_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w9, nullptr, dwarf_w9_mips64, dwarf_w9_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w10, nullptr, dwarf_w10_mips64, dwarf_w10_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w11, nullptr, dwarf_w11_mips64, dwarf_w11_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w12, nullptr, dwarf_w12_mips64, dwarf_w12_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w13, nullptr, dwarf_w13_mips64, dwarf_w13_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w14, nullptr, dwarf_w14_mips64, dwarf_w14_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w15, nullptr, dwarf_w15_mips64, dwarf_w15_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w16, nullptr, dwarf_w16_mips64, dwarf_w16_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w17, nullptr, dwarf_w17_mips64, dwarf_w17_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w18, nullptr, dwarf_w18_mips64, dwarf_w18_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w19, nullptr, dwarf_w19_mips64, dwarf_w19_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w20, nullptr, dwarf_w10_mips64, dwarf_w20_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w21, nullptr, dwarf_w21_mips64, dwarf_w21_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w22, nullptr, dwarf_w22_mips64, dwarf_w22_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w23, nullptr, dwarf_w23_mips64, dwarf_w23_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w24, nullptr, dwarf_w24_mips64, dwarf_w24_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w25, nullptr, dwarf_w25_mips64, dwarf_w25_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w26, nullptr, dwarf_w26_mips64, dwarf_w26_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w27, nullptr, dwarf_w27_mips64, dwarf_w27_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w28, nullptr, dwarf_w28_mips64, dwarf_w28_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w29, nullptr, dwarf_w29_mips64, dwarf_w29_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w30, nullptr, dwarf_w30_mips64, dwarf_w30_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA(w31, nullptr, dwarf_w31_mips64, dwarf_w31_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA_INFO(mcsr, nullptr, dwarf_mcsr_mips64, dwarf_mcsr_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA_INFO(mir, nullptr, dwarf_mir_mips64, dwarf_mir_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA_INFO(fcsr, nullptr, dwarf_fcsr_mips64, dwarf_fcsr_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA_INFO(fir, nullptr, dwarf_fir_mips64, dwarf_fir_mips64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_MSA_INFO(config5, nullptr, dwarf_config5_mips64, - dwarf_config5_mips64, LLDB_INVALID_REGNUM, - LLDB_INVALID_REGNUM) -#endif }; static_assert((sizeof(g_register_infos_mips64) / diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h index 90863dfdb090..04b4171b6722 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h @@ -6,7 +6,7 @@ // //===---------------------------------------------------------------------===// -#include <stddef.h> +#include <cstddef> // Computes the offset of the given GPR in the user data area. #define GPR_OFFSET(regname) (offsetof(GPR, regname)) diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64.h index 1086d3db0b06..059dba45f9bb 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64.h @@ -8,7 +8,7 @@ #ifdef DECLARE_REGISTER_INFOS_PPC64_STRUCT -#include <stddef.h> +#include <cstddef> // Computes the offset of the given GPR_PPC64 in the user data area. #define GPR_PPC64_OFFSET(regname) (offsetof(GPR_PPC64, regname)) diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h index 0b099a53d875..9937da2f3050 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h @@ -8,7 +8,7 @@ #ifdef DECLARE_REGISTER_INFOS_PPC64LE_STRUCT -#include <stddef.h> +#include <cstddef> // Computes the offset of the given GPR in the user data area. #define GPR_OFFSET(regname) (offsetof(GPR, regname)) diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h index 11344ff8ee79..d1df7c606207 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include <stddef.h> +#include <cstddef> #include "llvm/Support/Compiler.h" diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp index 2d8e8ef21612..85785a20354d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp @@ -509,7 +509,7 @@ StopInfoSP StopInfoMachException::CreateStopReasonWithMachException( // operating system thread ID, so we can't make any assumptions about // the thread ID so we must always report the breakpoint regardless // of the thread. - if (bp_site_sp->ValidForThisThread(&thread) || + if (bp_site_sp->ValidForThisThread(thread) || thread.GetProcess()->GetOperatingSystem() != nullptr) return StopInfo::CreateStopReasonWithBreakpointSiteID( thread, bp_site_sp->GetID()); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h deleted file mode 100644 index 348af27d2809..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h +++ /dev/null @@ -1,360 +0,0 @@ -//===-- lldb-mips-linux-register-enums.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_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_LINUX_REGISTER_ENUMS_H -#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_LINUX_REGISTER_ENUMS_H - -namespace lldb_private { -// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB) - -// Internal codes for all mips registers. -enum { - k_first_gpr_mips, - gpr_zero_mips = k_first_gpr_mips, - gpr_r1_mips, - gpr_r2_mips, - gpr_r3_mips, - gpr_r4_mips, - gpr_r5_mips, - gpr_r6_mips, - gpr_r7_mips, - gpr_r8_mips, - gpr_r9_mips, - gpr_r10_mips, - gpr_r11_mips, - gpr_r12_mips, - gpr_r13_mips, - gpr_r14_mips, - gpr_r15_mips, - gpr_r16_mips, - gpr_r17_mips, - gpr_r18_mips, - gpr_r19_mips, - gpr_r20_mips, - gpr_r21_mips, - gpr_r22_mips, - gpr_r23_mips, - gpr_r24_mips, - gpr_r25_mips, - gpr_r26_mips, - gpr_r27_mips, - gpr_gp_mips, - gpr_sp_mips, - gpr_r30_mips, - gpr_ra_mips, - gpr_sr_mips, - gpr_mullo_mips, - gpr_mulhi_mips, - gpr_badvaddr_mips, - gpr_cause_mips, - gpr_pc_mips, - gpr_config5_mips, - - k_last_gpr_mips = gpr_config5_mips, - - k_first_fpr_mips, - fpr_f0_mips = k_first_fpr_mips, - fpr_f1_mips, - fpr_f2_mips, - fpr_f3_mips, - fpr_f4_mips, - fpr_f5_mips, - fpr_f6_mips, - fpr_f7_mips, - fpr_f8_mips, - fpr_f9_mips, - fpr_f10_mips, - fpr_f11_mips, - fpr_f12_mips, - fpr_f13_mips, - fpr_f14_mips, - fpr_f15_mips, - fpr_f16_mips, - fpr_f17_mips, - fpr_f18_mips, - fpr_f19_mips, - fpr_f20_mips, - fpr_f21_mips, - fpr_f22_mips, - fpr_f23_mips, - fpr_f24_mips, - fpr_f25_mips, - fpr_f26_mips, - fpr_f27_mips, - fpr_f28_mips, - fpr_f29_mips, - fpr_f30_mips, - fpr_f31_mips, - fpr_fcsr_mips, - fpr_fir_mips, - fpr_config5_mips, - k_last_fpr_mips = fpr_config5_mips, - - k_first_msa_mips, - msa_w0_mips = k_first_msa_mips, - msa_w1_mips, - msa_w2_mips, - msa_w3_mips, - msa_w4_mips, - msa_w5_mips, - msa_w6_mips, - msa_w7_mips, - msa_w8_mips, - msa_w9_mips, - msa_w10_mips, - msa_w11_mips, - msa_w12_mips, - msa_w13_mips, - msa_w14_mips, - msa_w15_mips, - msa_w16_mips, - msa_w17_mips, - msa_w18_mips, - msa_w19_mips, - msa_w20_mips, - msa_w21_mips, - msa_w22_mips, - msa_w23_mips, - msa_w24_mips, - msa_w25_mips, - msa_w26_mips, - msa_w27_mips, - msa_w28_mips, - msa_w29_mips, - msa_w30_mips, - msa_w31_mips, - msa_fcsr_mips, - msa_fir_mips, - msa_mcsr_mips, - msa_mir_mips, - msa_config5_mips, - k_last_msa_mips = msa_config5_mips, - - k_num_registers_mips, - - k_num_gpr_registers_mips = k_last_gpr_mips - k_first_gpr_mips + 1, - k_num_fpr_registers_mips = k_last_fpr_mips - k_first_fpr_mips + 1, - k_num_msa_registers_mips = k_last_msa_mips - k_first_msa_mips + 1, - k_num_user_registers_mips = k_num_gpr_registers_mips + - k_num_fpr_registers_mips + - k_num_msa_registers_mips -}; - -// Internal codes for all mips64 registers. -enum { - k_first_gpr_mips64, - gpr_zero_mips64 = k_first_gpr_mips64, - gpr_r1_mips64, - gpr_r2_mips64, - gpr_r3_mips64, - gpr_r4_mips64, - gpr_r5_mips64, - gpr_r6_mips64, - gpr_r7_mips64, - gpr_r8_mips64, - gpr_r9_mips64, - gpr_r10_mips64, - gpr_r11_mips64, - gpr_r12_mips64, - gpr_r13_mips64, - gpr_r14_mips64, - gpr_r15_mips64, - gpr_r16_mips64, - gpr_r17_mips64, - gpr_r18_mips64, - gpr_r19_mips64, - gpr_r20_mips64, - gpr_r21_mips64, - gpr_r22_mips64, - gpr_r23_mips64, - gpr_r24_mips64, - gpr_r25_mips64, - gpr_r26_mips64, - gpr_r27_mips64, - gpr_gp_mips64, - gpr_sp_mips64, - gpr_r30_mips64, - gpr_ra_mips64, - gpr_sr_mips64, - gpr_mullo_mips64, - gpr_mulhi_mips64, - gpr_badvaddr_mips64, - gpr_cause_mips64, - gpr_pc_mips64, - gpr_config5_mips64, - k_last_gpr_mips64 = gpr_config5_mips64, - - k_first_fpr_mips64, - fpr_f0_mips64 = k_first_fpr_mips64, - fpr_f1_mips64, - fpr_f2_mips64, - fpr_f3_mips64, - fpr_f4_mips64, - fpr_f5_mips64, - fpr_f6_mips64, - fpr_f7_mips64, - fpr_f8_mips64, - fpr_f9_mips64, - fpr_f10_mips64, - fpr_f11_mips64, - fpr_f12_mips64, - fpr_f13_mips64, - fpr_f14_mips64, - fpr_f15_mips64, - fpr_f16_mips64, - fpr_f17_mips64, - fpr_f18_mips64, - fpr_f19_mips64, - fpr_f20_mips64, - fpr_f21_mips64, - fpr_f22_mips64, - fpr_f23_mips64, - fpr_f24_mips64, - fpr_f25_mips64, - fpr_f26_mips64, - fpr_f27_mips64, - fpr_f28_mips64, - fpr_f29_mips64, - fpr_f30_mips64, - fpr_f31_mips64, - fpr_fcsr_mips64, - fpr_fir_mips64, - fpr_config5_mips64, - k_last_fpr_mips64 = fpr_config5_mips64, - - k_first_msa_mips64, - msa_w0_mips64 = k_first_msa_mips64, - msa_w1_mips64, - msa_w2_mips64, - msa_w3_mips64, - msa_w4_mips64, - msa_w5_mips64, - msa_w6_mips64, - msa_w7_mips64, - msa_w8_mips64, - msa_w9_mips64, - msa_w10_mips64, - msa_w11_mips64, - msa_w12_mips64, - msa_w13_mips64, - msa_w14_mips64, - msa_w15_mips64, - msa_w16_mips64, - msa_w17_mips64, - msa_w18_mips64, - msa_w19_mips64, - msa_w20_mips64, - msa_w21_mips64, - msa_w22_mips64, - msa_w23_mips64, - msa_w24_mips64, - msa_w25_mips64, - msa_w26_mips64, - msa_w27_mips64, - msa_w28_mips64, - msa_w29_mips64, - msa_w30_mips64, - msa_w31_mips64, - msa_fcsr_mips64, - msa_fir_mips64, - msa_mcsr_mips64, - msa_mir_mips64, - msa_config5_mips64, - k_last_msa_mips64 = msa_config5_mips64, - - k_num_registers_mips64, - - k_num_gpr_registers_mips64 = k_last_gpr_mips64 - k_first_gpr_mips64 + 1, - k_num_fpr_registers_mips64 = k_last_fpr_mips64 - k_first_fpr_mips64 + 1, - k_num_msa_registers_mips64 = k_last_msa_mips64 - k_first_msa_mips64 + 1, - k_num_user_registers_mips64 = k_num_gpr_registers_mips64 + - k_num_fpr_registers_mips64 + - k_num_msa_registers_mips64 -}; - -// Register no. for RegisterKind = eRegisterKindProcessPlugin -// The ptrace request PTRACE_PEEKUSER/PTRACE_POKEUSER used this number -enum { - ptrace_zero_mips, - ptrace_r1_mips, - ptrace_r2_mips, - ptrace_r3_mips, - ptrace_r4_mips, - ptrace_r5_mips, - ptrace_r6_mips, - ptrace_r7_mips, - ptrace_r8_mips, - ptrace_r9_mips, - ptrace_r10_mips, - ptrace_r11_mips, - ptrace_r12_mips, - ptrace_r13_mips, - ptrace_r14_mips, - ptrace_r15_mips, - ptrace_r16_mips, - ptrace_r17_mips, - ptrace_r18_mips, - ptrace_r19_mips, - ptrace_r20_mips, - ptrace_r21_mips, - ptrace_r22_mips, - ptrace_r23_mips, - ptrace_r24_mips, - ptrace_r25_mips, - ptrace_r26_mips, - ptrace_r27_mips, - ptrace_gp_mips, - ptrace_sp_mips, - ptrace_r30_mips, - ptrace_ra_mips, - ptrace_f0_mips, - ptrace_f1_mips, - ptrace_f2_mips, - ptrace_f3_mips, - ptrace_f4_mips, - ptrace_f5_mips, - ptrace_f6_mips, - ptrace_f7_mips, - ptrace_f8_mips, - ptrace_f9_mips, - ptrace_f10_mips, - ptrace_f11_mips, - ptrace_f12_mips, - ptrace_f13_mips, - ptrace_f14_mips, - ptrace_f15_mips, - ptrace_f16_mips, - ptrace_f17_mips, - ptrace_f18_mips, - ptrace_f19_mips, - ptrace_f20_mips, - ptrace_f21_mips, - ptrace_f22_mips, - ptrace_f23_mips, - ptrace_f24_mips, - ptrace_f25_mips, - ptrace_f26_mips, - ptrace_f27_mips, - ptrace_f28_mips, - ptrace_f29_mips, - ptrace_f30_mips, - ptrace_f31_mips, - ptrace_pc_mips, - ptrace_cause_mips, - ptrace_badvaddr_mips, - ptrace_mulhi_mips, - ptrace_mullo_mips, - ptrace_fcsr_mips, - ptrace_fir_mips, - ptrace_sr_mips, - ptrace_config5_mips -}; -} - -#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_LINUX_REGISTER_ENUMS_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp index ae19367ca3ae..12bc7390c729 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include <stdlib.h> +#include <cstdlib> #include <memory> #include <mutex> @@ -353,7 +353,6 @@ size_t ProcessElfCore::DoReadMemory(lldb::addr_t addr, void *buf, size_t size, const lldb::addr_t file_end = address_range->data.GetRangeEnd(); size_t bytes_to_read = size; // Number of bytes to read from the core file size_t bytes_copied = 0; // Number of bytes actually read from the core file - size_t zero_fill_size = 0; // Padding lldb::addr_t bytes_left = 0; // Number of bytes available in the core file from the given address @@ -367,24 +366,15 @@ size_t ProcessElfCore::DoReadMemory(lldb::addr_t addr, void *buf, size_t size, if (file_end > file_start + offset) bytes_left = file_end - (file_start + offset); - // Figure out how many bytes we need to zero-fill if we are reading more - // bytes than available in the on-disk segment - if (bytes_to_read > bytes_left) { - zero_fill_size = bytes_to_read - bytes_left; + if (bytes_to_read > bytes_left) bytes_to_read = bytes_left; - } // If there is data available on the core file read it if (bytes_to_read) bytes_copied = core_objfile->CopyData(offset + file_start, bytes_to_read, buf); - assert(zero_fill_size <= size); - // Pad remaining bytes - if (zero_fill_size) - memset(((char *)buf) + bytes_copied, 0, zero_fill_size); - - return bytes_copied + zero_fill_size; + return bytes_copied; } void ProcessElfCore::Clear() { @@ -414,12 +404,8 @@ lldb::addr_t ProcessElfCore::GetImageInfoAddress() { // Parse a FreeBSD NT_PRSTATUS note - see FreeBSD sys/procfs.h for details. static void ParseFreeBSDPrStatus(ThreadData &thread_data, const DataExtractor &data, - const ArchSpec &arch) { + bool lp64) { lldb::offset_t offset = 0; - bool lp64 = (arch.GetMachine() == llvm::Triple::aarch64 || - arch.GetMachine() == llvm::Triple::mips64 || - arch.GetMachine() == llvm::Triple::ppc64 || - arch.GetMachine() == llvm::Triple::x86_64); int pr_version = data.GetU32(&offset); Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); @@ -443,6 +429,27 @@ static void ParseFreeBSDPrStatus(ThreadData &thread_data, thread_data.gpregset = DataExtractor(data, offset, len); } +// Parse a FreeBSD NT_PRPSINFO note - see FreeBSD sys/procfs.h for details. +static void ParseFreeBSDPrPsInfo(ProcessElfCore &process, + const DataExtractor &data, + bool lp64) { + lldb::offset_t offset = 0; + int pr_version = data.GetU32(&offset); + + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + if (log) { + if (pr_version > 1) + LLDB_LOGF(log, "FreeBSD PRPSINFO unexpected version %d", pr_version); + } + + // Skip pr_psinfosz, pr_fname, pr_psargs + offset += 108; + if (lp64) + offset += 4; + + process.SetID(data.GetU32(&offset)); // pr_pid +} + static llvm::Error ParseNetBSDProcInfo(const DataExtractor &data, uint32_t &cpi_nlwps, uint32_t &cpi_signo, @@ -522,6 +529,11 @@ ProcessElfCore::parseSegment(const DataExtractor &segment) { } llvm::Error ProcessElfCore::parseFreeBSDNotes(llvm::ArrayRef<CoreNote> notes) { + ArchSpec arch = GetArchitecture(); + bool lp64 = (arch.GetMachine() == llvm::Triple::aarch64 || + arch.GetMachine() == llvm::Triple::mips64 || + arch.GetMachine() == llvm::Triple::ppc64 || + arch.GetMachine() == llvm::Triple::x86_64); bool have_prstatus = false; bool have_prpsinfo = false; ThreadData thread_data; @@ -542,10 +554,11 @@ llvm::Error ProcessElfCore::parseFreeBSDNotes(llvm::ArrayRef<CoreNote> notes) { switch (note.info.n_type) { case ELF::NT_PRSTATUS: have_prstatus = true; - ParseFreeBSDPrStatus(thread_data, note.data, GetArchitecture()); + ParseFreeBSDPrStatus(thread_data, note.data, lp64); break; case ELF::NT_PRPSINFO: have_prpsinfo = true; + ParseFreeBSDPrPsInfo(*this, note.data, lp64); break; case ELF::NT_FREEBSD_THRMISC: { lldb::offset_t offset = 0; @@ -651,6 +664,32 @@ llvm::Error ProcessElfCore::parseNetBSDNotes(llvm::ArrayRef<CoreNote> notes) { thread_data.notes.push_back(note); } } break; + case llvm::Triple::x86: { + // Assume order PT_GETREGS, PT_GETFPREGS + if (note.info.n_type == NETBSD::I386::NT_REGS) { + // If this is the next thread, push the previous one first. + if (had_nt_regs) { + m_thread_data.push_back(thread_data); + thread_data = ThreadData(); + had_nt_regs = false; + } + + thread_data.gpregset = note.data; + thread_data.tid = tid; + if (thread_data.gpregset.GetByteSize() == 0) + return llvm::make_error<llvm::StringError>( + "Could not find general purpose registers note in core file.", + llvm::inconvertibleErrorCode()); + had_nt_regs = true; + } else if (note.info.n_type == NETBSD::I386::NT_FPREGS) { + if (!had_nt_regs || tid != thread_data.tid) + return llvm::make_error<llvm::StringError>( + "Error parsing NetBSD core(5) notes: Unexpected order " + "of NOTEs PT_GETFPREG before PT_GETREG", + llvm::inconvertibleErrorCode()); + thread_data.notes.push_back(note); + } + } break; case llvm::Triple::x86_64: { // Assume order PT_GETREGS, PT_GETFPREGS if (note.info.n_type == NETBSD::AMD64::NT_REGS) { diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp index 2f71f175a00d..f0aee04b5f62 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp @@ -25,7 +25,7 @@ RegisterContextCorePOSIX_arm::RegisterContextCorePOSIX_arm( m_gpr.SetByteOrder(gpregset.GetByteOrder()); } -RegisterContextCorePOSIX_arm::~RegisterContextCorePOSIX_arm() {} +RegisterContextCorePOSIX_arm::~RegisterContextCorePOSIX_arm() = default; bool RegisterContextCorePOSIX_arm::ReadGPR() { return true; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp index 129a887a550c..e56aa88b57d9 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp @@ -17,26 +17,52 @@ using namespace lldb_private; +std::unique_ptr<RegisterContextCorePOSIX_arm64> +RegisterContextCorePOSIX_arm64::Create(Thread &thread, const ArchSpec &arch, + const DataExtractor &gpregset, + llvm::ArrayRef<CoreNote> notes) { + Flags opt_regsets = RegisterInfoPOSIX_arm64::eRegsetMaskDefault; + + DataExtractor sve_data = getRegset(notes, arch.GetTriple(), AARCH64_SVE_Desc); + if (sve_data.GetByteSize() > sizeof(sve::user_sve_header)) + opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskSVE); + + // Pointer Authentication register set data is based on struct + // user_pac_mask declared in ptrace.h. See reference implementation + // in Linux kernel source at arch/arm64/include/uapi/asm/ptrace.h. + DataExtractor pac_data = getRegset(notes, arch.GetTriple(), AARCH64_PAC_Desc); + if (pac_data.GetByteSize() >= sizeof(uint64_t) * 2) + opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskPAuth); + + auto register_info_up = + std::make_unique<RegisterInfoPOSIX_arm64>(arch, opt_regsets); + return std::unique_ptr<RegisterContextCorePOSIX_arm64>( + new RegisterContextCorePOSIX_arm64(thread, std::move(register_info_up), + gpregset, notes)); +} + RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64( Thread &thread, std::unique_ptr<RegisterInfoPOSIX_arm64> register_info, const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes) : RegisterContextPOSIX_arm64(thread, std::move(register_info)) { - m_gpr_buffer = std::make_shared<DataBufferHeap>(gpregset.GetDataStart(), - gpregset.GetByteSize()); - m_gpr.SetData(m_gpr_buffer); - m_gpr.SetByteOrder(gpregset.GetByteOrder()); + m_gpr_data.SetData(std::make_shared<DataBufferHeap>(gpregset.GetDataStart(), + gpregset.GetByteSize())); + m_gpr_data.SetByteOrder(gpregset.GetByteOrder()); - m_fpregset = getRegset( - notes, m_register_info_up->GetTargetArchitecture().GetTriple(), FPR_Desc); + const llvm::Triple &target_triple = + m_register_info_up->GetTargetArchitecture().GetTriple(); + m_fpr_data = getRegset(notes, target_triple, FPR_Desc); - m_sveregset = - getRegset(notes, m_register_info_up->GetTargetArchitecture().GetTriple(), - AARCH64_SVE_Desc); + if (m_register_info_up->IsSVEEnabled()) + m_sve_data = getRegset(notes, target_triple, AARCH64_SVE_Desc); + + if (m_register_info_up->IsPAuthEnabled()) + m_pac_data = getRegset(notes, target_triple, AARCH64_PAC_Desc); ConfigureRegisterContext(); } -RegisterContextCorePOSIX_arm64::~RegisterContextCorePOSIX_arm64() {} +RegisterContextCorePOSIX_arm64::~RegisterContextCorePOSIX_arm64() = default; bool RegisterContextCorePOSIX_arm64::ReadGPR() { return true; } @@ -53,16 +79,16 @@ bool RegisterContextCorePOSIX_arm64::WriteFPR() { } const uint8_t *RegisterContextCorePOSIX_arm64::GetSVEBuffer(uint64_t offset) { - return m_sveregset.GetDataStart() + offset; + return m_sve_data.GetDataStart() + offset; } void RegisterContextCorePOSIX_arm64::ConfigureRegisterContext() { - if (m_sveregset.GetByteSize() > sizeof(sve::user_sve_header)) { + if (m_sve_data.GetByteSize() > sizeof(sve::user_sve_header)) { uint64_t sve_header_field_offset = 8; - m_sve_vector_length = m_sveregset.GetU16(&sve_header_field_offset); + m_sve_vector_length = m_sve_data.GetU16(&sve_header_field_offset); sve_header_field_offset = 12; uint16_t sve_header_flags_field = - m_sveregset.GetU16(&sve_header_field_offset); + m_sve_data.GetU16(&sve_header_field_offset); if ((sve_header_flags_field & sve::ptrace_regs_mask) == sve::ptrace_regs_fpsimd) m_sve_state = SVEState::FPSIMD; @@ -70,15 +96,16 @@ void RegisterContextCorePOSIX_arm64::ConfigureRegisterContext() { sve::ptrace_regs_sve) m_sve_state = SVEState::Full; - if (sve::vl_valid(m_sve_vector_length)) - m_register_info_up->ConfigureVectorRegisterInfos( - sve::vq_from_vl(m_sve_vector_length)); - else { + if (!sve::vl_valid(m_sve_vector_length)) { m_sve_state = SVEState::Disabled; m_sve_vector_length = 0; } } else m_sve_state = SVEState::Disabled; + + if (m_sve_state != SVEState::Disabled) + m_register_info_up->ConfigureVectorLength( + sve::vq_from_vl(m_sve_vector_length)); } uint32_t RegisterContextCorePOSIX_arm64::CalculateSVEOffset( @@ -104,7 +131,7 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info, offset = reg_info->byte_offset; if (offset + reg_info->byte_size <= GetGPRSize()) { - uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size); + uint64_t v = m_gpr_data.GetMaxU64(&offset, reg_info->byte_size); if (offset == reg_info->byte_offset + reg_info->byte_size) { value = v; return true; @@ -119,8 +146,8 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info, if (m_sve_state == SVEState::Disabled) { // SVE is disabled take legacy route for FPU register access offset -= GetGPRSize(); - if (offset < m_fpregset.GetByteSize()) { - value.SetFromMemoryData(reg_info, m_fpregset.GetDataStart() + offset, + if (offset < m_fpr_data.GetByteSize()) { + value.SetFromMemoryData(reg_info, m_fpr_data.GetDataStart() + offset, reg_info->byte_size, lldb::eByteOrderLittle, error); return error.Success(); @@ -152,7 +179,7 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info, } assert(sve_reg_num != LLDB_INVALID_REGNUM); - assert(offset < m_sveregset.GetByteSize()); + assert(offset < m_sve_data.GetByteSize()); value.SetFromMemoryData(reg_info, GetSVEBuffer(offset), reg_info->byte_size, lldb::eByteOrderLittle, error); @@ -174,7 +201,7 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info, if (IsSVEZ(reg)) { byte_size = 16; offset = CalculateSVEOffset(reg_info); - assert(offset < m_sveregset.GetByteSize()); + assert(offset < m_sve_data.GetByteSize()); src = GetSVEBuffer(offset); } value.SetFromMemoryData(reg_info, src, byte_size, lldb::eByteOrderLittle, @@ -182,7 +209,7 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info, } break; case SVEState::Full: offset = CalculateSVEOffset(reg_info); - assert(offset < m_sveregset.GetByteSize()); + assert(offset < m_sve_data.GetByteSize()); value.SetFromMemoryData(reg_info, GetSVEBuffer(offset), reg_info->byte_size, lldb::eByteOrderLittle, error); @@ -191,6 +218,11 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info, default: return false; } + } else if (IsPAuth(reg)) { + offset = reg_info->byte_offset - m_register_info_up->GetPAuthOffset(); + assert(offset < m_pac_data.GetByteSize()); + value.SetFromMemoryData(reg_info, m_pac_data.GetDataStart() + offset, + reg_info->byte_size, lldb::eByteOrderLittle, error); } else return false; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h index a4fdc4f14328..3988e3539b89 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h @@ -18,11 +18,10 @@ class RegisterContextCorePOSIX_arm64 : public RegisterContextPOSIX_arm64 { public: - RegisterContextCorePOSIX_arm64( - lldb_private::Thread &thread, - std::unique_ptr<RegisterInfoPOSIX_arm64> register_info, - const lldb_private::DataExtractor &gpregset, - llvm::ArrayRef<lldb_private::CoreNote> notes); + static std::unique_ptr<RegisterContextCorePOSIX_arm64> + Create(lldb_private::Thread &thread, const lldb_private::ArchSpec &arch, + const lldb_private::DataExtractor &gpregset, + llvm::ArrayRef<lldb_private::CoreNote> notes); ~RegisterContextCorePOSIX_arm64() override; @@ -39,6 +38,12 @@ public: bool HardwareSingleStep(bool enable) override; protected: + RegisterContextCorePOSIX_arm64( + lldb_private::Thread &thread, + std::unique_ptr<RegisterInfoPOSIX_arm64> register_info, + const lldb_private::DataExtractor &gpregset, + llvm::ArrayRef<lldb_private::CoreNote> notes); + bool ReadGPR() override; bool ReadFPR() override; @@ -48,10 +53,10 @@ protected: bool WriteFPR() override; private: - lldb::DataBufferSP m_gpr_buffer; - lldb_private::DataExtractor m_gpr; - lldb_private::DataExtractor m_fpregset; - lldb_private::DataExtractor m_sveregset; + lldb_private::DataExtractor m_gpr_data; + lldb_private::DataExtractor m_fpr_data; + lldb_private::DataExtractor m_sve_data; + lldb_private::DataExtractor m_pac_data; SVEState m_sve_state; uint16_t m_sve_vector_length = 0; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp index b5b83d899a44..5b1eb8b5437d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp @@ -32,7 +32,7 @@ RegisterContextCorePOSIX_mips64::RegisterContextCorePOSIX_mips64( m_fpr.SetByteOrder(fpregset.GetByteOrder()); } -RegisterContextCorePOSIX_mips64::~RegisterContextCorePOSIX_mips64() {} +RegisterContextCorePOSIX_mips64::~RegisterContextCorePOSIX_mips64() = default; bool RegisterContextCorePOSIX_mips64::ReadGPR() { return true; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp index e15cd47cd7da..8380731692a3 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp @@ -39,7 +39,7 @@ RegisterContextCorePOSIX_powerpc::RegisterContextCorePOSIX_powerpc( m_vec.SetByteOrder(vregset.GetByteOrder()); } -RegisterContextCorePOSIX_powerpc::~RegisterContextCorePOSIX_powerpc() {} +RegisterContextCorePOSIX_powerpc::~RegisterContextCorePOSIX_powerpc() = default; bool RegisterContextCorePOSIX_powerpc::ReadGPR() { return true; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp index c3aa92c9f86c..f1cd6897616d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp @@ -33,7 +33,7 @@ RegisterContextCorePOSIX_s390x::RegisterContextCorePOSIX_s390x( m_fpr.SetByteOrder(fpregset.GetByteOrder()); } -RegisterContextCorePOSIX_s390x::~RegisterContextCorePOSIX_s390x() {} +RegisterContextCorePOSIX_s390x::~RegisterContextCorePOSIX_s390x() = default; bool RegisterContextCorePOSIX_s390x::ReadGPR() { return true; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h index 25abd7ed54b7..f6a2fbdcc938 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h @@ -55,6 +55,10 @@ namespace AMD64 { enum { NT_REGS = 33, NT_FPREGS = 35 }; } +namespace I386 { +enum { NT_REGS = 33, NT_FPREGS = 35 }; +} + } // namespace NETBSD namespace OPENBSD { @@ -96,6 +100,9 @@ DataExtractor getRegset(llvm::ArrayRef<CoreNote> Notes, llvm::ArrayRef<RegsetDesc> RegsetDescs); constexpr RegsetDesc FPR_Desc[] = { + // FreeBSD/i386 core NT_FPREGSET is x87 FSAVE result but the XSAVE dump + // starts with FXSAVE struct, so use that instead if available. + {llvm::Triple::FreeBSD, llvm::Triple::x86, llvm::ELF::NT_X86_XSTATE}, {llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, llvm::ELF::NT_FPREGSET}, // In a i386 core file NT_FPREGSET is present, but it's not the result // of the FXSAVE instruction like in 64 bit files. @@ -103,6 +110,7 @@ constexpr RegsetDesc FPR_Desc[] = { {llvm::Triple::Linux, llvm::Triple::x86, llvm::ELF::NT_PRXFPREG}, {llvm::Triple::Linux, llvm::Triple::UnknownArch, llvm::ELF::NT_FPREGSET}, {llvm::Triple::NetBSD, llvm::Triple::aarch64, NETBSD::AARCH64::NT_FPREGS}, + {llvm::Triple::NetBSD, llvm::Triple::x86, NETBSD::I386::NT_FPREGS}, {llvm::Triple::NetBSD, llvm::Triple::x86_64, NETBSD::AMD64::NT_FPREGS}, {llvm::Triple::OpenBSD, llvm::Triple::UnknownArch, OPENBSD::NT_FPREGS}, }; @@ -111,6 +119,10 @@ constexpr RegsetDesc AARCH64_SVE_Desc[] = { {llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_SVE}, }; +constexpr RegsetDesc AARCH64_PAC_Desc[] = { + {llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_PAC_MASK}, +}; + constexpr RegsetDesc PPC_VMX_Desc[] = { {llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VMX}, {llvm::Triple::Linux, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VMX}, diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp index 6c3ee9debc7c..5086cfaa6536 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp @@ -18,12 +18,11 @@ #include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h" #include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h" #include "Plugins/Process/Utility/RegisterContextLinux_i386.h" -#include "Plugins/Process/Utility/RegisterContextLinux_mips.h" -#include "Plugins/Process/Utility/RegisterContextLinux_mips64.h" #ifdef LLDB_ENABLE_ALL #include "Plugins/Process/Utility/RegisterContextLinux_s390x.h" #endif // LLDB_ENABLE_ALL #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h" +#include "Plugins/Process/Utility/RegisterContextNetBSD_i386.h" #include "Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h" #include "Plugins/Process/Utility/RegisterContextOpenBSD_i386.h" #include "Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h" @@ -113,6 +112,9 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { switch (arch.GetMachine()) { case llvm::Triple::aarch64: break; + case llvm::Triple::x86: + reg_interface = new RegisterContextNetBSD_i386(arch); + break; case llvm::Triple::x86_64: reg_interface = new RegisterContextNetBSD_x86_64(arch); break; @@ -126,14 +128,6 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { switch (arch.GetMachine()) { case llvm::Triple::aarch64: break; - case llvm::Triple::mipsel: - case llvm::Triple::mips: - reg_interface = new RegisterContextLinux_mips(arch); - break; - case llvm::Triple::mips64el: - case llvm::Triple::mips64: - reg_interface = new RegisterContextLinux_mips64(arch); - break; case llvm::Triple::ppc64le: reg_interface = new RegisterInfoPOSIX_ppc64le(arch); break; @@ -183,9 +177,8 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { switch (arch.GetMachine()) { case llvm::Triple::aarch64: - m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_arm64>( - *this, std::make_unique<RegisterInfoPOSIX_arm64>(arch), - m_gpregset_data, m_notes); + m_thread_reg_ctx_sp = RegisterContextCorePOSIX_arm64::Create( + *this, arch, m_gpregset_data, m_notes); break; case llvm::Triple::arm: m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_arm>( diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp index fdaa60e2df41..a4c71e864a76 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp @@ -20,7 +20,10 @@ using namespace lldb_private; using namespace lldb_private::process_gdb_remote; using namespace std::chrono; -static const seconds kInterruptTimeout(5); +// When we've sent a continue packet and are waiting for the target to stop, +// we wake up the wait with this interval to make sure the stub hasn't gone +// away while we were waiting. +static const seconds kWakeupInterval(5); ///////////////////////// // GDBRemoteClientBase // @@ -35,7 +38,8 @@ GDBRemoteClientBase::GDBRemoteClientBase(const char *comm_name, StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse( ContinueDelegate &delegate, const UnixSignals &signals, - llvm::StringRef payload, StringExtractorGDBRemote &response) { + llvm::StringRef payload, std::chrono::seconds interrupt_timeout, + StringExtractorGDBRemote &response) { Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); response.Clear(); @@ -48,16 +52,37 @@ StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse( if (!cont_lock) return eStateInvalid; OnRunPacketSent(true); - + // The main ReadPacket loop wakes up at computed_timeout intervals, just to + // check that the connection hasn't dropped. When we wake up we also check + // whether there is an interrupt request that has reached its endpoint. + // If we want a shorter interrupt timeout that kWakeupInterval, we need to + // choose the shorter interval for the wake up as well. + std::chrono::seconds computed_timeout = std::min(interrupt_timeout, + kWakeupInterval); for (;;) { - PacketResult read_result = ReadPacket(response, kInterruptTimeout, false); + PacketResult read_result = ReadPacket(response, computed_timeout, false); + // Reset the computed_timeout to the default value in case we are going + // round again. + computed_timeout = std::min(interrupt_timeout, kWakeupInterval); switch (read_result) { case PacketResult::ErrorReplyTimeout: { std::lock_guard<std::mutex> lock(m_mutex); - if (m_async_count == 0) + if (m_async_count == 0) { continue; - if (steady_clock::now() >= m_interrupt_time + kInterruptTimeout) + } + auto cur_time = steady_clock::now(); + if (cur_time >= m_interrupt_endpoint) return eStateInvalid; + else { + // We woke up and found an interrupt is in flight, but we haven't + // exceeded the interrupt wait time. So reset the wait time to the + // time left till the interrupt timeout. But don't wait longer + // than our wakeup timeout. + auto new_wait = m_interrupt_endpoint - cur_time; + computed_timeout = std::min(kWakeupInterval, + std::chrono::duration_cast<std::chrono::seconds>(new_wait)); + continue; + } break; } case PacketResult::Success: @@ -133,8 +158,9 @@ StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse( } } -bool GDBRemoteClientBase::SendAsyncSignal(int signo) { - Lock lock(*this, true); +bool GDBRemoteClientBase::SendAsyncSignal( + int signo, std::chrono::seconds interrupt_timeout) { + Lock lock(*this, interrupt_timeout); if (!lock || !lock.DidInterrupt()) return false; @@ -144,25 +170,26 @@ bool GDBRemoteClientBase::SendAsyncSignal(int signo) { return true; } -bool GDBRemoteClientBase::Interrupt() { - Lock lock(*this, true); +bool GDBRemoteClientBase::Interrupt(std::chrono::seconds interrupt_timeout) { + Lock lock(*this, interrupt_timeout); if (!lock.DidInterrupt()) return false; m_should_stop = true; return true; } + GDBRemoteCommunication::PacketResult GDBRemoteClientBase::SendPacketAndWaitForResponse( llvm::StringRef payload, StringExtractorGDBRemote &response, - bool send_async) { - Lock lock(*this, send_async); + std::chrono::seconds interrupt_timeout) { + Lock lock(*this, interrupt_timeout); if (!lock) { if (Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)) LLDB_LOGF(log, "GDBRemoteClientBase::%s failed to get mutex, not sending " - "packet '%.*s' (send_async=%d)", - __FUNCTION__, int(payload.size()), payload.data(), send_async); + "packet '%.*s'", + __FUNCTION__, int(payload.size()), payload.data()); return PacketResult::ErrorSendFailed; } @@ -172,16 +199,16 @@ GDBRemoteClientBase::SendPacketAndWaitForResponse( GDBRemoteCommunication::PacketResult GDBRemoteClientBase::SendPacketAndReceiveResponseWithOutputSupport( llvm::StringRef payload, StringExtractorGDBRemote &response, - bool send_async, + std::chrono::seconds interrupt_timeout, llvm::function_ref<void(llvm::StringRef)> output_callback) { - Lock lock(*this, send_async); + Lock lock(*this, interrupt_timeout); if (!lock) { if (Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)) LLDB_LOGF(log, "GDBRemoteClientBase::%s failed to get mutex, not sending " - "packet '%.*s' (send_async=%d)", - __FUNCTION__, int(payload.size()), payload.data(), send_async); + "packet '%.*s'", + __FUNCTION__, int(payload.size()), payload.data()); return PacketResult::ErrorSendFailed; } @@ -222,13 +249,14 @@ GDBRemoteClientBase::SendPacketAndWaitForResponseNoLock( return packet_result; } -bool GDBRemoteClientBase::SendvContPacket(llvm::StringRef payload, - StringExtractorGDBRemote &response) { +bool GDBRemoteClientBase::SendvContPacket( + llvm::StringRef payload, std::chrono::seconds interrupt_timeout, + StringExtractorGDBRemote &response) { Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s ()", __FUNCTION__); // we want to lock down packet sending while we continue - Lock lock(*this, true); + Lock lock(*this, interrupt_timeout); LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s () sending vCont packet: %.*s", @@ -336,18 +364,20 @@ GDBRemoteClientBase::ContinueLock::lock() { // GDBRemoteClientBase::Lock // /////////////////////////////// -GDBRemoteClientBase::Lock::Lock(GDBRemoteClientBase &comm, bool interrupt) +GDBRemoteClientBase::Lock::Lock(GDBRemoteClientBase &comm, + std::chrono::seconds interrupt_timeout) : m_async_lock(comm.m_async_mutex, std::defer_lock), m_comm(comm), - m_acquired(false), m_did_interrupt(false) { - SyncWithContinueThread(interrupt); + m_interrupt_timeout(interrupt_timeout), m_acquired(false), + m_did_interrupt(false) { + SyncWithContinueThread(); if (m_acquired) m_async_lock.lock(); } -void GDBRemoteClientBase::Lock::SyncWithContinueThread(bool interrupt) { +void GDBRemoteClientBase::Lock::SyncWithContinueThread() { Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); std::unique_lock<std::mutex> lock(m_comm.m_mutex); - if (m_comm.m_is_running && !interrupt) + if (m_comm.m_is_running && m_interrupt_timeout == std::chrono::seconds(0)) return; // We were asked to avoid interrupting the sender. Lock is not // acquired. @@ -365,9 +395,9 @@ void GDBRemoteClientBase::Lock::SyncWithContinueThread(bool interrupt) { "interrupt packet"); return; } + m_comm.m_interrupt_endpoint = steady_clock::now() + m_interrupt_timeout; if (log) log->PutCString("GDBRemoteClientBase::Lock::Lock sent packet: \\x03"); - m_comm.m_interrupt_time = steady_clock::now(); } m_comm.m_cv.wait(lock, [this] { return !m_comm.m_is_running; }); m_did_interrupt = true; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h index cd9f6ebd7642..518b81318b6c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h @@ -33,29 +33,46 @@ public: GDBRemoteClientBase(const char *comm_name, const char *listener_name); - bool SendAsyncSignal(int signo); + bool SendAsyncSignal(int signo, std::chrono::seconds interrupt_timeout); - bool Interrupt(); + bool Interrupt(std::chrono::seconds interrupt_timeout); lldb::StateType SendContinuePacketAndWaitForResponse( ContinueDelegate &delegate, const UnixSignals &signals, - llvm::StringRef payload, StringExtractorGDBRemote &response); - - PacketResult SendPacketAndWaitForResponse(llvm::StringRef payload, - StringExtractorGDBRemote &response, - bool send_async); + llvm::StringRef payload, std::chrono::seconds interrupt_timeout, + StringExtractorGDBRemote &response); + + // If interrupt_timeout == 0 seconds, don't interrupt the target. + // Only send the packet if the target is stopped. + // If you want to use this mode, use the fact that the timeout is defaulted + // so it's clear from the call-site that you are using no-interrupt. + // If it is non-zero, interrupt the target if it is running, and + // send the packet. + // It the target doesn't respond within the given timeout, it returns + // ErrorReplyTimeout. + PacketResult SendPacketAndWaitForResponse( + llvm::StringRef payload, StringExtractorGDBRemote &response, + std::chrono::seconds interrupt_timeout = std::chrono::seconds(0)); PacketResult SendPacketAndReceiveResponseWithOutputSupport( llvm::StringRef payload, StringExtractorGDBRemote &response, - bool send_async, + std::chrono::seconds interrupt_timeout, llvm::function_ref<void(llvm::StringRef)> output_callback); bool SendvContPacket(llvm::StringRef payload, + std::chrono::seconds interrupt_timeout, StringExtractorGDBRemote &response); class Lock { public: - Lock(GDBRemoteClientBase &comm, bool interrupt); + // If interrupt_timeout == 0 seconds, only take the lock if the target is + // not running. If using this option, use the fact that the + // interrupt_timeout is defaulted so it will be obvious at the call site + // that you are choosing this mode. If it is non-zero, interrupt the target + // if it is running, waiting for the given timeout for the interrupt to + // succeed. + Lock(GDBRemoteClientBase &comm, + std::chrono::seconds interrupt_timeout = std::chrono::seconds(0)); ~Lock(); explicit operator bool() { return m_acquired; } @@ -67,10 +84,11 @@ public: private: std::unique_lock<std::recursive_mutex> m_async_lock; GDBRemoteClientBase &m_comm; + std::chrono::seconds m_interrupt_timeout; bool m_acquired; bool m_did_interrupt; - void SyncWithContinueThread(bool interrupt); + void SyncWithContinueThread(); }; protected: @@ -109,7 +127,7 @@ private: /// When was the interrupt packet sent. Used to make sure we time out if the /// stub does not respond to interrupt requests. - std::chrono::time_point<std::chrono::steady_clock> m_interrupt_time; + std::chrono::time_point<std::chrono::steady_clock> m_interrupt_endpoint; /// Number of threads interested in sending. uint32_t m_async_count; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index 4981345d6a18..013d407c0fc1 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -8,9 +8,9 @@ #include "GDBRemoteCommunication.h" +#include <climits> +#include <cstring> #include <future> -#include <limits.h> -#include <string.h> #include <sys/stat.h> #include "lldb/Core/StreamFile.h" diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index d375a312ae2c..b16aed4f5c90 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -8,7 +8,7 @@ #include "GDBRemoteCommunicationClient.h" -#include <math.h> +#include <cmath> #include <sys/stat.h> #include <numeric> @@ -16,6 +16,7 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Host/HostInfo.h" +#include "lldb/Host/StringConvert.h" #include "lldb/Host/XML.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Target/MemoryRegionInfo.h" @@ -55,40 +56,7 @@ llvm::raw_ostream &process_gdb_remote::operator<<(llvm::raw_ostream &os, // GDBRemoteCommunicationClient constructor GDBRemoteCommunicationClient::GDBRemoteCommunicationClient() : GDBRemoteClientBase("gdb-remote.client", "gdb-remote.client.rx_packet"), - m_supports_not_sending_acks(eLazyBoolCalculate), - m_supports_thread_suffix(eLazyBoolCalculate), - m_supports_threads_in_stop_reply(eLazyBoolCalculate), - m_supports_vCont_all(eLazyBoolCalculate), - m_supports_vCont_any(eLazyBoolCalculate), - m_supports_vCont_c(eLazyBoolCalculate), - m_supports_vCont_C(eLazyBoolCalculate), - m_supports_vCont_s(eLazyBoolCalculate), - m_supports_vCont_S(eLazyBoolCalculate), - m_qHostInfo_is_valid(eLazyBoolCalculate), - m_curr_pid_is_valid(eLazyBoolCalculate), - m_qProcessInfo_is_valid(eLazyBoolCalculate), - m_qGDBServerVersion_is_valid(eLazyBoolCalculate), - m_supports_alloc_dealloc_memory(eLazyBoolCalculate), - m_supports_memory_region_info(eLazyBoolCalculate), - m_supports_watchpoint_support_info(eLazyBoolCalculate), - m_supports_detach_stay_stopped(eLazyBoolCalculate), - m_watchpoints_trigger_after_instruction(eLazyBoolCalculate), - m_attach_or_wait_reply(eLazyBoolCalculate), - m_prepare_for_reg_writing_reply(eLazyBoolCalculate), - m_supports_p(eLazyBoolCalculate), m_supports_x(eLazyBoolCalculate), - m_avoid_g_packets(eLazyBoolCalculate), - m_supports_QSaveRegisterState(eLazyBoolCalculate), - m_supports_qXfer_auxv_read(eLazyBoolCalculate), - m_supports_qXfer_libraries_read(eLazyBoolCalculate), - m_supports_qXfer_libraries_svr4_read(eLazyBoolCalculate), - m_supports_qXfer_features_read(eLazyBoolCalculate), - m_supports_qXfer_memory_map_read(eLazyBoolCalculate), - m_supports_augmented_libraries_svr4_read(eLazyBoolCalculate), - m_supports_jThreadExtendedInfo(eLazyBoolCalculate), - m_supports_jLoadedDynamicLibrariesInfos(eLazyBoolCalculate), - m_supports_jGetSharedCacheInfo(eLazyBoolCalculate), - m_supports_QPassSignals(eLazyBoolCalculate), - m_supports_error_string_reply(eLazyBoolCalculate), + m_supports_qProcessInfoPID(true), m_supports_qfProcessInfo(true), m_supports_qUserName(true), m_supports_qGroupName(true), m_supports_qThreadStopInfo(true), m_supports_z0(true), @@ -97,15 +65,11 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient() m_supports_QEnvironmentHexEncoded(true), m_supports_qSymbol(true), m_qSymbol_requests_done(false), m_supports_qModuleInfo(true), m_supports_jThreadsInfo(true), m_supports_jModulesInfo(true), - m_curr_pid(LLDB_INVALID_PROCESS_ID), m_curr_tid(LLDB_INVALID_THREAD_ID), - m_curr_tid_run(LLDB_INVALID_THREAD_ID), - m_num_supported_hardware_watchpoints(0), m_host_arch(), m_process_arch(), - m_os_build(), m_os_kernel(), m_hostname(), m_gdb_server_name(), - m_gdb_server_version(UINT32_MAX), m_default_packet_timeout(0), - m_max_packet_size(0), m_qSupported_response(), - m_supported_async_json_packets_is_valid(false), - m_supported_async_json_packets_sp(), m_qXfer_memory_map(), - m_qXfer_memory_map_loaded(false) {} + + m_host_arch(), m_process_arch(), m_os_build(), m_os_kernel(), + m_hostname(), m_gdb_server_name(), m_default_packet_timeout(0), + m_qSupported_response(), m_supported_async_json_packets_sp(), + m_qXfer_memory_map() {} // Destructor GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient() { @@ -218,7 +182,7 @@ bool GDBRemoteCommunicationClient::QueryNoAckModeSupported() { ScopedTimeout timeout(*this, std::max(GetPacketTimeout(), seconds(6))); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false) == + if (SendPacketAndWaitForResponse("QStartNoAckMode", response) == PacketResult::Success) { if (response.IsOKResponse()) { m_send_acks = false; @@ -235,8 +199,8 @@ void GDBRemoteCommunicationClient::GetListThreadsInStopReplySupported() { m_supports_threads_in_stop_reply = eLazyBoolNo; StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response, - false) == PacketResult::Success) { + if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response) == + PacketResult::Success) { if (response.IsOKResponse()) m_supports_threads_in_stop_reply = eLazyBoolYes; } @@ -248,8 +212,8 @@ bool GDBRemoteCommunicationClient::GetVAttachOrWaitSupported() { m_attach_or_wait_reply = eLazyBoolNo; StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response, - false) == PacketResult::Success) { + if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response) == + PacketResult::Success) { if (response.IsOKResponse()) m_attach_or_wait_reply = eLazyBoolYes; } @@ -262,8 +226,8 @@ bool GDBRemoteCommunicationClient::GetSyncThreadStateSupported() { m_prepare_for_reg_writing_reply = eLazyBoolNo; StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response, - false) == PacketResult::Success) { + if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response) == + PacketResult::Success) { if (response.IsOKResponse()) m_prepare_for_reg_writing_reply = eLazyBoolYes; } @@ -292,6 +256,7 @@ void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) { m_prepare_for_reg_writing_reply = eLazyBoolCalculate; m_attach_or_wait_reply = eLazyBoolCalculate; m_avoid_g_packets = eLazyBoolCalculate; + m_supports_multiprocess = eLazyBoolCalculate; m_supports_qXfer_auxv_read = eLazyBoolCalculate; m_supports_qXfer_libraries_read = eLazyBoolCalculate; m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate; @@ -321,6 +286,7 @@ void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) { m_gdb_server_name.clear(); m_gdb_server_version = UINT32_MAX; m_default_packet_timeout = seconds(0); + m_target_vm_page_size = 0; m_max_packet_size = 0; m_qSupported_response.clear(); m_supported_async_json_packets_is_valid = false; @@ -342,11 +308,17 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() { m_supports_augmented_libraries_svr4_read = eLazyBoolNo; m_supports_qXfer_features_read = eLazyBoolNo; m_supports_qXfer_memory_map_read = eLazyBoolNo; + m_supports_multiprocess = eLazyBoolNo; + m_supports_qEcho = eLazyBoolNo; + m_supports_QPassSignals = eLazyBoolNo; + m_supports_memory_tagging = eLazyBoolNo; + m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if // not, we assume no limit // build the qSupported packet - std::vector<std::string> features = {"xmlRegisters=i386,arm,mips,arc"}; + std::vector<std::string> features = {"xmlRegisters=i386,arm,mips,arc", + "multiprocess+"}; StreamString packet; packet.PutCString("qSupported"); for (uint32_t i = 0; i < features.size(); ++i) { @@ -355,97 +327,57 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() { } StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(packet.GetString(), response, - /*send_async=*/false) == + if (SendPacketAndWaitForResponse(packet.GetString(), response) == PacketResult::Success) { - const char *response_cstr = response.GetStringRef().data(); - // Hang on to the qSupported packet, so that platforms can do custom // configuration of the transport before attaching/launching the process. - m_qSupported_response = response_cstr; - - if (::strstr(response_cstr, "qXfer:auxv:read+")) - m_supports_qXfer_auxv_read = eLazyBoolYes; - if (::strstr(response_cstr, "qXfer:libraries-svr4:read+")) - m_supports_qXfer_libraries_svr4_read = eLazyBoolYes; - if (::strstr(response_cstr, "augmented-libraries-svr4-read")) { - m_supports_qXfer_libraries_svr4_read = eLazyBoolYes; // implied - m_supports_augmented_libraries_svr4_read = eLazyBoolYes; - } - if (::strstr(response_cstr, "qXfer:libraries:read+")) - m_supports_qXfer_libraries_read = eLazyBoolYes; - if (::strstr(response_cstr, "qXfer:features:read+")) - m_supports_qXfer_features_read = eLazyBoolYes; - if (::strstr(response_cstr, "qXfer:memory-map:read+")) - m_supports_qXfer_memory_map_read = eLazyBoolYes; - - // Look for a list of compressions in the features list e.g. - // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib- - // deflate,lzma - const char *features_list = ::strstr(response_cstr, "qXfer:features:"); - if (features_list) { - const char *compressions = - ::strstr(features_list, "SupportedCompressions="); - if (compressions) { - std::vector<std::string> supported_compressions; - compressions += sizeof("SupportedCompressions=") - 1; - const char *end_of_compressions = strchr(compressions, ';'); - if (end_of_compressions == nullptr) { - end_of_compressions = strchr(compressions, '\0'); - } - const char *current_compression = compressions; - while (current_compression < end_of_compressions) { - const char *next_compression_name = strchr(current_compression, ','); - const char *end_of_this_word = next_compression_name; - if (next_compression_name == nullptr || - end_of_compressions < next_compression_name) { - end_of_this_word = end_of_compressions; - } - - if (end_of_this_word) { - if (end_of_this_word == current_compression) { - current_compression++; - } else { - std::string this_compression( - current_compression, end_of_this_word - current_compression); - supported_compressions.push_back(this_compression); - current_compression = end_of_this_word + 1; - } - } else { - supported_compressions.push_back(current_compression); - current_compression = end_of_compressions; - } - } - - if (supported_compressions.size() > 0) { - MaybeEnableCompression(supported_compressions); + m_qSupported_response = response.GetStringRef().str(); + + llvm::SmallVector<llvm::StringRef, 16> server_features; + response.GetStringRef().split(server_features, ';'); + + for (llvm::StringRef x : server_features) { + if (x == "qXfer:auxv:read+") + m_supports_qXfer_auxv_read = eLazyBoolYes; + else if (x == "qXfer:libraries-svr4:read+") + m_supports_qXfer_libraries_svr4_read = eLazyBoolYes; + else if (x == "augmented-libraries-svr4-read") { + m_supports_qXfer_libraries_svr4_read = eLazyBoolYes; // implied + m_supports_augmented_libraries_svr4_read = eLazyBoolYes; + } else if (x == "qXfer:libraries:read+") + m_supports_qXfer_libraries_read = eLazyBoolYes; + else if (x == "qXfer:features:read+") + m_supports_qXfer_features_read = eLazyBoolYes; + else if (x == "qXfer:memory-map:read+") + m_supports_qXfer_memory_map_read = eLazyBoolYes; + else if (x == "qEcho") + m_supports_qEcho = eLazyBoolYes; + else if (x == "QPassSignals+") + m_supports_QPassSignals = eLazyBoolYes; + else if (x == "multiprocess+") + m_supports_multiprocess = eLazyBoolYes; + else if (x == "memory-tagging+") + m_supports_memory_tagging = eLazyBoolYes; + // Look for a list of compressions in the features list e.g. + // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib- + // deflate,lzma + else if (x.consume_front("SupportedCompressions=")) { + llvm::SmallVector<llvm::StringRef, 4> compressions; + x.split(compressions, ','); + if (!compressions.empty()) + MaybeEnableCompression(compressions); + } else if (x.consume_front("PacketSize=")) { + StringExtractorGDBRemote packet_response(x); + m_max_packet_size = + packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX); + if (m_max_packet_size == 0) { + m_max_packet_size = UINT64_MAX; // Must have been a garbled response + Log *log( + ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); + LLDB_LOGF(log, "Garbled PacketSize spec in qSupported response"); } } } - - if (::strstr(response_cstr, "qEcho")) - m_supports_qEcho = eLazyBoolYes; - else - m_supports_qEcho = eLazyBoolNo; - - if (::strstr(response_cstr, "QPassSignals+")) - m_supports_QPassSignals = eLazyBoolYes; - else - m_supports_QPassSignals = eLazyBoolNo; - - const char *packet_size_str = ::strstr(response_cstr, "PacketSize="); - if (packet_size_str) { - StringExtractorGDBRemote packet_response(packet_size_str + - strlen("PacketSize=")); - m_max_packet_size = - packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX); - if (m_max_packet_size == 0) { - m_max_packet_size = UINT64_MAX; // Must have been a garbled response - Log *log( - ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - LLDB_LOGF(log, "Garbled PacketSize spec in qSupported response"); - } - } } } @@ -453,8 +385,8 @@ bool GDBRemoteCommunicationClient::GetThreadSuffixSupported() { if (m_supports_thread_suffix == eLazyBoolCalculate) { StringExtractorGDBRemote response; m_supports_thread_suffix = eLazyBoolNo; - if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, - false) == PacketResult::Success) { + if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response) == + PacketResult::Success) { if (response.IsOKResponse()) m_supports_thread_suffix = eLazyBoolYes; } @@ -470,7 +402,7 @@ bool GDBRemoteCommunicationClient::GetVContSupported(char flavor) { m_supports_vCont_C = eLazyBoolNo; m_supports_vCont_s = eLazyBoolNo; m_supports_vCont_S = eLazyBoolNo; - if (SendPacketAndWaitForResponse("vCont?", response, false) == + if (SendPacketAndWaitForResponse("vCont?", response) == PacketResult::Success) { const char *response_cstr = response.GetStringRef().data(); if (::strstr(response_cstr, ";c")) @@ -522,9 +454,9 @@ bool GDBRemoteCommunicationClient::GetVContSupported(char flavor) { GDBRemoteCommunication::PacketResult GDBRemoteCommunicationClient::SendThreadSpecificPacketAndWaitForResponse( - lldb::tid_t tid, StreamString &&payload, StringExtractorGDBRemote &response, - bool send_async) { - Lock lock(*this, send_async); + lldb::tid_t tid, StreamString &&payload, + StringExtractorGDBRemote &response) { + Lock lock(*this); if (!lock) { if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet( GDBR_LOG_PROCESS | GDBR_LOG_PACKETS)) @@ -561,7 +493,7 @@ LazyBool GDBRemoteCommunicationClient::GetThreadPacketSupported( payload.PutCString(packetStr); StringExtractorGDBRemote response; if (SendThreadSpecificPacketAndWaitForResponse( - tid, std::move(payload), response, false) == PacketResult::Success && + tid, std::move(payload), response) == PacketResult::Success && response.IsNormalResponse()) { return eLazyBoolYes; } @@ -575,7 +507,7 @@ StructuredData::ObjectSP GDBRemoteCommunicationClient::GetThreadsInfo() { if (m_supports_jThreadsInfo) { StringExtractorGDBRemote response; response.SetResponseValidatorToJSON(); - if (SendPacketAndWaitForResponse("jThreadsInfo", response, false) == + if (SendPacketAndWaitForResponse("jThreadsInfo", response) == PacketResult::Success) { if (response.IsUnsupportedResponse()) { m_supports_jThreadsInfo = false; @@ -592,7 +524,7 @@ bool GDBRemoteCommunicationClient::GetThreadExtendedInfoSupported() { if (m_supports_jThreadExtendedInfo == eLazyBoolCalculate) { StringExtractorGDBRemote response; m_supports_jThreadExtendedInfo = eLazyBoolNo; - if (SendPacketAndWaitForResponse("jThreadExtendedInfo:", response, false) == + if (SendPacketAndWaitForResponse("jThreadExtendedInfo:", response) == PacketResult::Success) { if (response.IsOKResponse()) { m_supports_jThreadExtendedInfo = eLazyBoolYes; @@ -608,7 +540,7 @@ void GDBRemoteCommunicationClient::EnableErrorStringInPacket() { // We try to enable error strings in remote packets but if we fail, we just // work in the older way. m_supports_error_string_reply = eLazyBoolNo; - if (SendPacketAndWaitForResponse("QEnableErrorStrings", response, false) == + if (SendPacketAndWaitForResponse("QEnableErrorStrings", response) == PacketResult::Success) { if (response.IsOKResponse()) { m_supports_error_string_reply = eLazyBoolYes; @@ -622,8 +554,7 @@ bool GDBRemoteCommunicationClient::GetLoadedDynamicLibrariesInfosSupported() { StringExtractorGDBRemote response; m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolNo; if (SendPacketAndWaitForResponse("jGetLoadedDynamicLibrariesInfos:", - response, - false) == PacketResult::Success) { + response) == PacketResult::Success) { if (response.IsOKResponse()) { m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolYes; } @@ -636,7 +567,7 @@ bool GDBRemoteCommunicationClient::GetSharedCacheInfoSupported() { if (m_supports_jGetSharedCacheInfo == eLazyBoolCalculate) { StringExtractorGDBRemote response; m_supports_jGetSharedCacheInfo = eLazyBoolNo; - if (SendPacketAndWaitForResponse("jGetSharedCacheInfo:", response, false) == + if (SendPacketAndWaitForResponse("jGetSharedCacheInfo:", response) == PacketResult::Success) { if (response.IsOKResponse()) { m_supports_jGetSharedCacheInfo = eLazyBoolYes; @@ -646,13 +577,82 @@ bool GDBRemoteCommunicationClient::GetSharedCacheInfoSupported() { return m_supports_jGetSharedCacheInfo; } +bool GDBRemoteCommunicationClient::GetMemoryTaggingSupported() { + if (m_supports_memory_tagging == eLazyBoolCalculate) { + GetRemoteQSupported(); + } + return m_supports_memory_tagging == eLazyBoolYes; +} + +DataBufferSP GDBRemoteCommunicationClient::ReadMemoryTags(lldb::addr_t addr, + size_t len, + int32_t type) { + StreamString packet; + packet.Printf("qMemTags:%" PRIx64 ",%zx:%" PRIx32, addr, len, type); + StringExtractorGDBRemote response; + + Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_MEMORY); + + if (SendPacketAndWaitForResponse(packet.GetString(), response) != + PacketResult::Success || + !response.IsNormalResponse()) { + LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s: qMemTags packet failed", + __FUNCTION__); + return nullptr; + } + + // We are expecting + // m<hex encoded bytes> + + if (response.GetChar() != 'm') { + LLDB_LOGF(log, + "GDBRemoteCommunicationClient::%s: qMemTags response did not " + "begin with \"m\"", + __FUNCTION__); + return nullptr; + } + + size_t expected_bytes = response.GetBytesLeft() / 2; + DataBufferSP buffer_sp(new DataBufferHeap(expected_bytes, 0)); + size_t got_bytes = response.GetHexBytesAvail(buffer_sp->GetData()); + // Check both because in some situations chars are consumed even + // if the decoding fails. + if (response.GetBytesLeft() || (expected_bytes != got_bytes)) { + LLDB_LOGF( + log, + "GDBRemoteCommunicationClient::%s: Invalid data in qMemTags response", + __FUNCTION__); + return nullptr; + } + + return buffer_sp; +} + +Status GDBRemoteCommunicationClient::WriteMemoryTags( + lldb::addr_t addr, size_t len, int32_t type, + const std::vector<uint8_t> &tags) { + // Format QMemTags:address,length:type:tags + StreamString packet; + packet.Printf("QMemTags:%" PRIx64 ",%zx:%" PRIx32 ":", addr, len, type); + packet.PutBytesAsRawHex8(tags.data(), tags.size()); + + Status status; + StringExtractorGDBRemote response; + if (SendPacketAndWaitForResponse(packet.GetString(), response) != + PacketResult::Success || + !response.IsOKResponse()) { + status.SetErrorString("QMemTags packet failed"); + } + return status; +} + bool GDBRemoteCommunicationClient::GetxPacketSupported() { if (m_supports_x == eLazyBoolCalculate) { StringExtractorGDBRemote response; m_supports_x = eLazyBoolNo; char packet[256]; snprintf(packet, sizeof(packet), "x0,0"); - if (SendPacketAndWaitForResponse(packet, response, false) == + if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success) { if (response.IsOKResponse()) m_supports_x = eLazyBoolYes; @@ -664,7 +664,7 @@ bool GDBRemoteCommunicationClient::GetxPacketSupported() { GDBRemoteCommunicationClient::PacketResult GDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses( const char *payload_prefix, std::string &response_string) { - Lock lock(*this, false); + Lock lock(*this); if (!lock) { Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS | GDBR_LOG_PACKETS)); @@ -725,11 +725,11 @@ lldb::pid_t GDBRemoteCommunicationClient::GetCurrentProcessID(bool allow_lazy) { // the thread id, which newer debugserver and lldb-gdbserver stubs return // correctly. StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse("qC", response, false) == - PacketResult::Success) { + if (SendPacketAndWaitForResponse("qC", response) == PacketResult::Success) { if (response.GetChar() == 'Q') { if (response.GetChar() == 'C') { - m_curr_pid = response.GetHexMaxU32(false, LLDB_INVALID_PROCESS_ID); + m_curr_pid_run = m_curr_pid = + response.GetHexMaxU64(false, LLDB_INVALID_PROCESS_ID); if (m_curr_pid != LLDB_INVALID_PROCESS_ID) { m_curr_pid_is_valid = eLazyBoolYes; return m_curr_pid; @@ -741,12 +741,14 @@ lldb::pid_t GDBRemoteCommunicationClient::GetCurrentProcessID(bool allow_lazy) { // If we don't get a response for $qC, check if $qfThreadID gives us a // result. if (m_curr_pid == LLDB_INVALID_PROCESS_ID) { - std::vector<lldb::tid_t> thread_ids; bool sequence_mutex_unavailable; - size_t size; - size = GetCurrentThreadIDs(thread_ids, sequence_mutex_unavailable); - if (size && !sequence_mutex_unavailable) { - m_curr_pid = thread_ids.front(); + auto ids = GetCurrentProcessAndThreadIDs(sequence_mutex_unavailable); + if (!ids.empty() && !sequence_mutex_unavailable) { + // If server returned an explicit PID, use that. + m_curr_pid_run = m_curr_pid = ids.front().first; + // Otherwise, use the TID of the first thread (Linux hack). + if (m_curr_pid == LLDB_INVALID_PROCESS_ID) + m_curr_pid_run = m_curr_pid = ids.front().second; m_curr_pid_is_valid = eLazyBoolYes; return m_curr_pid; } @@ -759,7 +761,7 @@ lldb::pid_t GDBRemoteCommunicationClient::GetCurrentProcessID(bool allow_lazy) { bool GDBRemoteCommunicationClient::GetLaunchSuccess(std::string &error_str) { error_str.clear(); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse("qLaunchSuccess", response, false) == + if (SendPacketAndWaitForResponse("qLaunchSuccess", response) == PacketResult::Success) { if (response.IsOKResponse()) return true; @@ -813,7 +815,7 @@ int GDBRemoteCommunicationClient::SendArgumentsPacket( } StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(packet.GetString(), response, false) == + if (SendPacketAndWaitForResponse(packet.GetString(), response) == PacketResult::Success) { if (response.IsOKResponse()) return 0; @@ -863,7 +865,7 @@ int GDBRemoteCommunicationClient::SendEnvironmentPacket( if (m_supports_QEnvironmentHexEncoded) { packet.PutCString("QEnvironmentHexEncoded:"); packet.PutBytesAsRawHex8(name_equal_value, strlen(name_equal_value)); - if (SendPacketAndWaitForResponse(packet.GetString(), response, false) == + if (SendPacketAndWaitForResponse(packet.GetString(), response) == PacketResult::Success) { if (response.IsOKResponse()) return 0; @@ -877,7 +879,7 @@ int GDBRemoteCommunicationClient::SendEnvironmentPacket( } else if (m_supports_QEnvironment) { packet.Printf("QEnvironment:%s", name_equal_value); - if (SendPacketAndWaitForResponse(packet.GetString(), response, false) == + if (SendPacketAndWaitForResponse(packet.GetString(), response) == PacketResult::Success) { if (response.IsOKResponse()) return 0; @@ -897,7 +899,7 @@ int GDBRemoteCommunicationClient::SendLaunchArchPacket(char const *arch) { StreamString packet; packet.Printf("QLaunchArch:%s", arch); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(packet.GetString(), response, false) == + if (SendPacketAndWaitForResponse(packet.GetString(), response) == PacketResult::Success) { if (response.IsOKResponse()) return 0; @@ -915,7 +917,7 @@ int GDBRemoteCommunicationClient::SendLaunchEventDataPacket( StreamString packet; packet.Printf("QSetProcessEvent:%s", data); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(packet.GetString(), response, false) == + if (SendPacketAndWaitForResponse(packet.GetString(), response) == PacketResult::Success) { if (response.IsOKResponse()) { if (was_supported) @@ -1000,7 +1002,7 @@ bool GDBRemoteCommunicationClient::GetGDBServerVersion() { m_qGDBServerVersion_is_valid = eLazyBoolNo; StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse("qGDBServerVersion", response, false) == + if (SendPacketAndWaitForResponse("qGDBServerVersion", response) == PacketResult::Success) { if (response.IsNormalResponse()) { llvm::StringRef name, value; @@ -1025,9 +1027,9 @@ bool GDBRemoteCommunicationClient::GetGDBServerVersion() { } void GDBRemoteCommunicationClient::MaybeEnableCompression( - std::vector<std::string> supported_compressions) { + llvm::ArrayRef<llvm::StringRef> supported_compressions) { CompressionType avail_type = CompressionType::None; - std::string avail_name; + llvm::StringRef avail_name; #if defined(HAVE_LIBCOMPRESSION) if (avail_type == CompressionType::None) { @@ -1091,8 +1093,8 @@ void GDBRemoteCommunicationClient::MaybeEnableCompression( if (avail_type != CompressionType::None) { StringExtractorGDBRemote response; - std::string packet = "QEnableCompression:type:" + avail_name + ";"; - if (SendPacketAndWaitForResponse(packet, response, false) != + llvm::Twine packet = "QEnableCompression:type:" + avail_name + ";"; + if (SendPacketAndWaitForResponse(packet.str(), response) != PacketResult::Success) return; @@ -1118,15 +1120,29 @@ uint32_t GDBRemoteCommunicationClient::GetGDBServerProgramVersion() { bool GDBRemoteCommunicationClient::GetDefaultThreadId(lldb::tid_t &tid) { StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse("qC", response, false) != - PacketResult::Success) + if (SendPacketAndWaitForResponse("qC", response) != PacketResult::Success) return false; if (!response.IsNormalResponse()) return false; - if (response.GetChar() == 'Q' && response.GetChar() == 'C') - tid = response.GetHexMaxU32(true, -1); + if (response.GetChar() == 'Q' && response.GetChar() == 'C') { + auto pid_tid = response.GetPidTid(0); + if (!pid_tid) + return false; + + lldb::pid_t pid = pid_tid->first; + // invalid + if (pid == StringExtractorGDBRemote::AllProcesses) + return false; + + // if we get pid as well, update m_curr_pid + if (pid != 0) { + m_curr_pid_run = m_curr_pid = pid; + m_curr_pid_is_valid = eLazyBoolYes; + } + tid = pid_tid->second; + } return true; } @@ -1154,7 +1170,7 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) { ScopedTimeout timeout(*this, seconds(10)); m_qHostInfo_is_valid = eLazyBoolNo; StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse("qHostInfo", response, false) == + if (SendPacketAndWaitForResponse("qHostInfo", response) == PacketResult::Success) { if (response.IsNormalResponse()) { llvm::StringRef name; @@ -1219,11 +1235,13 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) { } else if (name.equals("ptrsize")) { if (!value.getAsInteger(0, pointer_byte_size)) ++num_keys_decoded; + } else if (name.equals("addressing_bits")) { + if (!value.getAsInteger(0, m_addressing_bits)) + ++num_keys_decoded; } else if (name.equals("os_version") || - name.equals( - "version")) // Older debugserver binaries used the - // "version" key instead of - // "os_version"... + name.equals("version")) // Older debugserver binaries used + // the "version" key instead of + // "os_version"... { if (!m_os_version.tryParse(value)) ++num_keys_decoded; @@ -1245,6 +1263,12 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) { SetPacketTimeout(m_default_packet_timeout); ++num_keys_decoded; } + } else if (name.equals("vm-page-size")) { + int page_size; + if (!value.getAsInteger(0, page_size)) { + m_target_vm_page_size = page_size; + ++num_keys_decoded; + } } } @@ -1344,7 +1368,7 @@ int GDBRemoteCommunicationClient::SendAttach( ::snprintf(packet, sizeof(packet), "vAttach;%" PRIx64, pid); UNUSED_IF_ASSERT_DISABLED(packet_len); assert(packet_len < (int)sizeof(packet)); - if (SendPacketAndWaitForResponse(packet, response, false) == + if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success) { if (response.IsErrorResponse()) return response.GetError(); @@ -1360,7 +1384,7 @@ int GDBRemoteCommunicationClient::SendStdinNotification(const char *data, packet.PutCString("I"); packet.PutBytesAsRawHex8(data, data_len); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(packet.GetString(), response, false) == + if (SendPacketAndWaitForResponse(packet.GetString(), response) == PacketResult::Success) { return 0; } @@ -1374,6 +1398,11 @@ GDBRemoteCommunicationClient::GetHostArchitecture() { return m_host_arch; } +uint32_t GDBRemoteCommunicationClient::GetAddressingBits() { + if (m_qHostInfo_is_valid == eLazyBoolCalculate) + GetHostInfo(); + return m_addressing_bits; +} seconds GDBRemoteCommunicationClient::GetHostDefaultPacketTimeout() { if (m_qHostInfo_is_valid == eLazyBoolCalculate) GetHostInfo(); @@ -1393,7 +1422,7 @@ addr_t GDBRemoteCommunicationClient::AllocateMemory(size_t size, assert(packet_len < (int)sizeof(packet)); UNUSED_IF_ASSERT_DISABLED(packet_len); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(packet, response, false) == + if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success) { if (response.IsUnsupportedResponse()) m_supports_alloc_dealloc_memory = eLazyBoolNo; @@ -1415,7 +1444,7 @@ bool GDBRemoteCommunicationClient::DeallocateMemory(addr_t addr) { assert(packet_len < (int)sizeof(packet)); UNUSED_IF_ASSERT_DISABLED(packet_len); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(packet, response, false) == + if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success) { if (response.IsUnsupportedResponse()) m_supports_alloc_dealloc_memory = eLazyBoolNo; @@ -1439,7 +1468,7 @@ Status GDBRemoteCommunicationClient::Detach(bool keep_stopped) { assert(packet_len < (int)sizeof(packet)); UNUSED_IF_ASSERT_DISABLED(packet_len); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(packet, response, false) == + if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success && response.IsOKResponse()) { m_supports_detach_stay_stopped = eLazyBoolYes; @@ -1453,15 +1482,13 @@ Status GDBRemoteCommunicationClient::Detach(bool keep_stopped) { return error; } else { StringExtractorGDBRemote response; - PacketResult packet_result = - SendPacketAndWaitForResponse("D1", response, false); + PacketResult packet_result = SendPacketAndWaitForResponse("D1", response); if (packet_result != PacketResult::Success) error.SetErrorString("Sending extended disconnect packet failed."); } } else { StringExtractorGDBRemote response; - PacketResult packet_result = - SendPacketAndWaitForResponse("D", response, false); + PacketResult packet_result = SendPacketAndWaitForResponse("D", response); if (packet_result != PacketResult::Success) error.SetErrorString("Sending disconnect packet failed."); } @@ -1481,7 +1508,7 @@ Status GDBRemoteCommunicationClient::GetMemoryRegionInfo( assert(packet_len < (int)sizeof(packet)); UNUSED_IF_ASSERT_DISABLED(packet_len); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(packet, response, false) == + if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success && response.GetResponseType() == StringExtractorGDBRemote::eResponse) { llvm::StringRef name; @@ -1551,9 +1578,30 @@ Status GDBRemoteCommunicationClient::GetMemoryRegionInfo( // Now convert the HEX bytes into a string value error_extractor.GetHexByteString(error_string); error.SetErrorString(error_string.c_str()); + } else if (name.equals("dirty-pages")) { + std::vector<addr_t> dirty_page_list; + std::string comma_sep_str = value.str(); + size_t comma_pos; + addr_t page; + while ((comma_pos = comma_sep_str.find(',')) != std::string::npos) { + comma_sep_str[comma_pos] = '\0'; + page = StringConvert::ToUInt64(comma_sep_str.c_str(), + LLDB_INVALID_ADDRESS, 16); + if (page != LLDB_INVALID_ADDRESS) + dirty_page_list.push_back(page); + comma_sep_str.erase(0, comma_pos + 1); + } + page = StringConvert::ToUInt64(comma_sep_str.c_str(), + LLDB_INVALID_ADDRESS, 16); + if (page != LLDB_INVALID_ADDRESS) + dirty_page_list.push_back(page); + region_info.SetDirtyPageList(dirty_page_list); } } + if (m_target_vm_page_size != 0) + region_info.SetPageSize(m_target_vm_page_size); + if (region_info.GetRange().IsValid()) { // We got a valid address range back but no permissions -- which means // this is an unmapped page @@ -1718,8 +1766,8 @@ Status GDBRemoteCommunicationClient::GetWatchpointSupportInfo(uint32_t &num) { num = 0; if (m_supports_watchpoint_support_info != eLazyBoolNo) { StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse("qWatchpointSupportInfo:", response, - false) == PacketResult::Success) { + if (SendPacketAndWaitForResponse("qWatchpointSupportInfo:", response) == + PacketResult::Success) { m_supports_watchpoint_support_info = eLazyBoolYes; llvm::StringRef name; llvm::StringRef value; @@ -1787,7 +1835,7 @@ int GDBRemoteCommunicationClient::SetSTDIN(const FileSpec &file_spec) { packet.PutStringAsRawHex8(path); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(packet.GetString(), response, false) == + if (SendPacketAndWaitForResponse(packet.GetString(), response) == PacketResult::Success) { if (response.IsOKResponse()) return 0; @@ -1807,7 +1855,7 @@ int GDBRemoteCommunicationClient::SetSTDOUT(const FileSpec &file_spec) { packet.PutStringAsRawHex8(path); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(packet.GetString(), response, false) == + if (SendPacketAndWaitForResponse(packet.GetString(), response) == PacketResult::Success) { if (response.IsOKResponse()) return 0; @@ -1827,7 +1875,7 @@ int GDBRemoteCommunicationClient::SetSTDERR(const FileSpec &file_spec) { packet.PutStringAsRawHex8(path); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(packet.GetString(), response, false) == + if (SendPacketAndWaitForResponse(packet.GetString(), response) == PacketResult::Success) { if (response.IsOKResponse()) return 0; @@ -1841,7 +1889,7 @@ int GDBRemoteCommunicationClient::SetSTDERR(const FileSpec &file_spec) { bool GDBRemoteCommunicationClient::GetWorkingDir(FileSpec &working_dir) { StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse("qGetWorkingDir", response, false) == + if (SendPacketAndWaitForResponse("qGetWorkingDir", response) == PacketResult::Success) { if (response.IsUnsupportedResponse()) return false; @@ -1863,7 +1911,7 @@ int GDBRemoteCommunicationClient::SetWorkingDir(const FileSpec &working_dir) { packet.PutStringAsRawHex8(path); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(packet.GetString(), response, false) == + if (SendPacketAndWaitForResponse(packet.GetString(), response) == PacketResult::Success) { if (response.IsOKResponse()) return 0; @@ -1882,8 +1930,7 @@ int GDBRemoteCommunicationClient::SetDisableASLR(bool enable) { assert(packet_len < (int)sizeof(packet)); UNUSED_IF_ASSERT_DISABLED(packet_len); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(packet, response, false) == - PacketResult::Success) { + if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success) { if (response.IsOKResponse()) return 0; uint8_t error = response.GetError(); @@ -1900,8 +1947,7 @@ int GDBRemoteCommunicationClient::SetDetachOnError(bool enable) { assert(packet_len < (int)sizeof(packet)); UNUSED_IF_ASSERT_DISABLED(packet_len); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(packet, response, false) == - PacketResult::Success) { + if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success) { if (response.IsOKResponse()) return 0; uint8_t error = response.GetError(); @@ -2019,7 +2065,7 @@ bool GDBRemoteCommunicationClient::GetProcessInfo( assert(packet_len < (int)sizeof(packet)); UNUSED_IF_ASSERT_DISABLED(packet_len); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(packet, response, false) == + if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success) { return DecodeProcessInfoResponse(response, process_info); } else { @@ -2044,7 +2090,7 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) { GetHostInfo(); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse("qProcessInfo", response, false) == + if (SendPacketAndWaitForResponse("qProcessInfo", response) == PacketResult::Success) { if (response.IsNormalResponse()) { llvm::StringRef name; @@ -2102,7 +2148,7 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) { m_qProcessInfo_is_valid = eLazyBoolYes; if (pid != LLDB_INVALID_PROCESS_ID) { m_curr_pid_is_valid = eLazyBoolYes; - m_curr_pid = pid; + m_curr_pid_run = m_curr_pid = pid; } // Set the ArchSpec from the triple if we have it. @@ -2240,7 +2286,7 @@ uint32_t GDBRemoteCommunicationClient::FindProcesses( // Increase timeout as the first qfProcessInfo packet takes a long time on // Android. The value of 1min was arrived at empirically. ScopedTimeout timeout(*this, minutes(1)); - if (SendPacketAndWaitForResponse(packet.GetString(), response, false) == + if (SendPacketAndWaitForResponse(packet.GetString(), response) == PacketResult::Success) { do { ProcessInstanceInfo process_info; @@ -2248,7 +2294,7 @@ uint32_t GDBRemoteCommunicationClient::FindProcesses( break; process_infos.push_back(process_info); response = StringExtractorGDBRemote(); - } while (SendPacketAndWaitForResponse("qsProcessInfo", response, false) == + } while (SendPacketAndWaitForResponse("qsProcessInfo", response) == PacketResult::Success); } else { m_supports_qfProcessInfo = false; @@ -2267,7 +2313,7 @@ bool GDBRemoteCommunicationClient::GetUserName(uint32_t uid, assert(packet_len < (int)sizeof(packet)); UNUSED_IF_ASSERT_DISABLED(packet_len); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(packet, response, false) == + if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success) { if (response.IsNormalResponse()) { // Make sure we parsed the right number of characters. The response is @@ -2294,7 +2340,7 @@ bool GDBRemoteCommunicationClient::GetGroupName(uint32_t gid, assert(packet_len < (int)sizeof(packet)); UNUSED_IF_ASSERT_DISABLED(packet_len); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(packet, response, false) == + if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success) { if (response.IsNormalResponse()) { // Make sure we parsed the right number of characters. The response is @@ -2322,8 +2368,7 @@ bool GDBRemoteCommunicationClient::SetNonStopMode(const bool enable) { StringExtractorGDBRemote response; // Send to target - if (SendPacketAndWaitForResponse(packet, response, false) == - PacketResult::Success) + if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success) if (response.IsOKResponse()) return true; @@ -2395,7 +2440,7 @@ void GDBRemoteCommunicationClient::TestPacketSpeed(const uint32_t num_packets, for (i = 0; i < num_packets; ++i) { const auto packet_start_time = steady_clock::now(); StringExtractorGDBRemote response; - SendPacketAndWaitForResponse(packet.GetString(), response, false); + SendPacketAndWaitForResponse(packet.GetString(), response); const auto packet_end_time = steady_clock::now(); packet_times.push_back(packet_end_time - packet_start_time); } @@ -2449,7 +2494,7 @@ void GDBRemoteCommunicationClient::TestPacketSpeed(const uint32_t num_packets, uint32_t packet_count = 0; while (bytes_read < recv_amount) { StringExtractorGDBRemote response; - SendPacketAndWaitForResponse(packet.GetString(), response, false); + SendPacketAndWaitForResponse(packet.GetString(), response); bytes_read += recv_size; ++packet_count; } @@ -2503,7 +2548,7 @@ bool GDBRemoteCommunicationClient::SendSpeedTestPacket(uint32_t send_size, } StringExtractorGDBRemote response; - return SendPacketAndWaitForResponse(packet.GetString(), response, false) == + return SendPacketAndWaitForResponse(packet.GetString(), response) == PacketResult::Success; } @@ -2533,7 +2578,7 @@ bool GDBRemoteCommunicationClient::LaunchGDBServer( // give the process a few seconds to startup ScopedTimeout timeout(*this, seconds(10)); - if (SendPacketAndWaitForResponse(stream.GetString(), response, false) == + if (SendPacketAndWaitForResponse(stream.GetString(), response) == PacketResult::Success) { llvm::StringRef name; llvm::StringRef value; @@ -2557,7 +2602,7 @@ size_t GDBRemoteCommunicationClient::QueryGDBServer( connection_urls.clear(); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse("qQueryGDBServer", response, false) != + if (SendPacketAndWaitForResponse("qQueryGDBServer", response) != PacketResult::Success) return 0; @@ -2596,7 +2641,7 @@ bool GDBRemoteCommunicationClient::KillSpawnedProcess(lldb::pid_t pid) { stream.Printf("qKillSpawnedProcess:%" PRId64, pid); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(stream.GetString(), response, false) == + if (SendPacketAndWaitForResponse(stream.GetString(), response) == PacketResult::Success) { if (response.IsOKResponse()) return true; @@ -2604,25 +2649,27 @@ bool GDBRemoteCommunicationClient::KillSpawnedProcess(lldb::pid_t pid) { return false; } -bool GDBRemoteCommunicationClient::SetCurrentThread(uint64_t tid) { - if (m_curr_tid == tid) - return true; +llvm::Optional<PidTid> +GDBRemoteCommunicationClient::SendSetCurrentThreadPacket(uint64_t tid, + uint64_t pid, + char op) { + lldb_private::StreamString packet; + packet.PutChar('H'); + packet.PutChar(op); + + if (pid != LLDB_INVALID_PROCESS_ID) + packet.Printf("p%" PRIx64 ".", pid); - char packet[32]; - int packet_len; if (tid == UINT64_MAX) - packet_len = ::snprintf(packet, sizeof(packet), "Hg-1"); + packet.PutCString("-1"); else - packet_len = ::snprintf(packet, sizeof(packet), "Hg%" PRIx64, tid); - assert(packet_len + 1 < (int)sizeof(packet)); - UNUSED_IF_ASSERT_DISABLED(packet_len); + packet.Printf("%" PRIx64, tid); + StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(packet, response, false) == - PacketResult::Success) { - if (response.IsOKResponse()) { - m_curr_tid = tid; - return true; - } + if (SendPacketAndWaitForResponse(packet.GetString(), response) + == PacketResult::Success) { + if (response.IsOKResponse()) + return {{pid, tid}}; /* * Connected bare-iron target (like YAMON gdb-stub) may not have support for @@ -2630,55 +2677,46 @@ bool GDBRemoteCommunicationClient::SetCurrentThread(uint64_t tid) { * The reply from '?' packet could be as simple as 'S05'. There is no packet * which can * give us pid and/or tid. Assume pid=tid=1 in such cases. - */ - if (response.IsUnsupportedResponse() && IsConnected()) { - m_curr_tid = 1; - return true; - } + */ + if (response.IsUnsupportedResponse() && IsConnected()) + return {{1, 1}}; } - return false; + return llvm::None; } -bool GDBRemoteCommunicationClient::SetCurrentThreadForRun(uint64_t tid) { - if (m_curr_tid_run == tid) +bool GDBRemoteCommunicationClient::SetCurrentThread(uint64_t tid, + uint64_t pid) { + if (m_curr_tid == tid && + (m_curr_pid == pid || LLDB_INVALID_PROCESS_ID == pid)) return true; - char packet[32]; - int packet_len; - if (tid == UINT64_MAX) - packet_len = ::snprintf(packet, sizeof(packet), "Hc-1"); - else - packet_len = ::snprintf(packet, sizeof(packet), "Hc%" PRIx64, tid); + llvm::Optional<PidTid> ret = SendSetCurrentThreadPacket(tid, pid, 'g'); + if (ret.hasValue()) { + if (ret->pid != LLDB_INVALID_PROCESS_ID) + m_curr_pid = ret->pid; + m_curr_tid = ret->tid; + } + return ret.hasValue(); +} - assert(packet_len + 1 < (int)sizeof(packet)); - UNUSED_IF_ASSERT_DISABLED(packet_len); - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(packet, response, false) == - PacketResult::Success) { - if (response.IsOKResponse()) { - m_curr_tid_run = tid; - return true; - } +bool GDBRemoteCommunicationClient::SetCurrentThreadForRun(uint64_t tid, + uint64_t pid) { + if (m_curr_tid_run == tid && + (m_curr_pid_run == pid || LLDB_INVALID_PROCESS_ID == pid)) + return true; - /* - * Connected bare-iron target (like YAMON gdb-stub) may not have support for - * Hc packet. - * The reply from '?' packet could be as simple as 'S05'. There is no packet - * which can - * give us pid and/or tid. Assume pid=tid=1 in such cases. - */ - if (response.IsUnsupportedResponse() && IsConnected()) { - m_curr_tid_run = 1; - return true; - } + llvm::Optional<PidTid> ret = SendSetCurrentThreadPacket(tid, pid, 'c'); + if (ret.hasValue()) { + if (ret->pid != LLDB_INVALID_PROCESS_ID) + m_curr_pid_run = ret->pid; + m_curr_tid_run = ret->tid; } - return false; + return ret.hasValue(); } bool GDBRemoteCommunicationClient::GetStopReply( StringExtractorGDBRemote &response) { - if (SendPacketAndWaitForResponse("?", response, false) == - PacketResult::Success) + if (SendPacketAndWaitForResponse("?", response) == PacketResult::Success) return response.IsNormalResponse(); return false; } @@ -2691,7 +2729,7 @@ bool GDBRemoteCommunicationClient::GetThreadStopInfo( ::snprintf(packet, sizeof(packet), "qThreadStopInfo%" PRIx64, tid); assert(packet_len < (int)sizeof(packet)); UNUSED_IF_ASSERT_DISABLED(packet_len); - if (SendPacketAndWaitForResponse(packet, response, false) == + if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success) { if (response.IsUnsupportedResponse()) m_supports_qThreadStopInfo = false; @@ -2707,7 +2745,8 @@ bool GDBRemoteCommunicationClient::GetThreadStopInfo( } uint8_t GDBRemoteCommunicationClient::SendGDBStoppointTypePacket( - GDBStoppointType type, bool insert, addr_t addr, uint32_t length) { + GDBStoppointType type, bool insert, addr_t addr, uint32_t length, + std::chrono::seconds timeout) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64, __FUNCTION__, insert ? "add" : "remove", addr); @@ -2728,7 +2767,7 @@ uint8_t GDBRemoteCommunicationClient::SendGDBStoppointTypePacket( // or "" (unsupported) response.SetResponseValidatorToOKErrorNotSupported(); // Try to send the breakpoint packet, and check that it was correctly sent - if (SendPacketAndWaitForResponse(packet, response, true) == + if (SendPacketAndWaitForResponse(packet, response, timeout) == PacketResult::Success) { // Receive and OK packet when the breakpoint successfully placed if (response.IsOKResponse()) @@ -2766,11 +2805,12 @@ uint8_t GDBRemoteCommunicationClient::SendGDBStoppointTypePacket( return UINT8_MAX; } -size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs( - std::vector<lldb::tid_t> &thread_ids, bool &sequence_mutex_unavailable) { - thread_ids.clear(); +std::vector<std::pair<lldb::pid_t, lldb::tid_t>> +GDBRemoteCommunicationClient::GetCurrentProcessAndThreadIDs( + bool &sequence_mutex_unavailable) { + std::vector<std::pair<lldb::pid_t, lldb::tid_t>> ids; - Lock lock(*this, false); + Lock lock(*this); if (lock) { sequence_mutex_unavailable = false; StringExtractorGDBRemote response; @@ -2786,11 +2826,11 @@ size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs( break; if (ch == 'm') { do { - tid_t tid = response.GetHexMaxU64(false, LLDB_INVALID_THREAD_ID); + auto pid_tid = response.GetPidTid(LLDB_INVALID_PROCESS_ID); + if (!pid_tid) + return {}; - if (tid != LLDB_INVALID_THREAD_ID) { - thread_ids.push_back(tid); - } + ids.push_back(pid_tid.getValue()); ch = response.GetChar(); // Skip the command separator } while (ch == ','); // Make sure we got a comma separator } @@ -2803,10 +2843,10 @@ size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs( * be as simple as 'S05'. There is no packet which can give us pid and/or * tid. * Assume pid=tid=1 in such cases. - */ + */ if ((response.IsUnsupportedResponse() || response.IsNormalResponse()) && - thread_ids.size() == 0 && IsConnected()) { - thread_ids.push_back(1); + ids.size() == 0 && IsConnected()) { + ids.emplace_back(1, 1); } } else { Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS | @@ -2815,12 +2855,34 @@ size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs( "packet 'qfThreadInfo'"); sequence_mutex_unavailable = true; } + + return ids; +} + +size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs( + std::vector<lldb::tid_t> &thread_ids, bool &sequence_mutex_unavailable) { + lldb::pid_t pid = GetCurrentProcessID(); + thread_ids.clear(); + + auto ids = GetCurrentProcessAndThreadIDs(sequence_mutex_unavailable); + if (ids.empty() || sequence_mutex_unavailable) + return 0; + + for (auto id : ids) { + // skip threads that do not belong to the current process + if (id.first != LLDB_INVALID_PROCESS_ID && id.first != pid) + continue; + if (id.second != LLDB_INVALID_THREAD_ID && + id.second != StringExtractorGDBRemote::AllThreads) + thread_ids.push_back(id.second); + } + return thread_ids.size(); } lldb::addr_t GDBRemoteCommunicationClient::GetShlibInfoAddr() { StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse("qShlibInfoAddr", response, false) != + if (SendPacketAndWaitForResponse("qShlibInfoAddr", response) != PacketResult::Success || !response.IsNormalResponse()) return LLDB_INVALID_ADDRESS; @@ -2853,7 +2915,7 @@ lldb_private::Status GDBRemoteCommunicationClient::RunShellCommand( stream.PutStringAsRawHex8(path); } StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(stream.GetString(), response, false) == + if (SendPacketAndWaitForResponse(stream.GetString(), response) == PacketResult::Success) { if (response.GetChar() != 'F') return Status("malformed reply"); @@ -2891,8 +2953,7 @@ Status GDBRemoteCommunicationClient::MakeDirectory(const FileSpec &file_spec, llvm::StringRef packet = stream.GetString(); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(packet, response, false) != - PacketResult::Success) + if (SendPacketAndWaitForResponse(packet, response) != PacketResult::Success) return Status("failed to send '%s' packet", packet.str().c_str()); if (response.GetChar() != 'F') @@ -2913,8 +2974,7 @@ GDBRemoteCommunicationClient::SetFilePermissions(const FileSpec &file_spec, llvm::StringRef packet = stream.GetString(); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(packet, response, false) != - PacketResult::Success) + if (SendPacketAndWaitForResponse(packet, response) != PacketResult::Success) return Status("failed to send '%s' packet", stream.GetData()); if (response.GetChar() != 'F') @@ -2956,7 +3016,7 @@ GDBRemoteCommunicationClient::OpenFile(const lldb_private::FileSpec &file_spec, stream.PutChar(','); stream.PutHex32(mode); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(stream.GetString(), response, false) == + if (SendPacketAndWaitForResponse(stream.GetString(), response) == PacketResult::Success) { return ParseHostIOPacketResponse(response, UINT64_MAX, error); } @@ -2968,7 +3028,7 @@ bool GDBRemoteCommunicationClient::CloseFile(lldb::user_id_t fd, lldb_private::StreamString stream; stream.Printf("vFile:close:%i", (int)fd); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(stream.GetString(), response, false) == + if (SendPacketAndWaitForResponse(stream.GetString(), response) == PacketResult::Success) { return ParseHostIOPacketResponse(response, -1, error) == 0; } @@ -2983,7 +3043,7 @@ lldb::user_id_t GDBRemoteCommunicationClient::GetFileSize( stream.PutCString("vFile:size:"); stream.PutStringAsRawHex8(path); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(stream.GetString(), response, false) == + if (SendPacketAndWaitForResponse(stream.GetString(), response) == PacketResult::Success) { if (response.GetChar() != 'F') return UINT64_MAX; @@ -3001,7 +3061,7 @@ void GDBRemoteCommunicationClient::AutoCompleteDiskFileOrDirectory( stream.PutChar(','); stream.PutStringAsRawHex8(request.GetCursorArgumentPrefix()); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(stream.GetString(), response, false) == + if (SendPacketAndWaitForResponse(stream.GetString(), response) == PacketResult::Success) { StreamString strm; char ch = response.GetChar(); @@ -3027,7 +3087,7 @@ GDBRemoteCommunicationClient::GetFilePermissions(const FileSpec &file_spec, stream.PutCString("vFile:mode:"); stream.PutStringAsRawHex8(path); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(stream.GetString(), response, false) == + if (SendPacketAndWaitForResponse(stream.GetString(), response) == PacketResult::Success) { if (response.GetChar() != 'F') { error.SetErrorStringWithFormat("invalid response to '%s' packet", @@ -3062,7 +3122,7 @@ uint64_t GDBRemoteCommunicationClient::ReadFile(lldb::user_id_t fd, stream.Printf("vFile:pread:%i,%" PRId64 ",%" PRId64, (int)fd, dst_len, offset); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(stream.GetString(), response, false) == + if (SendPacketAndWaitForResponse(stream.GetString(), response) == PacketResult::Success) { if (response.GetChar() != 'F') return 0; @@ -3096,7 +3156,7 @@ uint64_t GDBRemoteCommunicationClient::WriteFile(lldb::user_id_t fd, stream.Printf("vFile:pwrite:%i,%" PRId64 ",", (int)fd, offset); stream.PutEscapedBytes(src, src_len); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(stream.GetString(), response, false) == + if (SendPacketAndWaitForResponse(stream.GetString(), response) == PacketResult::Success) { if (response.GetChar() != 'F') { error.SetErrorStringWithFormat("write file failed"); @@ -3131,7 +3191,7 @@ Status GDBRemoteCommunicationClient::CreateSymlink(const FileSpec &src, stream.PutChar(','); stream.PutStringAsRawHex8(src_path); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(stream.GetString(), response, false) == + if (SendPacketAndWaitForResponse(stream.GetString(), response) == PacketResult::Success) { if (response.GetChar() == 'F') { uint32_t result = response.GetU32(UINT32_MAX); @@ -3162,7 +3222,7 @@ Status GDBRemoteCommunicationClient::Unlink(const FileSpec &file_spec) { // so we follow suit here stream.PutStringAsRawHex8(path); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(stream.GetString(), response, false) == + if (SendPacketAndWaitForResponse(stream.GetString(), response) == PacketResult::Success) { if (response.GetChar() == 'F') { uint32_t result = response.GetU32(UINT32_MAX); @@ -3192,7 +3252,7 @@ bool GDBRemoteCommunicationClient::GetFileExists( stream.PutCString("vFile:exists:"); stream.PutStringAsRawHex8(path); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(stream.GetString(), response, false) == + if (SendPacketAndWaitForResponse(stream.GetString(), response) == PacketResult::Success) { if (response.GetChar() != 'F') return false; @@ -3211,7 +3271,7 @@ bool GDBRemoteCommunicationClient::CalculateMD5( stream.PutCString("vFile:MD5:"); stream.PutStringAsRawHex8(path); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(stream.GetString(), response, false) == + if (SendPacketAndWaitForResponse(stream.GetString(), response) == PacketResult::Success) { if (response.GetChar() != 'F') return false; @@ -3258,7 +3318,7 @@ DataBufferSP GDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid, payload.Printf("p%x", reg); StringExtractorGDBRemote response; if (SendThreadSpecificPacketAndWaitForResponse( - tid, std::move(payload), response, false) != PacketResult::Success || + tid, std::move(payload), response) != PacketResult::Success || !response.IsNormalResponse()) return nullptr; @@ -3273,7 +3333,7 @@ DataBufferSP GDBRemoteCommunicationClient::ReadAllRegisters(lldb::tid_t tid) { payload.PutChar('g'); StringExtractorGDBRemote response; if (SendThreadSpecificPacketAndWaitForResponse( - tid, std::move(payload), response, false) != PacketResult::Success || + tid, std::move(payload), response) != PacketResult::Success || !response.IsNormalResponse()) return nullptr; @@ -3292,9 +3352,8 @@ bool GDBRemoteCommunicationClient::WriteRegister(lldb::tid_t tid, endian::InlHostByteOrder(), endian::InlHostByteOrder()); StringExtractorGDBRemote response; - return SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload), - response, false) == - PacketResult::Success && + return SendThreadSpecificPacketAndWaitForResponse( + tid, std::move(payload), response) == PacketResult::Success && response.IsOKResponse(); } @@ -3306,9 +3365,8 @@ bool GDBRemoteCommunicationClient::WriteAllRegisters( endian::InlHostByteOrder(), endian::InlHostByteOrder()); StringExtractorGDBRemote response; - return SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload), - response, false) == - PacketResult::Success && + return SendThreadSpecificPacketAndWaitForResponse( + tid, std::move(payload), response) == PacketResult::Success && response.IsOKResponse(); } @@ -3323,7 +3381,7 @@ bool GDBRemoteCommunicationClient::SaveRegisterState(lldb::tid_t tid, payload.PutCString("QSaveRegisterState"); StringExtractorGDBRemote response; if (SendThreadSpecificPacketAndWaitForResponse( - tid, std::move(payload), response, false) != PacketResult::Success) + tid, std::move(payload), response) != PacketResult::Success) return false; if (response.IsUnsupportedResponse()) @@ -3349,7 +3407,7 @@ bool GDBRemoteCommunicationClient::RestoreRegisterState(lldb::tid_t tid, payload.Printf("QRestoreRegisterState:%u", save_id); StringExtractorGDBRemote response; if (SendThreadSpecificPacketAndWaitForResponse( - tid, std::move(payload), response, false) != PacketResult::Success) + tid, std::move(payload), response) != PacketResult::Success) return false; if (response.IsOKResponse()) @@ -3367,251 +3425,179 @@ bool GDBRemoteCommunicationClient::SyncThreadState(lldb::tid_t tid) { StreamString packet; StringExtractorGDBRemote response; packet.Printf("QSyncThreadState:%4.4" PRIx64 ";", tid); - return SendPacketAndWaitForResponse(packet.GetString(), response, false) == + return SendPacketAndWaitForResponse(packet.GetString(), response) == GDBRemoteCommunication::PacketResult::Success && response.IsOKResponse(); } -lldb::user_id_t -GDBRemoteCommunicationClient::SendStartTracePacket(const TraceOptions &options, - Status &error) { +llvm::Expected<TraceSupportedResponse> +GDBRemoteCommunicationClient::SendTraceSupported(std::chrono::seconds timeout) { Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - lldb::user_id_t ret_uid = LLDB_INVALID_UID; StreamGDBRemote escaped_packet; - escaped_packet.PutCString("jTraceStart:"); - - StructuredData::Dictionary json_packet; - json_packet.AddIntegerItem("type", options.getType()); - json_packet.AddIntegerItem("buffersize", options.getTraceBufferSize()); - json_packet.AddIntegerItem("metabuffersize", options.getMetaDataBufferSize()); - - if (options.getThreadID() != LLDB_INVALID_THREAD_ID) - json_packet.AddIntegerItem("threadid", options.getThreadID()); - - StructuredData::DictionarySP custom_params = options.getTraceParams(); - if (custom_params) - json_packet.AddItem("params", custom_params); - - StreamString json_string; - json_packet.Dump(json_string, false); - escaped_packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize()); + escaped_packet.PutCString("jLLDBTraceSupported"); StringExtractorGDBRemote response; if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response, - true) == + timeout) == GDBRemoteCommunication::PacketResult::Success) { - if (!response.IsNormalResponse()) { - error = response.GetStatus(); - LLDB_LOG(log, "Target does not support Tracing , error {0}", error); - } else { - ret_uid = response.GetHexMaxU64(false, LLDB_INVALID_UID); - } - } else { - LLDB_LOG(log, "failed to send packet"); - error.SetErrorStringWithFormat("failed to send packet: '%s'", - escaped_packet.GetData()); + if (response.IsErrorResponse()) + return response.GetStatus().ToError(); + if (response.IsUnsupportedResponse()) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "jLLDBTraceSupported is unsupported"); + + return llvm::json::parse<TraceSupportedResponse>(response.Peek(), + "TraceSupportedResponse"); } - return ret_uid; + LLDB_LOG(log, "failed to send packet: jLLDBTraceSupported"); + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "failed to send packet: jLLDBTraceSupported"); } -Status -GDBRemoteCommunicationClient::SendStopTracePacket(lldb::user_id_t uid, - lldb::tid_t thread_id) { +llvm::Error +GDBRemoteCommunicationClient::SendTraceStop(const TraceStopRequest &request, + std::chrono::seconds timeout) { Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - StringExtractorGDBRemote response; - Status error; - StructuredData::Dictionary json_packet; StreamGDBRemote escaped_packet; - StreamString json_string; - escaped_packet.PutCString("jTraceStop:"); - - json_packet.AddIntegerItem("traceid", uid); + escaped_packet.PutCString("jLLDBTraceStop:"); - if (thread_id != LLDB_INVALID_THREAD_ID) - json_packet.AddIntegerItem("threadid", thread_id); + std::string json_string; + llvm::raw_string_ostream os(json_string); + os << toJSON(request); + os.flush(); - json_packet.Dump(json_string, false); - - escaped_packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize()); + escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size()); + StringExtractorGDBRemote response; if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response, - true) == + timeout) == GDBRemoteCommunication::PacketResult::Success) { - if (!response.IsOKResponse()) { - error = response.GetStatus(); - LLDB_LOG(log, "stop tracing failed"); - } - } else { - LLDB_LOG(log, "failed to send packet"); - error.SetErrorStringWithFormat( - "failed to send packet: '%s' with error '%d'", escaped_packet.GetData(), - response.GetError()); + if (response.IsErrorResponse()) + return response.GetStatus().ToError(); + if (response.IsUnsupportedResponse()) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "jLLDBTraceStop is unsupported"); + if (response.IsOKResponse()) + return llvm::Error::success(); + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Invalid jLLDBTraceStart response"); } - return error; + LLDB_LOG(log, "failed to send packet: jLLDBTraceStop"); + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "failed to send packet: jLLDBTraceStop '%s'", + escaped_packet.GetData()); } -Status GDBRemoteCommunicationClient::SendGetDataPacket( - lldb::user_id_t uid, lldb::tid_t thread_id, - llvm::MutableArrayRef<uint8_t> &buffer, size_t offset) { +llvm::Error +GDBRemoteCommunicationClient::SendTraceStart(const llvm::json::Value ¶ms, + std::chrono::seconds timeout) { + Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); StreamGDBRemote escaped_packet; - escaped_packet.PutCString("jTraceBufferRead:"); - return SendGetTraceDataPacket(escaped_packet, uid, thread_id, buffer, offset); -} - -Status GDBRemoteCommunicationClient::SendGetMetaDataPacket( - lldb::user_id_t uid, lldb::tid_t thread_id, - llvm::MutableArrayRef<uint8_t> &buffer, size_t offset) { + escaped_packet.PutCString("jLLDBTraceStart:"); - StreamGDBRemote escaped_packet; - escaped_packet.PutCString("jTraceMetaRead:"); - return SendGetTraceDataPacket(escaped_packet, uid, thread_id, buffer, offset); -} + std::string json_string; + llvm::raw_string_ostream os(json_string); + os << params; + os.flush(); -llvm::Expected<TraceTypeInfo> -GDBRemoteCommunicationClient::SendGetSupportedTraceType() { - Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - - StreamGDBRemote escaped_packet; - escaped_packet.PutCString("jLLDBTraceSupportedType"); + escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size()); StringExtractorGDBRemote response; if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response, - true) == + timeout) == GDBRemoteCommunication::PacketResult::Success) { if (response.IsErrorResponse()) return response.GetStatus().ToError(); if (response.IsUnsupportedResponse()) return llvm::createStringError(llvm::inconvertibleErrorCode(), - "jLLDBTraceSupportedType is unsupported"); - - if (llvm::Expected<TraceTypeInfo> type = - llvm::json::parse<TraceTypeInfo>(response.Peek())) - return *type; - else - return type.takeError(); + "jLLDBTraceStart is unsupported"); + if (response.IsOKResponse()) + return llvm::Error::success(); + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Invalid jLLDBTraceStart response"); } - LLDB_LOG(log, "failed to send packet: jLLDBTraceSupportedType"); - return llvm::createStringError( - llvm::inconvertibleErrorCode(), - "failed to send packet: jLLDBTraceSupportedType"); + LLDB_LOG(log, "failed to send packet: jLLDBTraceStart"); + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "failed to send packet: jLLDBTraceStart '%s'", + escaped_packet.GetData()); } -Status -GDBRemoteCommunicationClient::SendGetTraceConfigPacket(lldb::user_id_t uid, - TraceOptions &options) { +llvm::Expected<std::string> +GDBRemoteCommunicationClient::SendTraceGetState(llvm::StringRef type, + std::chrono::seconds timeout) { Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - StringExtractorGDBRemote response; - Status error; - StreamString json_string; StreamGDBRemote escaped_packet; - escaped_packet.PutCString("jTraceConfigRead:"); - - StructuredData::Dictionary json_packet; - json_packet.AddIntegerItem("traceid", uid); + escaped_packet.PutCString("jLLDBTraceGetState:"); - if (options.getThreadID() != LLDB_INVALID_THREAD_ID) - json_packet.AddIntegerItem("threadid", options.getThreadID()); + std::string json_string; + llvm::raw_string_ostream os(json_string); + os << toJSON(TraceGetStateRequest{type.str()}); + os.flush(); - json_packet.Dump(json_string, false); - escaped_packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize()); + escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size()); + StringExtractorGDBRemote response; if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response, - true) == + timeout) == GDBRemoteCommunication::PacketResult::Success) { - if (response.IsNormalResponse()) { - uint64_t type = std::numeric_limits<uint64_t>::max(); - uint64_t buffersize = std::numeric_limits<uint64_t>::max(); - uint64_t metabuffersize = std::numeric_limits<uint64_t>::max(); - - auto json_object = StructuredData::ParseJSON(response.Peek()); - - if (!json_object || - json_object->GetType() != lldb::eStructuredDataTypeDictionary) { - error.SetErrorString("Invalid Configuration obtained"); - return error; - } - - auto json_dict = json_object->GetAsDictionary(); - - json_dict->GetValueForKeyAsInteger<uint64_t>("metabuffersize", - metabuffersize); - options.setMetaDataBufferSize(metabuffersize); - - json_dict->GetValueForKeyAsInteger<uint64_t>("buffersize", buffersize); - options.setTraceBufferSize(buffersize); - - json_dict->GetValueForKeyAsInteger<uint64_t>("type", type); - options.setType(static_cast<lldb::TraceType>(type)); - - StructuredData::ObjectSP custom_params_sp = - json_dict->GetValueForKey("params"); - if (custom_params_sp) { - if (custom_params_sp->GetType() != - lldb::eStructuredDataTypeDictionary) { - error.SetErrorString("Invalid Configuration obtained"); - return error; - } else - options.setTraceParams( - std::static_pointer_cast<StructuredData::Dictionary>( - custom_params_sp)); - } - } else { - error = response.GetStatus(); - } - } else { - LLDB_LOG(log, "failed to send packet"); - error.SetErrorStringWithFormat("failed to send packet: '%s'", - escaped_packet.GetData()); + if (response.IsErrorResponse()) + return response.GetStatus().ToError(); + if (response.IsUnsupportedResponse()) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "jLLDBTraceGetState is unsupported"); + return std::string(response.Peek()); } - return error; + + LLDB_LOG(log, "failed to send packet: jLLDBTraceGetState"); + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "failed to send packet: jLLDBTraceGetState '%s'", + escaped_packet.GetData()); } -Status GDBRemoteCommunicationClient::SendGetTraceDataPacket( - StreamGDBRemote &packet, lldb::user_id_t uid, lldb::tid_t thread_id, - llvm::MutableArrayRef<uint8_t> &buffer, size_t offset) { +llvm::Expected<std::vector<uint8_t>> +GDBRemoteCommunicationClient::SendTraceGetBinaryData( + const TraceGetBinaryDataRequest &request, std::chrono::seconds timeout) { Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - Status error; - StructuredData::Dictionary json_packet; - - json_packet.AddIntegerItem("traceid", uid); - json_packet.AddIntegerItem("offset", offset); - json_packet.AddIntegerItem("buffersize", buffer.size()); + StreamGDBRemote escaped_packet; + escaped_packet.PutCString("jLLDBTraceGetBinaryData:"); - if (thread_id != LLDB_INVALID_THREAD_ID) - json_packet.AddIntegerItem("threadid", thread_id); + std::string json_string; + llvm::raw_string_ostream os(json_string); + os << toJSON(request); + os.flush(); - StreamString json_string; - json_packet.Dump(json_string, false); + escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size()); - packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize()); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(packet.GetString(), response, true) == + if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response, + timeout) == GDBRemoteCommunication::PacketResult::Success) { - if (response.IsNormalResponse()) { - size_t filled_size = response.GetHexBytesAvail(buffer); - buffer = llvm::MutableArrayRef<uint8_t>(buffer.data(), filled_size); - } else { - error = response.GetStatus(); - buffer = buffer.slice(buffer.size()); - } - } else { - LLDB_LOG(log, "failed to send packet"); - error.SetErrorStringWithFormat("failed to send packet: '%s'", - packet.GetData()); - buffer = buffer.slice(buffer.size()); + if (response.IsErrorResponse()) + return response.GetStatus().ToError(); + if (response.IsUnsupportedResponse()) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "jLLDBTraceGetBinaryData is unsupported"); + std::string data; + response.GetEscapedBinaryData(data); + return std::vector<uint8_t>(data.begin(), data.end()); } - return error; + LLDB_LOG(log, "failed to send packet: jLLDBTraceGetBinaryData"); + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "failed to send packet: jLLDBTraceGetBinaryData '%s'", + escaped_packet.GetData()); } llvm::Optional<QOffsets> GDBRemoteCommunicationClient::GetQOffsets() { StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse( - "qOffsets", response, /*send_async=*/false) != PacketResult::Success) + if (SendPacketAndWaitForResponse("qOffsets", response) != + PacketResult::Success) return llvm::None; if (!response.IsNormalResponse()) return llvm::None; @@ -3666,7 +3652,7 @@ bool GDBRemoteCommunicationClient::GetModuleInfo( packet.PutStringAsRawHex8(triple); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(packet.GetString(), response, false) != + if (SendPacketAndWaitForResponse(packet.GetString(), response) != PacketResult::Success) return false; @@ -3773,7 +3759,7 @@ GDBRemoteCommunicationClient::GetModulesInfo( ScopedTimeout timeout(*this, std::chrono::seconds(10)); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(payload.GetString(), response, false) != + if (SendPacketAndWaitForResponse(payload.GetString(), response) != PacketResult::Success || response.IsErrorResponse()) return llvm::None; @@ -3832,7 +3818,7 @@ bool GDBRemoteCommunicationClient::ReadExtFeature( << "," << std::hex << size; GDBRemoteCommunication::PacketResult res = - SendPacketAndWaitForResponse(packet.str(), chunk, false); + SendPacketAndWaitForResponse(packet.str(), chunk); if (res != GDBRemoteCommunication::PacketResult::Success) { err.SetErrorString("Error sending $qXfer packet"); @@ -3921,7 +3907,7 @@ void GDBRemoteCommunicationClient::ServeSymbolLookups( bool first_qsymbol_query = true; if (m_supports_qSymbol && !m_qSymbol_requests_done) { - Lock lock(*this, false); + Lock lock(*this); if (lock) { StreamString packet; packet.PutCString("qSymbol::"); @@ -4049,9 +4035,8 @@ GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins() { // Poll it now. StringExtractorGDBRemote response; - const bool send_async = false; - if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response, - send_async) == PacketResult::Success) { + if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response) == + PacketResult::Success) { m_supported_async_json_packets_sp = StructuredData::ParseJSON(std::string(response.GetStringRef())); if (m_supported_async_json_packets_sp && @@ -4095,7 +4080,7 @@ Status GDBRemoteCommunicationClient::SendSignalsToIgnore( std::string packet = formatv("QPassSignals:{0:$[;]@(x-2)}", range).str(); StringExtractorGDBRemote response; - auto send_status = SendPacketAndWaitForResponse(packet, response, false); + auto send_status = SendPacketAndWaitForResponse(packet, response); if (send_status != GDBRemoteCommunication::PacketResult::Success) return Status("Sending QPassSignals packet failed"); @@ -4134,10 +4119,8 @@ Status GDBRemoteCommunicationClient::ConfigureRemoteStructuredData( stream.Flush(); // Send the packet. - const bool send_async = false; StringExtractorGDBRemote response; - auto result = - SendPacketAndWaitForResponse(stream.GetString(), response, send_async); + auto result = SendPacketAndWaitForResponse(stream.GetString(), response); if (result == PacketResult::Success) { // We failed if the config result comes back other than OK. if (strcmp(response.GetStringRef().data(), "OK") == 0) { diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h index af3755fce774..1e1797c10dfc 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -22,7 +22,7 @@ #include "lldb/Utility/GDBRemote.h" #include "lldb/Utility/ProcessInfo.h" #include "lldb/Utility/StructuredData.h" -#include "lldb/Utility/TraceOptions.h" +#include "lldb/Utility/TraceGDBRemotePackets.h" #if defined(_WIN32) #include "lldb/Host/windows/PosixApi.h" #endif @@ -49,6 +49,12 @@ inline bool operator==(const QOffsets &a, const QOffsets &b) { } llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const QOffsets &offsets); +// A trivial struct used to return a pair of PID and TID. +struct PidTid { + uint64_t pid; + uint64_t tid; +}; + class GDBRemoteCommunicationClient : public GDBRemoteClientBase { public: GDBRemoteCommunicationClient(); @@ -275,6 +281,8 @@ public: ArchSpec GetSystemArchitecture(); + uint32_t GetAddressingBits(); + bool GetHostname(std::string &s); lldb::addr_t GetShlibInfoAddr(); @@ -319,7 +327,8 @@ public: GDBStoppointType type, // Type of breakpoint or watchpoint bool insert, // Insert or remove? lldb::addr_t addr, // Address of breakpoint or watchpoint - uint32_t length); // Byte Size of breakpoint or watchpoint + uint32_t length, // Byte Size of breakpoint or watchpoint + std::chrono::seconds interrupt_timeout); // Time to wait for an interrupt bool SetNonStopMode(const bool enable); @@ -334,9 +343,14 @@ public: // and response times. bool SendSpeedTestPacket(uint32_t send_size, uint32_t recv_size); - bool SetCurrentThread(uint64_t tid); + llvm::Optional<PidTid> + SendSetCurrentThreadPacket(uint64_t tid, uint64_t pid, char op); - bool SetCurrentThreadForRun(uint64_t tid); + bool SetCurrentThread(uint64_t tid, + lldb::pid_t pid = LLDB_INVALID_PROCESS_ID); + + bool SetCurrentThreadForRun(uint64_t tid, + lldb::pid_t pid = LLDB_INVALID_PROCESS_ID); bool GetQXferAuxvReadSupported(); @@ -366,6 +380,9 @@ public: return m_supports_alloc_dealloc_memory; } + std::vector<std::pair<lldb::pid_t, lldb::tid_t>> + GetCurrentProcessAndThreadIDs(bool &sequence_mutex_unavailable); + size_t GetCurrentThreadIDs(std::vector<lldb::tid_t> &thread_ids, bool &sequence_mutex_unavailable); @@ -446,6 +463,14 @@ public: bool GetSharedCacheInfoSupported(); + bool GetMemoryTaggingSupported(); + + lldb::DataBufferSP ReadMemoryTags(lldb::addr_t addr, size_t len, + int32_t type); + + Status WriteMemoryTags(lldb::addr_t addr, size_t len, int32_t type, + const std::vector<uint8_t> &tags); + /// Use qOffsets to query the offset used when relocating the target /// executable. If successful, the returned structure will contain at least /// one value in the offsets field. @@ -505,59 +530,61 @@ public: ConfigureRemoteStructuredData(ConstString type_name, const StructuredData::ObjectSP &config_sp); - lldb::user_id_t SendStartTracePacket(const TraceOptions &options, - Status &error); + llvm::Expected<TraceSupportedResponse> + SendTraceSupported(std::chrono::seconds interrupt_timeout); - Status SendStopTracePacket(lldb::user_id_t uid, lldb::tid_t thread_id); + llvm::Error SendTraceStart(const llvm::json::Value &request, + std::chrono::seconds interrupt_timeout); - Status SendGetDataPacket(lldb::user_id_t uid, lldb::tid_t thread_id, - llvm::MutableArrayRef<uint8_t> &buffer, - size_t offset = 0); + llvm::Error SendTraceStop(const TraceStopRequest &request, + std::chrono::seconds interrupt_timeout); - Status SendGetMetaDataPacket(lldb::user_id_t uid, lldb::tid_t thread_id, - llvm::MutableArrayRef<uint8_t> &buffer, - size_t offset = 0); + llvm::Expected<std::string> + SendTraceGetState(llvm::StringRef type, + std::chrono::seconds interrupt_timeout); - Status SendGetTraceConfigPacket(lldb::user_id_t uid, TraceOptions &options); - - llvm::Expected<TraceTypeInfo> SendGetSupportedTraceType(); + llvm::Expected<std::vector<uint8_t>> + SendTraceGetBinaryData(const TraceGetBinaryDataRequest &request, + std::chrono::seconds interrupt_timeout); protected: - LazyBool m_supports_not_sending_acks; - LazyBool m_supports_thread_suffix; - LazyBool m_supports_threads_in_stop_reply; - LazyBool m_supports_vCont_all; - LazyBool m_supports_vCont_any; - LazyBool m_supports_vCont_c; - LazyBool m_supports_vCont_C; - LazyBool m_supports_vCont_s; - LazyBool m_supports_vCont_S; - LazyBool m_qHostInfo_is_valid; - LazyBool m_curr_pid_is_valid; - LazyBool m_qProcessInfo_is_valid; - LazyBool m_qGDBServerVersion_is_valid; - LazyBool m_supports_alloc_dealloc_memory; - LazyBool m_supports_memory_region_info; - LazyBool m_supports_watchpoint_support_info; - LazyBool m_supports_detach_stay_stopped; - LazyBool m_watchpoints_trigger_after_instruction; - LazyBool m_attach_or_wait_reply; - LazyBool m_prepare_for_reg_writing_reply; - LazyBool m_supports_p; - LazyBool m_supports_x; - LazyBool m_avoid_g_packets; - LazyBool m_supports_QSaveRegisterState; - LazyBool m_supports_qXfer_auxv_read; - LazyBool m_supports_qXfer_libraries_read; - LazyBool m_supports_qXfer_libraries_svr4_read; - LazyBool m_supports_qXfer_features_read; - LazyBool m_supports_qXfer_memory_map_read; - LazyBool m_supports_augmented_libraries_svr4_read; - LazyBool m_supports_jThreadExtendedInfo; - LazyBool m_supports_jLoadedDynamicLibrariesInfos; - LazyBool m_supports_jGetSharedCacheInfo; - LazyBool m_supports_QPassSignals; - LazyBool m_supports_error_string_reply; + LazyBool m_supports_not_sending_acks = eLazyBoolCalculate; + LazyBool m_supports_thread_suffix = eLazyBoolCalculate; + LazyBool m_supports_threads_in_stop_reply = eLazyBoolCalculate; + LazyBool m_supports_vCont_all = eLazyBoolCalculate; + LazyBool m_supports_vCont_any = eLazyBoolCalculate; + LazyBool m_supports_vCont_c = eLazyBoolCalculate; + LazyBool m_supports_vCont_C = eLazyBoolCalculate; + LazyBool m_supports_vCont_s = eLazyBoolCalculate; + LazyBool m_supports_vCont_S = eLazyBoolCalculate; + LazyBool m_qHostInfo_is_valid = eLazyBoolCalculate; + LazyBool m_curr_pid_is_valid = eLazyBoolCalculate; + LazyBool m_qProcessInfo_is_valid = eLazyBoolCalculate; + LazyBool m_qGDBServerVersion_is_valid = eLazyBoolCalculate; + LazyBool m_supports_alloc_dealloc_memory = eLazyBoolCalculate; + LazyBool m_supports_memory_region_info = eLazyBoolCalculate; + LazyBool m_supports_watchpoint_support_info = eLazyBoolCalculate; + LazyBool m_supports_detach_stay_stopped = eLazyBoolCalculate; + LazyBool m_watchpoints_trigger_after_instruction = eLazyBoolCalculate; + LazyBool m_attach_or_wait_reply = eLazyBoolCalculate; + LazyBool m_prepare_for_reg_writing_reply = eLazyBoolCalculate; + LazyBool m_supports_p = eLazyBoolCalculate; + LazyBool m_supports_x = eLazyBoolCalculate; + LazyBool m_avoid_g_packets = eLazyBoolCalculate; + LazyBool m_supports_QSaveRegisterState = eLazyBoolCalculate; + LazyBool m_supports_qXfer_auxv_read = eLazyBoolCalculate; + LazyBool m_supports_qXfer_libraries_read = eLazyBoolCalculate; + LazyBool m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate; + LazyBool m_supports_qXfer_features_read = eLazyBoolCalculate; + LazyBool m_supports_qXfer_memory_map_read = eLazyBoolCalculate; + LazyBool m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate; + LazyBool m_supports_jThreadExtendedInfo = eLazyBoolCalculate; + LazyBool m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolCalculate; + LazyBool m_supports_jGetSharedCacheInfo = eLazyBoolCalculate; + LazyBool m_supports_QPassSignals = eLazyBoolCalculate; + LazyBool m_supports_error_string_reply = eLazyBoolCalculate; + LazyBool m_supports_multiprocess = eLazyBoolCalculate; + LazyBool m_supports_memory_tagging = eLazyBoolCalculate; bool m_supports_qProcessInfoPID : 1, m_supports_qfProcessInfo : 1, m_supports_qUserName : 1, m_supports_qGroupName : 1, @@ -568,13 +595,17 @@ protected: m_supports_qModuleInfo : 1, m_supports_jThreadsInfo : 1, m_supports_jModulesInfo : 1; - lldb::pid_t m_curr_pid; - lldb::tid_t m_curr_tid; // Current gdb remote protocol thread index for all - // other operations - lldb::tid_t m_curr_tid_run; // Current gdb remote protocol thread index for - // continue, step, etc + /// Current gdb remote protocol process identifier for all other operations + lldb::pid_t m_curr_pid = LLDB_INVALID_PROCESS_ID; + /// Current gdb remote protocol process identifier for continue, step, etc + lldb::pid_t m_curr_pid_run = LLDB_INVALID_PROCESS_ID; + /// Current gdb remote protocol thread identifier for all other operations + lldb::tid_t m_curr_tid = LLDB_INVALID_THREAD_ID; + /// Current gdb remote protocol thread identifier for continue, step, etc + lldb::tid_t m_curr_tid_run = LLDB_INVALID_THREAD_ID; - uint32_t m_num_supported_hardware_watchpoints; + uint32_t m_num_supported_hardware_watchpoints = 0; + uint32_t m_addressing_bits = 0; ArchSpec m_host_arch; ArchSpec m_process_arch; @@ -585,17 +616,19 @@ protected: std::string m_hostname; std::string m_gdb_server_name; // from reply to qGDBServerVersion, empty if // qGDBServerVersion is not supported - uint32_t m_gdb_server_version; // from reply to qGDBServerVersion, zero if - // qGDBServerVersion is not supported + uint32_t m_gdb_server_version = + UINT32_MAX; // from reply to qGDBServerVersion, zero if + // qGDBServerVersion is not supported std::chrono::seconds m_default_packet_timeout; - uint64_t m_max_packet_size; // as returned by qSupported + int m_target_vm_page_size = 0; // target system VM page size; 0 unspecified + uint64_t m_max_packet_size = 0; // as returned by qSupported std::string m_qSupported_response; // the complete response to qSupported - bool m_supported_async_json_packets_is_valid; + bool m_supported_async_json_packets_is_valid = false; lldb_private::StructuredData::ObjectSP m_supported_async_json_packets_sp; std::vector<MemoryRegionInfo> m_qXfer_memory_map; - bool m_qXfer_memory_map_loaded; + bool m_qXfer_memory_map_loaded = false; bool GetCurrentProcessInfo(bool allow_lazy_pid = true); @@ -603,7 +636,8 @@ protected: // Given the list of compression types that the remote debug stub can support, // possibly enable compression if we find an encoding we can handle. - void MaybeEnableCompression(std::vector<std::string> supported_compressions); + void MaybeEnableCompression( + llvm::ArrayRef<llvm::StringRef> supported_compressions); bool DecodeProcessInfoResponse(StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info); @@ -612,7 +646,7 @@ protected: PacketResult SendThreadSpecificPacketAndWaitForResponse( lldb::tid_t tid, StreamString &&payload, - StringExtractorGDBRemote &response, bool send_async); + StringExtractorGDBRemote &response); Status SendGetTraceDataPacket(StreamGDBRemote &packet, lldb::user_id_t uid, lldb::tid_t thread_id, diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp index 3984a45c3da1..d92c97e81659 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp @@ -19,13 +19,12 @@ using namespace lldb_private; using namespace lldb_private::process_gdb_remote; GDBRemoteCommunicationHistory::GDBRemoteCommunicationHistory(uint32_t size) - : m_packets(), m_curr_idx(0), m_total_packet_count(0), - m_dumped_to_log(false) { + : m_packets() { if (size) m_packets.resize(size); } -GDBRemoteCommunicationHistory::~GDBRemoteCommunicationHistory() {} +GDBRemoteCommunicationHistory::~GDBRemoteCommunicationHistory() = default; void GDBRemoteCommunicationHistory::AddPacket(char packet_char, GDBRemotePacket::Type type, diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h index e783e59c3455..eda464a758e4 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h @@ -74,9 +74,9 @@ private: } std::vector<GDBRemotePacket> m_packets; - uint32_t m_curr_idx; - uint32_t m_total_packet_count; - mutable bool m_dumped_to_log; + uint32_t m_curr_idx = 0; + uint32_t m_total_packet_count = 0; + mutable bool m_dumped_to_log = false; repro::PacketRecorder *m_recorder = nullptr; }; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp index 920327e7d0ab..c91d7cb5ac30 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include <errno.h> +#include <cerrno> #include "lldb/Host/Config.h" #include "llvm/ADT/ScopeExit.h" @@ -74,7 +74,7 @@ GDBRemoteCommunicationReplayServer::GDBRemoteCommunicationReplayServer() m_async_broadcaster(nullptr, "lldb.gdb-replay.async-broadcaster"), m_async_listener_sp( Listener::MakeListener("lldb.gdb-replay.async-listener")), - m_async_thread_state_mutex(), m_skip_acks(false) { + m_async_thread_state_mutex() { m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue, "async thread continue"); m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit, diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h index c13e5ee0bf92..2f8770d0accf 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h @@ -73,7 +73,7 @@ protected: HostThread m_async_thread; std::recursive_mutex m_async_thread_state_mutex; - bool m_skip_acks; + bool m_skip_acks = false; private: GDBRemoteCommunicationReplayServer( diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp index 60548efc0f33..11cac9fa3a4d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include <errno.h> +#include <cerrno> #include "lldb/Host/Config.h" @@ -16,11 +16,13 @@ #include "lldb/Utility/StreamString.h" #include "lldb/Utility/StringExtractorGDBRemote.h" #include "lldb/Utility/UnimplementedError.h" +#include "llvm/Support/JSON.h" #include <cstring> using namespace lldb; using namespace lldb_private; using namespace lldb_private::process_gdb_remote; +using namespace llvm; GDBRemoteCommunicationServer::GDBRemoteCommunicationServer( const char *comm_name, const char *listener_name) @@ -31,7 +33,7 @@ GDBRemoteCommunicationServer::GDBRemoteCommunicationServer( bool &quit) { return this->Handle_QErrorStringEnable(packet); }); } -GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer() {} +GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer() = default; void GDBRemoteCommunicationServer::RegisterPacketHandler( StringExtractorGDBRemote::ServerPacketType packet_type, @@ -151,3 +153,21 @@ GDBRemoteCommunicationServer::SendOKResponse() { bool GDBRemoteCommunicationServer::HandshakeWithClient() { return GetAck() == PacketResult::Success; } + +GDBRemoteCommunication::PacketResult +GDBRemoteCommunicationServer::SendJSONResponse(const json::Value &value) { + std::string json_string; + raw_string_ostream os(json_string); + os << value; + os.flush(); + StreamGDBRemote escaped_response; + escaped_response.PutEscapedBytes(json_string.c_str(), json_string.size()); + return SendPacketNoLock(escaped_response.GetString()); +} + +GDBRemoteCommunication::PacketResult +GDBRemoteCommunicationServer::SendJSONResponse(Expected<json::Value> value) { + if (!value) + return SendErrorResponse(value.takeError()); + return SendJSONResponse(*value); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h index a1cf70f9cd1a..68448eae2b9f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h @@ -72,6 +72,13 @@ protected: PacketResult SendOKResponse(); + /// Serialize and send a JSON object response. + PacketResult SendJSONResponse(const llvm::json::Value &value); + + /// Serialize and send a JSON object response, or respond with an error if the + /// input object is an \a llvm::Error. + PacketResult SendJSONResponse(llvm::Expected<llvm::json::Value> value); + private: GDBRemoteCommunicationServer(const GDBRemoteCommunicationServer &) = delete; const GDBRemoteCommunicationServer & diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp index 1ca0290eda13..b2b802552720 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp @@ -8,7 +8,7 @@ #include "GDBRemoteCommunicationServerCommon.h" -#include <errno.h> +#include <cerrno> #ifdef __APPLE__ #include <TargetConditionals.h> @@ -60,8 +60,7 @@ GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon( const char *comm_name, const char *listener_name) : GDBRemoteCommunicationServer(comm_name, listener_name), m_process_launch_info(), m_process_launch_error(), m_proc_infos(), - m_proc_infos_index(0), m_thread_suffix_supported(false), - m_list_threads_in_stop_reply(false) { + m_proc_infos_index(0) { RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_A, &GDBRemoteCommunicationServerCommon::Handle_A); RegisterMemberFunctionHandler( @@ -86,9 +85,6 @@ GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon( StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess, &GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess); RegisterMemberFunctionHandler( - StringExtractorGDBRemote::eServerPacketType_QListThreadsInStopReply, - &GDBRemoteCommunicationServerCommon::Handle_QListThreadsInStopReply); - RegisterMemberFunctionHandler( StringExtractorGDBRemote::eServerPacketType_qEcho, &GDBRemoteCommunicationServerCommon::Handle_qEcho); RegisterMemberFunctionHandler( @@ -134,9 +130,6 @@ GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon( StringExtractorGDBRemote::eServerPacketType_qSupported, &GDBRemoteCommunicationServerCommon::Handle_qSupported); RegisterMemberFunctionHandler( - StringExtractorGDBRemote::eServerPacketType_QThreadSuffixSupported, - &GDBRemoteCommunicationServerCommon::Handle_QThreadSuffixSupported); - RegisterMemberFunctionHandler( StringExtractorGDBRemote::eServerPacketType_qUserName, &GDBRemoteCommunicationServerCommon::Handle_qUserName); RegisterMemberFunctionHandler( @@ -175,7 +168,8 @@ GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon( } // Destructor -GDBRemoteCommunicationServerCommon::~GDBRemoteCommunicationServerCommon() {} +GDBRemoteCommunicationServerCommon::~GDBRemoteCommunicationServerCommon() = + default; GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerCommon::Handle_qHostInfo( @@ -831,39 +825,10 @@ GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod( GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerCommon::Handle_qSupported( StringExtractorGDBRemote &packet) { - StreamGDBRemote response; - - // Features common to lldb-platform and llgs. - uint32_t max_packet_size = 128 * 1024; // 128KBytes is a reasonable max packet - // size--debugger can always use less - response.Printf("PacketSize=%x", max_packet_size); - - response.PutCString(";QStartNoAckMode+"); - response.PutCString(";QThreadSuffixSupported+"); - response.PutCString(";QListThreadsInStopReply+"); - response.PutCString(";qEcho+"); - response.PutCString(";qXfer:features:read+"); -#if defined(__linux__) || defined(__NetBSD__) || defined(__FreeBSD__) - response.PutCString(";QPassSignals+"); - response.PutCString(";qXfer:auxv:read+"); - response.PutCString(";qXfer:libraries-svr4:read+"); -#endif - - return SendPacketNoLock(response.GetString()); -} - -GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerCommon::Handle_QThreadSuffixSupported( - StringExtractorGDBRemote &packet) { - m_thread_suffix_supported = true; - return SendOKResponse(); -} - -GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerCommon::Handle_QListThreadsInStopReply( - StringExtractorGDBRemote &packet) { - m_list_threads_in_stop_reply = true; - return SendOKResponse(); + // Parse client-indicated features. + llvm::SmallVector<llvm::StringRef, 4> client_features; + packet.GetStringRef().split(client_features, ';'); + return SendPacketNoLock(llvm::join(HandleFeatures(client_features), ";")); } GDBRemoteCommunication::PacketResult @@ -1311,3 +1276,16 @@ GDBRemoteCommunicationServerCommon::GetModuleInfo(llvm::StringRef module_path, return matched_module_spec; } + +std::vector<std::string> GDBRemoteCommunicationServerCommon::HandleFeatures( + const llvm::ArrayRef<llvm::StringRef> client_features) { + // 128KBytes is a reasonable max packet size--debugger can always use less. + constexpr uint32_t max_packet_size = 128 * 1024; + + // Features common to platform server and llgs. + return { + llvm::formatv("PacketSize={0}", max_packet_size), + "QStartNoAckMode+", + "qEcho+", + }; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h index 0f933c09cbd4..ecd80923fcf0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h @@ -36,8 +36,6 @@ protected: Status m_process_launch_error; ProcessInstanceInfoList m_proc_infos; uint32_t m_proc_infos_index; - bool m_thread_suffix_supported; - bool m_list_threads_in_stop_reply; PacketResult Handle_A(StringExtractorGDBRemote &packet); @@ -91,10 +89,6 @@ protected: PacketResult Handle_qSupported(StringExtractorGDBRemote &packet); - PacketResult Handle_QThreadSuffixSupported(StringExtractorGDBRemote &packet); - - PacketResult Handle_QListThreadsInStopReply(StringExtractorGDBRemote &packet); - PacketResult Handle_QSetDetachOnError(StringExtractorGDBRemote &packet); PacketResult Handle_QStartNoAckMode(StringExtractorGDBRemote &packet); @@ -145,6 +139,11 @@ protected: virtual FileSpec FindModuleFile(const std::string &module_path, const ArchSpec &arch); + // Process client_features (qSupported) and return an array of server features + // to be returned in response. + virtual std::vector<std::string> + HandleFeatures(llvm::ArrayRef<llvm::StringRef> client_features); + private: ModuleSpec GetModuleInfo(llvm::StringRef module_path, llvm::StringRef triple); }; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp index 62a09a2a432c..5e69b5793f9f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp @@ -6,13 +6,14 @@ // //===----------------------------------------------------------------------===// -#include <errno.h> +#include <cerrno> #include "lldb/Host/Config.h" #include <chrono> #include <cstring> +#include <limits> #include <thread> #include "GDBRemoteCommunicationServerLLGS.h" @@ -70,6 +71,7 @@ GDBRemoteCommunicationServerLLGS::GDBRemoteCommunicationServerLLGS( : GDBRemoteCommunicationServerCommon("gdb-remote.server", "gdb-remote.server.rx_packet"), m_mainloop(mainloop), m_process_factory(process_factory), + m_current_process(nullptr), m_continue_process(nullptr), m_stdio_communication("process.stdio") { RegisterPacketHandlers(); } @@ -113,6 +115,12 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() { StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir, &GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir); RegisterMemberFunctionHandler( + StringExtractorGDBRemote::eServerPacketType_QThreadSuffixSupported, + &GDBRemoteCommunicationServerLLGS::Handle_QThreadSuffixSupported); + RegisterMemberFunctionHandler( + StringExtractorGDBRemote::eServerPacketType_QListThreadsInStopReply, + &GDBRemoteCommunicationServerLLGS::Handle_QListThreadsInStopReply); + RegisterMemberFunctionHandler( StringExtractorGDBRemote::eServerPacketType_qMemoryRegionInfo, &GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo); RegisterMemberFunctionHandler( @@ -186,27 +194,32 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() { &GDBRemoteCommunicationServerLLGS::Handle_QPassSignals); RegisterMemberFunctionHandler( - StringExtractorGDBRemote::eServerPacketType_jTraceStart, - &GDBRemoteCommunicationServerLLGS::Handle_jTraceStart); + StringExtractorGDBRemote::eServerPacketType_jLLDBTraceSupported, + &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceSupported); RegisterMemberFunctionHandler( - StringExtractorGDBRemote::eServerPacketType_jTraceBufferRead, - &GDBRemoteCommunicationServerLLGS::Handle_jTraceRead); + StringExtractorGDBRemote::eServerPacketType_jLLDBTraceStart, + &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceStart); RegisterMemberFunctionHandler( - StringExtractorGDBRemote::eServerPacketType_jTraceMetaRead, - &GDBRemoteCommunicationServerLLGS::Handle_jTraceRead); + StringExtractorGDBRemote::eServerPacketType_jLLDBTraceStop, + &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceStop); RegisterMemberFunctionHandler( - StringExtractorGDBRemote::eServerPacketType_jTraceStop, - &GDBRemoteCommunicationServerLLGS::Handle_jTraceStop); + StringExtractorGDBRemote::eServerPacketType_jLLDBTraceGetState, + &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceGetState); RegisterMemberFunctionHandler( - StringExtractorGDBRemote::eServerPacketType_jTraceConfigRead, - &GDBRemoteCommunicationServerLLGS::Handle_jTraceConfigRead); - RegisterMemberFunctionHandler( - StringExtractorGDBRemote::eServerPacketType_jLLDBTraceSupportedType, - &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceSupportedType); + StringExtractorGDBRemote::eServerPacketType_jLLDBTraceGetBinaryData, + &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceGetBinaryData); RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_g, &GDBRemoteCommunicationServerLLGS::Handle_g); + RegisterMemberFunctionHandler( + StringExtractorGDBRemote::eServerPacketType_qMemTags, + &GDBRemoteCommunicationServerLLGS::Handle_qMemTags); + + RegisterMemberFunctionHandler( + StringExtractorGDBRemote::eServerPacketType_QMemTags, + &GDBRemoteCommunicationServerLLGS::Handle_QMemTags); + RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_k, [this](StringExtractorGDBRemote packet, Status &error, bool &interrupt, bool &quit) { @@ -245,15 +258,18 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() { { std::lock_guard<std::recursive_mutex> guard(m_debugged_process_mutex); - assert(!m_debugged_process_up && "lldb-server creating debugged " - "process but one already exists"); + assert(m_debugged_processes.empty() && "lldb-server creating debugged " + "process but one already exists"); auto process_or = m_process_factory.Launch(m_process_launch_info, *this, m_mainloop); if (!process_or) return Status(process_or.takeError()); - m_debugged_process_up = std::move(*process_or); + m_continue_process = m_current_process = process_or->get(); + m_debugged_processes[m_current_process->GetID()] = std::move(*process_or); } + SetEnabledExtensions(*m_current_process); + // Handle mirroring of inferior stdout/stderr over the gdb-remote protocol as // needed. llgs local-process debugging may specify PTY paths, which will // make these file actions non-null process launch -i/e/o will also make @@ -266,10 +282,10 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() { LLDB_LOG(log, "pid = {0}: setting up stdout/stderr redirection via $O " "gdb-remote commands", - m_debugged_process_up->GetID()); + m_current_process->GetID()); // Setup stdout/stderr mapping from inferior to $O - auto terminal_fd = m_debugged_process_up->GetTerminalFileDescriptor(); + auto terminal_fd = m_current_process->GetTerminalFileDescriptor(); if (terminal_fd >= 0) { LLDB_LOGF(log, "ProcessGDBRemoteCommunicationServerLLGS::%s setting " @@ -288,12 +304,12 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() { LLDB_LOG(log, "pid = {0} skipping stdout/stderr redirection via $O: inferior " "will communicate over client-provided file descriptors", - m_debugged_process_up->GetID()); + m_current_process->GetID()); } printf("Launched '%s' as process %" PRIu64 "...\n", m_process_launch_info.GetArguments().GetArgumentAtIndex(0), - m_debugged_process_up->GetID()); + m_current_process->GetID()); return Status(); } @@ -305,12 +321,11 @@ Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) { // Before we try to attach, make sure we aren't already monitoring something // else. - if (m_debugged_process_up && - m_debugged_process_up->GetID() != LLDB_INVALID_PROCESS_ID) + if (!m_debugged_processes.empty()) return Status("cannot attach to process %" PRIu64 " when another process with pid %" PRIu64 " is being debugged.", - pid, m_debugged_process_up->GetID()); + pid, m_current_process->GetID()); // Try to attach. auto process_or = m_process_factory.Attach(pid, *this, m_mainloop); @@ -320,10 +335,12 @@ Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) { status); return status; } - m_debugged_process_up = std::move(*process_or); + m_continue_process = m_current_process = process_or->get(); + m_debugged_processes[m_current_process->GetID()] = std::move(*process_or); + SetEnabledExtensions(*m_current_process); // Setup stdout/stderr mapping from inferior. - auto terminal_fd = m_debugged_process_up->GetTerminalFileDescriptor(); + auto terminal_fd = m_current_process->GetTerminalFileDescriptor(); if (terminal_fd >= 0) { LLDB_LOGF(log, "ProcessGDBRemoteCommunicationServerLLGS::%s setting " @@ -648,6 +665,14 @@ static const char *GetStopReasonString(StopReason stop_reason) { return "exception"; case eStopReasonExec: return "exec"; + case eStopReasonProcessorTrace: + return "processor trace"; + case eStopReasonFork: + return "fork"; + case eStopReasonVFork: + return "vfork"; + case eStopReasonVForkDone: + return "vforkdone"; case eStopReasonInstrumentation: case eStopReasonInvalid: case eStopReasonPlanComplete: @@ -736,15 +761,15 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); // Ensure we have a debugged process. - if (!m_debugged_process_up || - (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) + if (!m_current_process || + (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) return SendErrorResponse(50); LLDB_LOG(log, "preparing packet for pid {0} tid {1}", - m_debugged_process_up->GetID(), tid); + m_current_process->GetID(), tid); // Ensure we can get info on the given thread. - NativeThreadProtocol *thread = m_debugged_process_up->GetThreadByID(tid); + NativeThreadProtocol *thread = m_current_process->GetThreadByID(tid); if (!thread) return SendErrorResponse(51); @@ -767,7 +792,7 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( LLDB_LOG( log, "pid {0}, tid {1}, got signal signo = {2}, reason = {3}, exc_type = {4}", - m_debugged_process_up->GetID(), tid, signum, int(tid_stop_info.reason), + m_current_process->GetID(), tid, signum, int(tid_stop_info.reason), tid_stop_info.details.exception.type); // Print the signal number. @@ -805,9 +830,9 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( uint32_t thread_index = 0; NativeThreadProtocol *listed_thread; - for (listed_thread = m_debugged_process_up->GetThreadAtIndex(thread_index); + for (listed_thread = m_current_process->GetThreadAtIndex(thread_index); listed_thread; ++thread_index, - listed_thread = m_debugged_process_up->GetThreadAtIndex(thread_index)) { + listed_thread = m_current_process->GetThreadAtIndex(thread_index)) { if (thread_index > 0) response.PutChar(','); response.Printf("%" PRIx64, listed_thread->GetID()); @@ -822,7 +847,7 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( if (thread_index > 1) { const bool threads_with_valid_stop_info_only = true; llvm::Expected<json::Array> threads_info = GetJSONThreadsInfo( - *m_debugged_process_up, threads_with_valid_stop_info_only); + *m_current_process, threads_with_valid_stop_info_only); if (threads_info) { response.PutCString("jstopinfo:"); StreamString unescaped_response; @@ -832,7 +857,7 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( } else { LLDB_LOG_ERROR(log, threads_info.takeError(), "failed to prepare a jstopinfo field for pid {1}: {0}", - m_debugged_process_up->GetID()); + m_current_process->GetID()); } } @@ -840,8 +865,7 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( response.PutCString("thread-pcs"); char delimiter = ':'; for (NativeThreadProtocol *thread; - (thread = m_debugged_process_up->GetThreadAtIndex(i)) != nullptr; - ++i) { + (thread = m_current_process->GetThreadAtIndex(i)) != nullptr; ++i) { NativeRegisterContext& reg_ctx = thread->GetRegisterContext(); uint32_t reg_to_read = reg_ctx.ConvertRegisterKindToRegisterNumber( @@ -924,6 +948,22 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( } } + // Include child process PID/TID for forks. + if (tid_stop_info.reason == eStopReasonFork || + tid_stop_info.reason == eStopReasonVFork) { + assert(bool(m_extensions_supported & + NativeProcessProtocol::Extension::multiprocess)); + if (tid_stop_info.reason == eStopReasonFork) + assert(bool(m_extensions_supported & + NativeProcessProtocol::Extension::fork)); + if (tid_stop_info.reason == eStopReasonVFork) + assert(bool(m_extensions_supported & + NativeProcessProtocol::Extension::vfork)); + response.Printf("%s:p%" PRIx64 ".%" PRIx64 ";", reason_str, + tid_stop_info.details.fork.child_pid, + tid_stop_info.details.fork.child_tid); + } + return SendPacketNoLock(response.GetString()); } @@ -1028,6 +1068,15 @@ void GDBRemoteCommunicationServerLLGS::DidExec(NativeProcessProtocol *process) { ClearProcessSpecificData(); } +void GDBRemoteCommunicationServerLLGS::NewSubprocess( + NativeProcessProtocol *parent_process, + std::unique_ptr<NativeProcessProtocol> child_process) { + lldb::pid_t child_pid = child_process->GetID(); + assert(child_pid != LLDB_INVALID_PROCESS_ID); + assert(m_debugged_processes.find(child_pid) == m_debugged_processes.end()); + m_debugged_processes[child_pid] = std::move(child_process); +} + void GDBRemoteCommunicationServerLLGS::DataAvailableCallback() { Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_COMM)); @@ -1170,266 +1219,110 @@ void GDBRemoteCommunicationServerLLGS::SendProcessOutput() { } GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_jTraceStart( +GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceSupported( StringExtractorGDBRemote &packet) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); - // Fail if we don't have a current process. - if (!m_debugged_process_up || - (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) - return SendErrorResponse(68); - - if (!packet.ConsumeFront("jTraceStart:")) - return SendIllFormedResponse(packet, "jTraceStart: Ill formed packet "); - - TraceOptions options; - uint64_t type = std::numeric_limits<uint64_t>::max(); - uint64_t buffersize = std::numeric_limits<uint64_t>::max(); - lldb::tid_t tid = LLDB_INVALID_THREAD_ID; - uint64_t metabuffersize = std::numeric_limits<uint64_t>::max(); - - auto json_object = StructuredData::ParseJSON(packet.Peek()); - - if (!json_object || - json_object->GetType() != lldb::eStructuredDataTypeDictionary) - return SendIllFormedResponse(packet, "jTraceStart: Ill formed packet "); - - auto json_dict = json_object->GetAsDictionary(); - - json_dict->GetValueForKeyAsInteger("metabuffersize", metabuffersize); - options.setMetaDataBufferSize(metabuffersize); - json_dict->GetValueForKeyAsInteger("buffersize", buffersize); - options.setTraceBufferSize(buffersize); - - json_dict->GetValueForKeyAsInteger("type", type); - options.setType(static_cast<lldb::TraceType>(type)); - - json_dict->GetValueForKeyAsInteger("threadid", tid); - options.setThreadID(tid); - - StructuredData::ObjectSP custom_params_sp = - json_dict->GetValueForKey("params"); - if (custom_params_sp && - custom_params_sp->GetType() != lldb::eStructuredDataTypeDictionary) - return SendIllFormedResponse(packet, "jTraceStart: Ill formed packet "); - - options.setTraceParams( - std::static_pointer_cast<StructuredData::Dictionary>(custom_params_sp)); - - if (buffersize == std::numeric_limits<uint64_t>::max() || - type != lldb::TraceType::eTraceTypeProcessorTrace) { - LLDB_LOG(log, "Ill formed packet buffersize = {0} type = {1}", buffersize, - type); - return SendIllFormedResponse(packet, "JTrace:start: Ill formed packet "); - } - - Status error; - lldb::user_id_t uid = LLDB_INVALID_UID; - uid = m_debugged_process_up->StartTrace(options, error); - LLDB_LOG(log, "uid is {0} , error is {1}", uid, error.GetError()); - if (error.Fail()) - return SendErrorResponse(error); + // Fail if we don't have a current process. + if (!m_current_process || + (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) + return SendErrorResponse(Status("Process not running.")); - StreamGDBRemote response; - response.Printf("%" PRIx64, uid); - return SendPacketNoLock(response.GetString()); + return SendJSONResponse(m_current_process->TraceSupported()); } GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_jTraceStop( +GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceStop( StringExtractorGDBRemote &packet) { // Fail if we don't have a current process. - if (!m_debugged_process_up || - (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) - return SendErrorResponse(68); - - if (!packet.ConsumeFront("jTraceStop:")) - return SendIllFormedResponse(packet, "jTraceStop: Ill formed packet "); - - lldb::user_id_t uid = LLDB_INVALID_UID; - lldb::tid_t tid = LLDB_INVALID_THREAD_ID; - - auto json_object = StructuredData::ParseJSON(packet.Peek()); - - if (!json_object || - json_object->GetType() != lldb::eStructuredDataTypeDictionary) - return SendIllFormedResponse(packet, "jTraceStop: Ill formed packet "); - - auto json_dict = json_object->GetAsDictionary(); - - if (!json_dict->GetValueForKeyAsInteger("traceid", uid)) - return SendIllFormedResponse(packet, "jTraceStop: Ill formed packet "); + if (!m_current_process || + (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) + return SendErrorResponse(Status("Process not running.")); - json_dict->GetValueForKeyAsInteger("threadid", tid); + packet.ConsumeFront("jLLDBTraceStop:"); + Expected<TraceStopRequest> stop_request = + json::parse<TraceStopRequest>(packet.Peek(), "TraceStopRequest"); + if (!stop_request) + return SendErrorResponse(stop_request.takeError()); - Status error = m_debugged_process_up->StopTrace(uid, tid); - - if (error.Fail()) - return SendErrorResponse(error); + if (Error err = m_current_process->TraceStop(*stop_request)) + return SendErrorResponse(std::move(err)); return SendOKResponse(); } GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceSupportedType( +GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceStart( StringExtractorGDBRemote &packet) { // Fail if we don't have a current process. - if (!m_debugged_process_up || - (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) + if (!m_current_process || + (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) return SendErrorResponse(Status("Process not running.")); - llvm::Expected<TraceTypeInfo> supported_trace_type = - m_debugged_process_up->GetSupportedTraceType(); - if (!supported_trace_type) - return SendErrorResponse(supported_trace_type.takeError()); + packet.ConsumeFront("jLLDBTraceStart:"); + Expected<TraceStartRequest> request = + json::parse<TraceStartRequest>(packet.Peek(), "TraceStartRequest"); + if (!request) + return SendErrorResponse(request.takeError()); - StreamGDBRemote escaped_response; - StructuredData::Dictionary json_packet; + if (Error err = m_current_process->TraceStart(packet.Peek(), request->type)) + return SendErrorResponse(std::move(err)); - json_packet.AddStringItem("name", supported_trace_type->name); - json_packet.AddStringItem("description", supported_trace_type->description); - - StreamString json_string; - json_packet.Dump(json_string, false); - escaped_response.PutEscapedBytes(json_string.GetData(), - json_string.GetSize()); - return SendPacketNoLock(escaped_response.GetString()); + return SendOKResponse(); } GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_jTraceConfigRead( +GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceGetState( StringExtractorGDBRemote &packet) { // Fail if we don't have a current process. - if (!m_debugged_process_up || - (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) - return SendErrorResponse(68); - - if (!packet.ConsumeFront("jTraceConfigRead:")) - return SendIllFormedResponse(packet, - "jTraceConfigRead: Ill formed packet "); - - lldb::user_id_t uid = LLDB_INVALID_UID; - lldb::tid_t threadid = LLDB_INVALID_THREAD_ID; - - auto json_object = StructuredData::ParseJSON(packet.Peek()); - - if (!json_object || - json_object->GetType() != lldb::eStructuredDataTypeDictionary) - return SendIllFormedResponse(packet, - "jTraceConfigRead: Ill formed packet "); - - auto json_dict = json_object->GetAsDictionary(); - - if (!json_dict->GetValueForKeyAsInteger("traceid", uid)) - return SendIllFormedResponse(packet, - "jTraceConfigRead: Ill formed packet "); - - json_dict->GetValueForKeyAsInteger("threadid", threadid); - - TraceOptions options; - StreamGDBRemote response; - - options.setThreadID(threadid); - Status error = m_debugged_process_up->GetTraceConfig(uid, options); - - if (error.Fail()) - return SendErrorResponse(error); - - StreamGDBRemote escaped_response; - StructuredData::Dictionary json_packet; - - json_packet.AddIntegerItem("type", options.getType()); - json_packet.AddIntegerItem("buffersize", options.getTraceBufferSize()); - json_packet.AddIntegerItem("metabuffersize", options.getMetaDataBufferSize()); + if (!m_current_process || + (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) + return SendErrorResponse(Status("Process not running.")); - StructuredData::DictionarySP custom_params = options.getTraceParams(); - if (custom_params) - json_packet.AddItem("params", custom_params); + packet.ConsumeFront("jLLDBTraceGetState:"); + Expected<TraceGetStateRequest> request = + json::parse<TraceGetStateRequest>(packet.Peek(), "TraceGetStateRequest"); + if (!request) + return SendErrorResponse(request.takeError()); - StreamString json_string; - json_packet.Dump(json_string, false); - escaped_response.PutEscapedBytes(json_string.GetData(), - json_string.GetSize()); - return SendPacketNoLock(escaped_response.GetString()); + return SendJSONResponse(m_current_process->TraceGetState(request->type)); } GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_jTraceRead( +GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceGetBinaryData( StringExtractorGDBRemote &packet) { // Fail if we don't have a current process. - if (!m_debugged_process_up || - (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) - return SendErrorResponse(68); - - enum PacketType { MetaData, BufferData }; - PacketType tracetype = MetaData; - - if (packet.ConsumeFront("jTraceBufferRead:")) - tracetype = BufferData; - else if (packet.ConsumeFront("jTraceMetaRead:")) - tracetype = MetaData; - else { - return SendIllFormedResponse(packet, "jTrace: Ill formed packet "); - } - - lldb::user_id_t uid = LLDB_INVALID_UID; - - uint64_t byte_count = std::numeric_limits<uint64_t>::max(); - lldb::tid_t tid = LLDB_INVALID_THREAD_ID; - uint64_t offset = std::numeric_limits<uint64_t>::max(); - - auto json_object = StructuredData::ParseJSON(packet.Peek()); - - if (!json_object || - json_object->GetType() != lldb::eStructuredDataTypeDictionary) - return SendIllFormedResponse(packet, "jTrace: Ill formed packet "); - - auto json_dict = json_object->GetAsDictionary(); - - if (!json_dict->GetValueForKeyAsInteger("traceid", uid) || - !json_dict->GetValueForKeyAsInteger("offset", offset) || - !json_dict->GetValueForKeyAsInteger("buffersize", byte_count)) - return SendIllFormedResponse(packet, "jTrace: Ill formed packet "); - - json_dict->GetValueForKeyAsInteger("threadid", tid); - - // Allocate the response buffer. - std::unique_ptr<uint8_t[]> buffer (new (std::nothrow) uint8_t[byte_count]); - if (!buffer) - return SendErrorResponse(0x78); - - StreamGDBRemote response; - Status error; - llvm::MutableArrayRef<uint8_t> buf(buffer.get(), byte_count); - - if (tracetype == BufferData) - error = m_debugged_process_up->GetData(uid, tid, buf, offset); - else if (tracetype == MetaData) - error = m_debugged_process_up->GetMetaData(uid, tid, buf, offset); - - if (error.Fail()) - return SendErrorResponse(error); + if (!m_current_process || + (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) + return SendErrorResponse(Status("Process not running.")); - for (auto i : buf) - response.PutHex8(i); + packet.ConsumeFront("jLLDBTraceGetBinaryData:"); + llvm::Expected<TraceGetBinaryDataRequest> request = + llvm::json::parse<TraceGetBinaryDataRequest>(packet.Peek(), + "TraceGetBinaryDataRequest"); + if (!request) + return SendErrorResponse(Status(request.takeError())); - StreamGDBRemote escaped_response; - escaped_response.PutEscapedBytes(response.GetData(), response.GetSize()); - return SendPacketNoLock(escaped_response.GetString()); + if (Expected<std::vector<uint8_t>> bytes = + m_current_process->TraceGetBinaryData(*request)) { + StreamGDBRemote response; + response.PutEscapedBytes(bytes->data(), bytes->size()); + return SendPacketNoLock(response.GetString()); + } else + return SendErrorResponse(bytes.takeError()); } GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_qProcessInfo( StringExtractorGDBRemote &packet) { // Fail if we don't have a current process. - if (!m_debugged_process_up || - (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) + if (!m_current_process || + (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) return SendErrorResponse(68); - lldb::pid_t pid = m_debugged_process_up->GetID(); + lldb::pid_t pid = m_current_process->GetID(); if (pid == LLDB_INVALID_PROCESS_ID) return SendErrorResponse(1); @@ -1446,16 +1339,16 @@ GDBRemoteCommunicationServerLLGS::Handle_qProcessInfo( GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_qC(StringExtractorGDBRemote &packet) { // Fail if we don't have a current process. - if (!m_debugged_process_up || - (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) + if (!m_current_process || + (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) return SendErrorResponse(68); // Make sure we set the current thread so g and p packets return the data the // gdb will expect. - lldb::tid_t tid = m_debugged_process_up->GetCurrentThreadID(); + lldb::tid_t tid = m_current_process->GetCurrentThreadID(); SetCurrentThreadID(tid); - NativeThreadProtocol *thread = m_debugged_process_up->GetCurrentThread(); + NativeThreadProtocol *thread = m_current_process->GetCurrentThread(); if (!thread) return SendErrorResponse(69); @@ -1471,15 +1364,15 @@ GDBRemoteCommunicationServerLLGS::Handle_k(StringExtractorGDBRemote &packet) { StopSTDIOForwarding(); - if (!m_debugged_process_up) { + if (!m_current_process) { LLDB_LOG(log, "No debugged process found."); return PacketResult::Success; } - Status error = m_debugged_process_up->Kill(); + Status error = m_current_process->Kill(); if (error.Fail()) LLDB_LOG(log, "Failed to kill debugged process {0}: {1}", - m_debugged_process_up->GetID(), error); + m_current_process->GetID(), error); // No OK response for kill packet. // return SendOKResponse (); @@ -1521,12 +1414,26 @@ GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir( } GDBRemoteCommunication::PacketResult +GDBRemoteCommunicationServerLLGS::Handle_QThreadSuffixSupported( + StringExtractorGDBRemote &packet) { + m_thread_suffix_supported = true; + return SendOKResponse(); +} + +GDBRemoteCommunication::PacketResult +GDBRemoteCommunicationServerLLGS::Handle_QListThreadsInStopReply( + StringExtractorGDBRemote &packet) { + m_list_threads_in_stop_reply = true; + return SendOKResponse(); +} + +GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_C(StringExtractorGDBRemote &packet) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); // Ensure we have a native process. - if (!m_debugged_process_up) { + if (!m_continue_process) { LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s no debugged process " "shared pointer", @@ -1579,20 +1486,20 @@ GDBRemoteCommunicationServerLLGS::Handle_C(StringExtractorGDBRemote &packet) { } else { // Send the signal to the process since we weren't targeting a specific // continue thread with the signal. - error = m_debugged_process_up->Signal(signo); + error = m_continue_process->Signal(signo); if (error.Fail()) { LLDB_LOG(log, "failed to send signal for process {0}: {1}", - m_debugged_process_up->GetID(), error); + m_continue_process->GetID(), error); return SendErrorResponse(0x52); } } // Resume the threads. - error = m_debugged_process_up->Resume(resume_actions); + error = m_continue_process->Resume(resume_actions); if (error.Fail()) { LLDB_LOG(log, "failed to resume threads for process {0}: {1}", - m_debugged_process_up->GetID(), error); + m_continue_process->GetID(), error); return SendErrorResponse(0x38); } @@ -1617,7 +1524,7 @@ GDBRemoteCommunicationServerLLGS::Handle_c(StringExtractorGDBRemote &packet) { } // Ensure we have a native process. - if (!m_debugged_process_up) { + if (!m_continue_process) { LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s no debugged process " "shared pointer", @@ -1629,14 +1536,14 @@ GDBRemoteCommunicationServerLLGS::Handle_c(StringExtractorGDBRemote &packet) { ResumeActionList actions(StateType::eStateRunning, LLDB_INVALID_SIGNAL_NUMBER); - Status error = m_debugged_process_up->Resume(actions); + Status error = m_continue_process->Resume(actions); if (error.Fail()) { - LLDB_LOG(log, "c failed for process {0}: {1}", - m_debugged_process_up->GetID(), error); + LLDB_LOG(log, "c failed for process {0}: {1}", m_continue_process->GetID(), + error); return SendErrorResponse(GDBRemoteServerError::eErrorResume); } - LLDB_LOG(log, "continued process {0}", m_debugged_process_up->GetID()); + LLDB_LOG(log, "continued process {0}", m_continue_process->GetID()); // No response required from continue. return PacketResult::Success; } @@ -1679,7 +1586,7 @@ GDBRemoteCommunicationServerLLGS::Handle_vCont( } // Ensure we have a native process. - if (!m_debugged_process_up) { + if (!m_continue_process) { LLDB_LOG(log, "no debugged process"); return SendErrorResponse(0x36); } @@ -1732,23 +1639,27 @@ GDBRemoteCommunicationServerLLGS::Handle_vCont( // Consume the separator. packet.GetChar(); - thread_action.tid = packet.GetHexMaxU32(false, LLDB_INVALID_THREAD_ID); - if (thread_action.tid == LLDB_INVALID_THREAD_ID) - return SendIllFormedResponse( - packet, "Could not parse thread number in vCont packet"); + llvm::Expected<lldb::tid_t> tid_ret = + ReadTid(packet, /*allow_all=*/true, m_continue_process->GetID()); + if (!tid_ret) + return SendErrorResponse(tid_ret.takeError()); + + thread_action.tid = tid_ret.get(); + if (thread_action.tid == StringExtractorGDBRemote::AllThreads) + thread_action.tid = LLDB_INVALID_THREAD_ID; } thread_actions.Append(thread_action); } - Status error = m_debugged_process_up->Resume(thread_actions); + Status error = m_continue_process->Resume(thread_actions); if (error.Fail()) { LLDB_LOG(log, "vCont failed for process {0}: {1}", - m_debugged_process_up->GetID(), error); + m_continue_process->GetID(), error); return SendErrorResponse(GDBRemoteServerError::eErrorResume); } - LLDB_LOG(log, "continued process {0}", m_debugged_process_up->GetID()); + LLDB_LOG(log, "continued process {0}", m_continue_process->GetID()); // No response required from vCont. return PacketResult::Success; } @@ -1758,8 +1669,8 @@ void GDBRemoteCommunicationServerLLGS::SetCurrentThreadID(lldb::tid_t tid) { LLDB_LOG(log, "setting current thread id to {0}", tid); m_current_tid = tid; - if (m_debugged_process_up) - m_debugged_process_up->SetCurrentThreadID(m_current_tid); + if (m_current_process) + m_current_process->SetCurrentThreadID(m_current_tid); } void GDBRemoteCommunicationServerLLGS::SetContinueThreadID(lldb::tid_t tid) { @@ -1775,10 +1686,10 @@ GDBRemoteCommunicationServerLLGS::Handle_stop_reason( // Handle the $? gdbremote command. // If no process, indicate error - if (!m_debugged_process_up) + if (!m_current_process) return SendErrorResponse(02); - return SendStopReasonForState(m_debugged_process_up->GetState()); + return SendStopReasonForState(m_current_process->GetState()); } GDBRemoteCommunication::PacketResult @@ -1799,8 +1710,8 @@ GDBRemoteCommunicationServerLLGS::SendStopReasonForState( case eStateSuspended: case eStateStopped: case eStateCrashed: { - assert(m_debugged_process_up != nullptr); - lldb::tid_t tid = m_debugged_process_up->GetCurrentThreadID(); + assert(m_current_process != nullptr); + lldb::tid_t tid = m_current_process->GetCurrentThreadID(); // Make sure we set the current thread so g and p packets return the data // the gdb will expect. SetCurrentThreadID(tid); @@ -1810,11 +1721,11 @@ GDBRemoteCommunicationServerLLGS::SendStopReasonForState( case eStateInvalid: case eStateUnloaded: case eStateExited: - return SendWResponse(m_debugged_process_up.get()); + return SendWResponse(m_current_process); default: LLDB_LOG(log, "pid {0}, current state reporting not handled: {1}", - m_debugged_process_up->GetID(), process_state); + m_current_process->GetID(), process_state); break; } @@ -1825,12 +1736,12 @@ GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo( StringExtractorGDBRemote &packet) { // Fail if we don't have a current process. - if (!m_debugged_process_up || - (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) + if (!m_current_process || + (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) return SendErrorResponse(68); // Ensure we have a thread. - NativeThreadProtocol *thread = m_debugged_process_up->GetThreadAtIndex(0); + NativeThreadProtocol *thread = m_current_process->GetThreadAtIndex(0); if (!thread) return SendErrorResponse(69); @@ -1925,11 +1836,11 @@ GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo( Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); // Fail if we don't have a current process. - if (!m_debugged_process_up || - (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) { + if (!m_current_process || + (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { LLDB_LOG(log, "no process ({0}), returning OK", - m_debugged_process_up ? "invalid process id" - : "null m_debugged_process_up"); + m_current_process ? "invalid process id" + : "null m_current_process"); return SendOKResponse(); } @@ -1940,9 +1851,9 @@ GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo( NativeThreadProtocol *thread; uint32_t thread_index; for (thread_index = 0, - thread = m_debugged_process_up->GetThreadAtIndex(thread_index); + thread = m_current_process->GetThreadAtIndex(thread_index); thread; ++thread_index, - thread = m_debugged_process_up->GetThreadAtIndex(thread_index)) { + thread = m_current_process->GetThreadAtIndex(thread_index)) { LLDB_LOG(log, "iterated thread {0}(tid={2})", thread_index, thread->GetID()); if (thread_index > 0) @@ -2163,9 +2074,8 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) { // Build the reginfos response. StreamGDBRemote response; - RegisterValue reg_value( - makeArrayRef(reg_bytes, reg_size), - m_debugged_process_up->GetArchitecture().GetByteOrder()); + RegisterValue reg_value(makeArrayRef(reg_bytes, reg_size), + m_current_process->GetArchitecture().GetByteOrder()); Status error = reg_context.WriteRegister(reg_info, reg_value); if (error.Fail()) { LLDB_LOGF(log, @@ -2182,16 +2092,6 @@ GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); - // Fail if we don't have a current process. - if (!m_debugged_process_up || - (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) { - LLDB_LOGF( - log, - "GDBRemoteCommunicationServerLLGS::%s failed, no process available", - __FUNCTION__); - return SendErrorResponse(0x15); - } - // Parse out which variant of $H is requested. packet.SetFilePos(strlen("H")); if (packet.GetBytesLeft() < 1) { @@ -2203,11 +2103,14 @@ GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) { } const char h_variant = packet.GetChar(); + NativeProcessProtocol *default_process; switch (h_variant) { case 'g': + default_process = m_current_process; break; case 'c': + default_process = m_continue_process; break; default: @@ -2220,14 +2123,32 @@ GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) { } // Parse out the thread number. - // FIXME return a parse success/fail value. All values are valid here. - const lldb::tid_t tid = - packet.GetHexMaxU64(false, std::numeric_limits<lldb::tid_t>::max()); + auto pid_tid = packet.GetPidTid(default_process ? default_process->GetID() + : LLDB_INVALID_PROCESS_ID); + if (!pid_tid) + return SendErrorResponse(llvm::make_error<StringError>( + inconvertibleErrorCode(), "Malformed thread-id")); + + lldb::pid_t pid = pid_tid->first; + lldb::tid_t tid = pid_tid->second; + + if (pid == StringExtractorGDBRemote::AllProcesses) + return SendUnimplementedResponse("Selecting all processes not supported"); + if (pid == LLDB_INVALID_PROCESS_ID) + return SendErrorResponse(llvm::make_error<StringError>( + inconvertibleErrorCode(), "No current process and no PID provided")); + + // Check the process ID and find respective process instance. + auto new_process_it = m_debugged_processes.find(pid); + if (new_process_it == m_debugged_processes.end()) + return SendErrorResponse(llvm::make_error<StringError>( + inconvertibleErrorCode(), + llvm::formatv("No process with PID {0} debugged", pid))); // Ensure we have the given thread when not specifying -1 (all threads) or 0 // (any thread). if (tid != LLDB_INVALID_THREAD_ID && tid != 0) { - NativeThreadProtocol *thread = m_debugged_process_up->GetThreadByID(tid); + NativeThreadProtocol *thread = new_process_it->second->GetThreadByID(tid); if (!thread) { LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s failed, tid %" PRIu64 @@ -2237,13 +2158,15 @@ GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) { } } - // Now switch the given thread type. + // Now switch the given process and thread type. switch (h_variant) { case 'g': + m_current_process = new_process_it->second.get(); SetCurrentThreadID(tid); break; case 'c': + m_continue_process = new_process_it->second.get(); SetContinueThreadID(tid); break; @@ -2261,8 +2184,8 @@ GDBRemoteCommunicationServerLLGS::Handle_I(StringExtractorGDBRemote &packet) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); // Fail if we don't have a current process. - if (!m_debugged_process_up || - (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) { + if (!m_current_process || + (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { LLDB_LOGF( log, "GDBRemoteCommunicationServerLLGS::%s failed, no process available", @@ -2297,21 +2220,21 @@ GDBRemoteCommunicationServerLLGS::Handle_interrupt( Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); // Fail if we don't have a current process. - if (!m_debugged_process_up || - (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) { + if (!m_current_process || + (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { LLDB_LOG(log, "failed, no process available"); return SendErrorResponse(0x15); } // Interrupt the process. - Status error = m_debugged_process_up->Interrupt(); + Status error = m_current_process->Interrupt(); if (error.Fail()) { - LLDB_LOG(log, "failed for process {0}: {1}", m_debugged_process_up->GetID(), + LLDB_LOG(log, "failed for process {0}: {1}", m_current_process->GetID(), error); return SendErrorResponse(GDBRemoteServerError::eErrorResume); } - LLDB_LOG(log, "stopped process {0}", m_debugged_process_up->GetID()); + LLDB_LOG(log, "stopped process {0}", m_current_process->GetID()); // No response required from stop all. return PacketResult::Success; @@ -2322,8 +2245,8 @@ GDBRemoteCommunicationServerLLGS::Handle_memory_read( StringExtractorGDBRemote &packet) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); - if (!m_debugged_process_up || - (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) { + if (!m_current_process || + (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { LLDB_LOGF( log, "GDBRemoteCommunicationServerLLGS::%s failed, no process available", @@ -2365,13 +2288,13 @@ GDBRemoteCommunicationServerLLGS::Handle_memory_read( // Retrieve the process memory. size_t bytes_read = 0; - Status error = m_debugged_process_up->ReadMemoryWithoutTrap( + Status error = m_current_process->ReadMemoryWithoutTrap( read_addr, &buf[0], byte_count, bytes_read); if (error.Fail()) { LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " mem 0x%" PRIx64 ": failed to read. Error: %s", - __FUNCTION__, m_debugged_process_up->GetID(), read_addr, + __FUNCTION__, m_current_process->GetID(), read_addr, error.AsCString()); return SendErrorResponse(0x08); } @@ -2380,8 +2303,7 @@ GDBRemoteCommunicationServerLLGS::Handle_memory_read( LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " mem 0x%" PRIx64 ": read 0 of %" PRIu64 " requested bytes", - __FUNCTION__, m_debugged_process_up->GetID(), read_addr, - byte_count); + __FUNCTION__, m_current_process->GetID(), read_addr, byte_count); return SendErrorResponse(0x08); } @@ -2403,8 +2325,8 @@ GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle__M(StringExtractorGDBRemote &packet) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); - if (!m_debugged_process_up || - (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) { + if (!m_current_process || + (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { LLDB_LOGF( log, "GDBRemoteCommunicationServerLLGS::%s failed, no process available", @@ -2439,8 +2361,7 @@ GDBRemoteCommunicationServerLLGS::Handle__M(StringExtractorGDBRemote &packet) { } } - llvm::Expected<addr_t> addr = - m_debugged_process_up->AllocateMemory(size, perms); + llvm::Expected<addr_t> addr = m_current_process->AllocateMemory(size, perms); if (!addr) return SendErrorResponse(addr.takeError()); @@ -2453,8 +2374,8 @@ GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle__m(StringExtractorGDBRemote &packet) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); - if (!m_debugged_process_up || - (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) { + if (!m_current_process || + (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { LLDB_LOGF( log, "GDBRemoteCommunicationServerLLGS::%s failed, no process available", @@ -2471,7 +2392,7 @@ GDBRemoteCommunicationServerLLGS::Handle__m(StringExtractorGDBRemote &packet) { if (addr == LLDB_INVALID_ADDRESS) return SendIllFormedResponse(packet, "Address not valid"); - if (llvm::Error Err = m_debugged_process_up->DeallocateMemory(addr)) + if (llvm::Error Err = m_current_process->DeallocateMemory(addr)) return SendErrorResponse(std::move(Err)); return SendOKResponse(); @@ -2481,8 +2402,8 @@ GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_M(StringExtractorGDBRemote &packet) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); - if (!m_debugged_process_up || - (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) { + if (!m_current_process || + (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { LLDB_LOGF( log, "GDBRemoteCommunicationServerLLGS::%s failed, no process available", @@ -2531,8 +2452,7 @@ GDBRemoteCommunicationServerLLGS::Handle_M(StringExtractorGDBRemote &packet) { LLDB_LOG(log, "pid {0} mem {1:x}: asked to write {2} bytes, but only found {3} " "to convert.", - m_debugged_process_up->GetID(), write_addr, byte_count, - convert_count); + m_current_process->GetID(), write_addr, byte_count, convert_count); return SendIllFormedResponse(packet, "M content byte length specified did " "not match hex-encoded content " "length"); @@ -2540,17 +2460,17 @@ GDBRemoteCommunicationServerLLGS::Handle_M(StringExtractorGDBRemote &packet) { // Write the process memory. size_t bytes_written = 0; - Status error = m_debugged_process_up->WriteMemory(write_addr, &buf[0], - byte_count, bytes_written); + Status error = m_current_process->WriteMemory(write_addr, &buf[0], byte_count, + bytes_written); if (error.Fail()) { LLDB_LOG(log, "pid {0} mem {1:x}: failed to write. Error: {2}", - m_debugged_process_up->GetID(), write_addr, error); + m_current_process->GetID(), write_addr, error); return SendErrorResponse(0x09); } if (bytes_written == 0) { LLDB_LOG(log, "pid {0} mem {1:x}: wrote 0 of {2} requested bytes", - m_debugged_process_up->GetID(), write_addr, byte_count); + m_current_process->GetID(), write_addr, byte_count); return SendErrorResponse(0x09); } @@ -2569,8 +2489,8 @@ GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported( // Ensure we have a process running; otherwise, we can't figure this out // since we won't have a NativeProcessProtocol. - if (!m_debugged_process_up || - (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) { + if (!m_current_process || + (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { LLDB_LOGF( log, "GDBRemoteCommunicationServerLLGS::%s failed, no process available", @@ -2580,8 +2500,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported( // Test if we can get any region back when asking for the region around NULL. MemoryRegionInfo region_info; - const Status error = - m_debugged_process_up->GetMemoryRegionInfo(0, region_info); + const Status error = m_current_process->GetMemoryRegionInfo(0, region_info); if (error.Fail()) { // We don't support memory region info collection for this // NativeProcessProtocol. @@ -2597,8 +2516,8 @@ GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo( Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); // Ensure we have a process. - if (!m_debugged_process_up || - (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) { + if (!m_current_process || + (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { LLDB_LOGF( log, "GDBRemoteCommunicationServerLLGS::%s failed, no process available", @@ -2619,7 +2538,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo( // Get the memory region info for the target address. MemoryRegionInfo region_info; const Status error = - m_debugged_process_up->GetMemoryRegionInfo(read_addr, region_info); + m_current_process->GetMemoryRegionInfo(read_addr, region_info); if (error.Fail()) { // Return the error message. @@ -2674,8 +2593,8 @@ GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo( GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_Z(StringExtractorGDBRemote &packet) { // Ensure we have a process. - if (!m_debugged_process_up || - (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) { + if (!m_current_process || + (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); LLDB_LOG(log, "failed, no process available"); return SendErrorResponse(0x15); @@ -2745,22 +2664,22 @@ GDBRemoteCommunicationServerLLGS::Handle_Z(StringExtractorGDBRemote &packet) { if (want_breakpoint) { // Try to set the breakpoint. const Status error = - m_debugged_process_up->SetBreakpoint(addr, size, want_hardware); + m_current_process->SetBreakpoint(addr, size, want_hardware); if (error.Success()) return SendOKResponse(); Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); LLDB_LOG(log, "pid {0} failed to set breakpoint: {1}", - m_debugged_process_up->GetID(), error); + m_current_process->GetID(), error); return SendErrorResponse(0x09); } else { // Try to set the watchpoint. - const Status error = m_debugged_process_up->SetWatchpoint( + const Status error = m_current_process->SetWatchpoint( addr, size, watch_flags, want_hardware); if (error.Success()) return SendOKResponse(); Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); LLDB_LOG(log, "pid {0} failed to set watchpoint: {1}", - m_debugged_process_up->GetID(), error); + m_current_process->GetID(), error); return SendErrorResponse(0x09); } } @@ -2768,8 +2687,8 @@ GDBRemoteCommunicationServerLLGS::Handle_Z(StringExtractorGDBRemote &packet) { GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_z(StringExtractorGDBRemote &packet) { // Ensure we have a process. - if (!m_debugged_process_up || - (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) { + if (!m_current_process || + (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); LLDB_LOG(log, "failed, no process available"); return SendErrorResponse(0x15); @@ -2833,21 +2752,21 @@ GDBRemoteCommunicationServerLLGS::Handle_z(StringExtractorGDBRemote &packet) { if (want_breakpoint) { // Try to clear the breakpoint. const Status error = - m_debugged_process_up->RemoveBreakpoint(addr, want_hardware); + m_current_process->RemoveBreakpoint(addr, want_hardware); if (error.Success()) return SendOKResponse(); Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); LLDB_LOG(log, "pid {0} failed to remove breakpoint: {1}", - m_debugged_process_up->GetID(), error); + m_current_process->GetID(), error); return SendErrorResponse(0x09); } else { // Try to clear the watchpoint. - const Status error = m_debugged_process_up->RemoveWatchpoint(addr); + const Status error = m_current_process->RemoveWatchpoint(addr); if (error.Success()) return SendOKResponse(); Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); LLDB_LOG(log, "pid {0} failed to remove watchpoint: {1}", - m_debugged_process_up->GetID(), error); + m_current_process->GetID(), error); return SendErrorResponse(0x09); } } @@ -2857,8 +2776,8 @@ GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); // Ensure we have a process. - if (!m_debugged_process_up || - (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) { + if (!m_continue_process || + (m_continue_process->GetID() == LLDB_INVALID_PROCESS_ID)) { LLDB_LOGF( log, "GDBRemoteCommunicationServerLLGS::%s failed, no process available", @@ -2876,7 +2795,7 @@ GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) { // Double check that we have such a thread. // TODO investigate: on MacOSX we might need to do an UpdateThreads () here. - NativeThreadProtocol *thread = m_debugged_process_up->GetThreadByID(tid); + NativeThreadProtocol *thread = m_continue_process->GetThreadByID(tid); if (!thread) return SendErrorResponse(0x33); @@ -2889,12 +2808,12 @@ GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) { // All other threads stop while we're single stepping a thread. actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0); - Status error = m_debugged_process_up->Resume(actions); + Status error = m_continue_process->Resume(actions); if (error.Fail()) { LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 " Resume() failed with error: %s", - __FUNCTION__, m_debugged_process_up->GetID(), tid, + __FUNCTION__, m_continue_process->GetID(), tid, error.AsCString()); return SendErrorResponse(0x49); } @@ -2906,7 +2825,7 @@ GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) { llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> GDBRemoteCommunicationServerLLGS::BuildTargetXml() { // Ensure we have a thread. - NativeThreadProtocol *thread = m_debugged_process_up->GetThreadAtIndex(0); + NativeThreadProtocol *thread = m_current_process->GetThreadAtIndex(0); if (!thread) return llvm::createStringError(llvm::inconvertibleErrorCode(), "No thread available"); @@ -2921,7 +2840,7 @@ GDBRemoteCommunicationServerLLGS::BuildTargetXml() { response.Printf("<target version=\"1.0\">"); response.Printf("<architecture>%s</architecture>", - m_debugged_process_up->GetArchitecture() + m_current_process->GetArchitecture() .GetTriple() .getArchName() .str() @@ -3010,22 +2929,22 @@ llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> GDBRemoteCommunicationServerLLGS::ReadXferObject(llvm::StringRef object, llvm::StringRef annex) { // Make sure we have a valid process. - if (!m_debugged_process_up || - (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) { + if (!m_current_process || + (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { return llvm::createStringError(llvm::inconvertibleErrorCode(), "No process available"); } if (object == "auxv") { // Grab the auxv data. - auto buffer_or_error = m_debugged_process_up->GetAuxvData(); + auto buffer_or_error = m_current_process->GetAuxvData(); if (!buffer_or_error) return llvm::errorCodeToError(buffer_or_error.getError()); return std::move(*buffer_or_error); } if (object == "libraries-svr4") { - auto library_list = m_debugged_process_up->GetLoadedSVR4Libraries(); + auto library_list = m_current_process->GetLoadedSVR4Libraries(); if (!library_list) return library_list.takeError(); @@ -3148,7 +3067,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState( Status error = reg_context.ReadAllRegisterValues(register_data_sp); if (error.Fail()) { LLDB_LOG(log, "pid {0} failed to save all register values: {1}", - m_debugged_process_up->GetID(), error); + m_current_process->GetID(), error); return SendErrorResponse(0x75); } @@ -3211,7 +3130,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState( if (it == m_saved_registers_map.end()) { LLDB_LOG(log, "pid {0} does not have a register set save buffer for id {1}", - m_debugged_process_up->GetID(), save_id); + m_current_process->GetID(), save_id); return SendErrorResponse(0x77); } register_data_sp = it->second; @@ -3223,7 +3142,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState( Status error = reg_context.WriteAllRegisterValues(register_data_sp); if (error.Fail()) { LLDB_LOG(log, "pid {0} failed to restore all register values: {1}", - m_debugged_process_up->GetID(), error); + m_current_process->GetID(), error); return SendErrorResponse(0x77); } @@ -3263,7 +3182,7 @@ GDBRemoteCommunicationServerLLGS::Handle_vAttach( } // Notify we attached by sending a stop packet. - return SendStopReasonForState(m_debugged_process_up->GetState()); + return SendStopReasonForState(m_current_process->GetState()); } GDBRemoteCommunication::PacketResult @@ -3293,7 +3212,7 @@ GDBRemoteCommunicationServerLLGS::Handle_vAttachWait( } // Notify we attached by sending a stop packet. - return SendStopReasonForState(m_debugged_process_up->GetState()); + return SendStopReasonForState(m_current_process->GetState()); } GDBRemoteCommunication::PacketResult @@ -3329,25 +3248,13 @@ GDBRemoteCommunicationServerLLGS::Handle_vAttachOrWait( } // Notify we attached by sending a stop packet. - return SendStopReasonForState(m_debugged_process_up->GetState()); + return SendStopReasonForState(m_current_process->GetState()); } GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_D(StringExtractorGDBRemote &packet) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); - StopSTDIOForwarding(); - // Fail if we don't have a current process. - if (!m_debugged_process_up || - (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) { - LLDB_LOGF( - log, - "GDBRemoteCommunicationServerLLGS::%s failed, no process available", - __FUNCTION__); - return SendErrorResponse(0x15); - } - lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; // Consume the ';' after D. @@ -3362,19 +3269,32 @@ GDBRemoteCommunicationServerLLGS::Handle_D(StringExtractorGDBRemote &packet) { return SendIllFormedResponse(packet, "D failed to parse the process id"); } - if (pid != LLDB_INVALID_PROCESS_ID && m_debugged_process_up->GetID() != pid) { - return SendIllFormedResponse(packet, "Invalid pid"); - } - - const Status error = m_debugged_process_up->Detach(); - if (error.Fail()) { - LLDB_LOGF(log, - "GDBRemoteCommunicationServerLLGS::%s failed to detach from " - "pid %" PRIu64 ": %s\n", - __FUNCTION__, m_debugged_process_up->GetID(), error.AsCString()); - return SendErrorResponse(0x01); + // Detach forked children if their PID was specified *or* no PID was requested + // (i.e. detach-all packet). + llvm::Error detach_error = llvm::Error::success(); + bool detached = false; + for (auto it = m_debugged_processes.begin(); + it != m_debugged_processes.end();) { + if (pid == LLDB_INVALID_PROCESS_ID || pid == it->first) { + if (llvm::Error e = it->second->Detach().ToError()) + detach_error = llvm::joinErrors(std::move(detach_error), std::move(e)); + else { + if (it->second.get() == m_current_process) + m_current_process = nullptr; + if (it->second.get() == m_continue_process) + m_continue_process = nullptr; + it = m_debugged_processes.erase(it); + detached = true; + continue; + } + } + ++it; } + if (detach_error) + return SendErrorResponse(std::move(detach_error)); + if (!detached) + return SendErrorResponse(Status("PID %" PRIu64 " not traced", pid)); return SendOKResponse(); } @@ -3384,7 +3304,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo( Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); packet.SetFilePos(strlen("qThreadStopInfo")); - const lldb::tid_t tid = packet.GetHexMaxU32(false, LLDB_INVALID_THREAD_ID); + const lldb::tid_t tid = packet.GetHexMaxU64(false, LLDB_INVALID_THREAD_ID); if (tid == LLDB_INVALID_THREAD_ID) { LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s failed, could not " @@ -3401,19 +3321,19 @@ GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo( Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); // Ensure we have a debugged process. - if (!m_debugged_process_up || - (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) + if (!m_current_process || + (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) return SendErrorResponse(50); - LLDB_LOG(log, "preparing packet for pid {0}", m_debugged_process_up->GetID()); + LLDB_LOG(log, "preparing packet for pid {0}", m_current_process->GetID()); StreamString response; const bool threads_with_valid_stop_info_only = false; - llvm::Expected<json::Value> threads_info = GetJSONThreadsInfo( - *m_debugged_process_up, threads_with_valid_stop_info_only); + llvm::Expected<json::Value> threads_info = + GetJSONThreadsInfo(*m_current_process, threads_with_valid_stop_info_only); if (!threads_info) { LLDB_LOG_ERROR(log, threads_info.takeError(), "failed to prepare a packet for pid {1}: {0}", - m_debugged_process_up->GetID()); + m_current_process->GetID()); return SendErrorResponse(52); } @@ -3427,8 +3347,8 @@ GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo( StringExtractorGDBRemote &packet) { // Fail if we don't have a current process. - if (!m_debugged_process_up || - m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID) + if (!m_current_process || + m_current_process->GetID() == LLDB_INVALID_PROCESS_ID) return SendErrorResponse(68); packet.SetFilePos(strlen("qWatchpointSupportInfo")); @@ -3437,7 +3357,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo( if (packet.GetChar() != ':') return SendErrorResponse(67); - auto hw_debug_cap = m_debugged_process_up->GetHardwareDebugSupportInfo(); + auto hw_debug_cap = m_current_process->GetHardwareDebugSupportInfo(); StreamGDBRemote response; if (hw_debug_cap == llvm::None) @@ -3452,8 +3372,8 @@ GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress( StringExtractorGDBRemote &packet) { // Fail if we don't have a current process. - if (!m_debugged_process_up || - m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID) + if (!m_current_process || + m_current_process->GetID() == LLDB_INVALID_PROCESS_ID) return SendErrorResponse(67); packet.SetFilePos(strlen("qFileLoadAddress:")); @@ -3465,7 +3385,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress( lldb::addr_t file_load_address = LLDB_INVALID_ADDRESS; Status error = - m_debugged_process_up->GetFileLoadAddress(file_name, file_load_address); + m_current_process->GetFileLoadAddress(file_name, file_load_address); if (error.Fail()) return SendErrorResponse(69); @@ -3501,16 +3421,169 @@ GDBRemoteCommunicationServerLLGS::Handle_QPassSignals( } // Fail if we don't have a current process. - if (!m_debugged_process_up) + if (!m_current_process) return SendErrorResponse(68); - Status error = m_debugged_process_up->IgnoreSignals(signals); + Status error = m_current_process->IgnoreSignals(signals); if (error.Fail()) return SendErrorResponse(69); return SendOKResponse(); } +GDBRemoteCommunication::PacketResult +GDBRemoteCommunicationServerLLGS::Handle_qMemTags( + StringExtractorGDBRemote &packet) { + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + + // Ensure we have a process. + if (!m_current_process || + (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { + LLDB_LOGF( + log, + "GDBRemoteCommunicationServerLLGS::%s failed, no process available", + __FUNCTION__); + return SendErrorResponse(1); + } + + // We are expecting + // qMemTags:<hex address>,<hex length>:<hex type> + + // Address + packet.SetFilePos(strlen("qMemTags:")); + const char *current_char = packet.Peek(); + if (!current_char || *current_char == ',') + return SendIllFormedResponse(packet, "Missing address in qMemTags packet"); + const lldb::addr_t addr = packet.GetHexMaxU64(/*little_endian=*/false, 0); + + // Length + char previous_char = packet.GetChar(); + current_char = packet.Peek(); + // If we don't have a separator or the length field is empty + if (previous_char != ',' || (current_char && *current_char == ':')) + return SendIllFormedResponse(packet, + "Invalid addr,length pair in qMemTags packet"); + + if (packet.GetBytesLeft() < 1) + return SendIllFormedResponse( + packet, "Too short qMemtags: packet (looking for length)"); + const size_t length = packet.GetHexMaxU64(/*little_endian=*/false, 0); + + // Type + const char *invalid_type_err = "Invalid type field in qMemTags: packet"; + if (packet.GetBytesLeft() < 1 || packet.GetChar() != ':') + return SendIllFormedResponse(packet, invalid_type_err); + + int32_t type = + packet.GetS32(std::numeric_limits<int32_t>::max(), /*base=*/16); + if (type == std::numeric_limits<int32_t>::max() || + // To catch inputs like "123aardvark" that will parse but clearly aren't + // valid in this case. + packet.GetBytesLeft()) { + return SendIllFormedResponse(packet, invalid_type_err); + } + + StreamGDBRemote response; + std::vector<uint8_t> tags; + Status error = m_current_process->ReadMemoryTags(type, addr, length, tags); + if (error.Fail()) + return SendErrorResponse(1); + + // This m is here in case we want to support multi part replies in the future. + // In the same manner as qfThreadInfo/qsThreadInfo. + response.PutChar('m'); + response.PutBytesAsRawHex8(tags.data(), tags.size()); + return SendPacketNoLock(response.GetString()); +} + +GDBRemoteCommunication::PacketResult +GDBRemoteCommunicationServerLLGS::Handle_QMemTags( + StringExtractorGDBRemote &packet) { + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + + // Ensure we have a process. + if (!m_current_process || + (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { + LLDB_LOGF( + log, + "GDBRemoteCommunicationServerLLGS::%s failed, no process available", + __FUNCTION__); + return SendErrorResponse(1); + } + + // We are expecting + // QMemTags:<hex address>,<hex length>:<hex type>:<tags as hex bytes> + + // Address + packet.SetFilePos(strlen("QMemTags:")); + const char *current_char = packet.Peek(); + if (!current_char || *current_char == ',') + return SendIllFormedResponse(packet, "Missing address in QMemTags packet"); + const lldb::addr_t addr = packet.GetHexMaxU64(/*little_endian=*/false, 0); + + // Length + char previous_char = packet.GetChar(); + current_char = packet.Peek(); + // If we don't have a separator or the length field is empty + if (previous_char != ',' || (current_char && *current_char == ':')) + return SendIllFormedResponse(packet, + "Invalid addr,length pair in QMemTags packet"); + + if (packet.GetBytesLeft() < 1) + return SendIllFormedResponse( + packet, "Too short QMemtags: packet (looking for length)"); + const size_t length = packet.GetHexMaxU64(/*little_endian=*/false, 0); + + // Type + const char *invalid_type_err = "Invalid type field in QMemTags: packet"; + if (packet.GetBytesLeft() < 1 || packet.GetChar() != ':') + return SendIllFormedResponse(packet, invalid_type_err); + + // Our GetU64 uses strtoull which allows leading +/-, we don't want that. + const char *first_type_char = packet.Peek(); + if (first_type_char && (*first_type_char == '+' || *first_type_char == '-')) + return SendIllFormedResponse(packet, invalid_type_err); + + // The type is a signed integer but is in the packet as its raw bytes. + // So parse first as unsigned then cast to signed later. + // We extract to 64 bit, even though we only expect 32, so that we've + // got some invalid value we can check for. + uint64_t raw_type = + packet.GetU64(std::numeric_limits<uint64_t>::max(), /*base=*/16); + if (raw_type > std::numeric_limits<uint32_t>::max()) + return SendIllFormedResponse(packet, invalid_type_err); + int32_t type = static_cast<int32_t>(raw_type); + + // Tag data + if (packet.GetBytesLeft() < 1 || packet.GetChar() != ':') + return SendIllFormedResponse(packet, + "Missing tag data in QMemTags: packet"); + + // Must be 2 chars per byte + const char *invalid_data_err = "Invalid tag data in QMemTags: packet"; + if (packet.GetBytesLeft() % 2) + return SendIllFormedResponse(packet, invalid_data_err); + + // This is bytes here and is unpacked into target specific tags later + // We cannot assume that number of bytes == length here because the server + // can repeat tags to fill a given range. + std::vector<uint8_t> tag_data; + // Zero length writes will not have any tag data + // (but we pass them on because it will still check that tagging is enabled) + if (packet.GetBytesLeft()) { + size_t byte_count = packet.GetBytesLeft() / 2; + tag_data.resize(byte_count); + size_t converted_bytes = packet.GetHexBytes(tag_data, 0); + if (converted_bytes != byte_count) { + return SendIllFormedResponse(packet, invalid_data_err); + } + } + + Status status = + m_current_process->WriteMemoryTags(type, addr, length, tag_data); + return status.Success() ? SendOKResponse() : SendErrorResponse(1); +} + void GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection() { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); @@ -3539,8 +3612,8 @@ void GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection() { NativeThreadProtocol *GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix( StringExtractorGDBRemote &packet) { // We have no thread if we don't have a process. - if (!m_debugged_process_up || - m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID) + if (!m_current_process || + m_current_process->GetID() == LLDB_INVALID_PROCESS_ID) return nullptr; // If the client hasn't asked for thread suffix support, there will not be a @@ -3551,9 +3624,9 @@ NativeThreadProtocol *GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix( return nullptr; else if (current_tid == 0) { // Pick a thread. - return m_debugged_process_up->GetThreadAtIndex(0); + return m_current_process->GetThreadAtIndex(0); } else - return m_debugged_process_up->GetThreadByID(current_tid); + return m_current_process->GetThreadByID(current_tid); } Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); @@ -3583,7 +3656,7 @@ NativeThreadProtocol *GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix( packet.SetFilePos(packet.GetFilePos() + strlen("thread:")); const lldb::tid_t tid = packet.GetHexMaxU64(false, 0); if (tid != 0) - return m_debugged_process_up->GetThreadByID(tid); + return m_current_process->GetThreadByID(tid); return nullptr; } @@ -3593,9 +3666,9 @@ lldb::tid_t GDBRemoteCommunicationServerLLGS::GetCurrentThreadID() const { // Use whatever the debug process says is the current thread id since the // protocol either didn't specify or specified we want any/all threads // marked as the current thread. - if (!m_debugged_process_up) + if (!m_current_process) return LLDB_INVALID_THREAD_ID; - return m_debugged_process_up->GetCurrentThreadID(); + return m_current_process->GetCurrentThreadID(); } // Use the specific current thread id set by the gdb remote protocol. return m_current_tid; @@ -3616,9 +3689,9 @@ void GDBRemoteCommunicationServerLLGS::ClearProcessSpecificData() { FileSpec GDBRemoteCommunicationServerLLGS::FindModuleFile(const std::string &module_path, const ArchSpec &arch) { - if (m_debugged_process_up) { + if (m_current_process) { FileSpec file_spec; - if (m_debugged_process_up + if (m_current_process ->GetLoadedModuleFileSpec(module_path.c_str(), file_spec) .Success()) { if (FileSystem::Instance().Exists(file_spec)) @@ -3653,3 +3726,93 @@ std::string GDBRemoteCommunicationServerLLGS::XMLEncodeAttributeValue( } return result; } + +llvm::Expected<lldb::tid_t> GDBRemoteCommunicationServerLLGS::ReadTid( + StringExtractorGDBRemote &packet, bool allow_all, lldb::pid_t default_pid) { + assert(m_current_process); + assert(m_current_process->GetID() != LLDB_INVALID_PROCESS_ID); + + auto pid_tid = packet.GetPidTid(default_pid); + if (!pid_tid) + return llvm::make_error<StringError>(inconvertibleErrorCode(), + "Malformed thread-id"); + + lldb::pid_t pid = pid_tid->first; + lldb::tid_t tid = pid_tid->second; + + if (!allow_all && pid == StringExtractorGDBRemote::AllProcesses) + return llvm::make_error<StringError>( + inconvertibleErrorCode(), + llvm::formatv("PID value {0} not allowed", pid == 0 ? 0 : -1)); + + if (!allow_all && tid == StringExtractorGDBRemote::AllThreads) + return llvm::make_error<StringError>( + inconvertibleErrorCode(), + llvm::formatv("TID value {0} not allowed", tid == 0 ? 0 : -1)); + + if (pid != StringExtractorGDBRemote::AllProcesses) { + if (pid != m_current_process->GetID()) + return llvm::make_error<StringError>( + inconvertibleErrorCode(), llvm::formatv("PID {0} not debugged", pid)); + } + + return tid; +} + +std::vector<std::string> GDBRemoteCommunicationServerLLGS::HandleFeatures( + const llvm::ArrayRef<llvm::StringRef> client_features) { + std::vector<std::string> ret = + GDBRemoteCommunicationServerCommon::HandleFeatures(client_features); + ret.insert(ret.end(), { + "QThreadSuffixSupported+", + "QListThreadsInStopReply+", + "qXfer:features:read+", + }); + + // report server-only features + using Extension = NativeProcessProtocol::Extension; + Extension plugin_features = m_process_factory.GetSupportedExtensions(); + if (bool(plugin_features & Extension::pass_signals)) + ret.push_back("QPassSignals+"); + if (bool(plugin_features & Extension::auxv)) + ret.push_back("qXfer:auxv:read+"); + if (bool(plugin_features & Extension::libraries_svr4)) + ret.push_back("qXfer:libraries-svr4:read+"); + if (bool(plugin_features & Extension::memory_tagging)) + ret.push_back("memory-tagging+"); + + // check for client features + m_extensions_supported = {}; + for (llvm::StringRef x : client_features) + m_extensions_supported |= + llvm::StringSwitch<Extension>(x) + .Case("multiprocess+", Extension::multiprocess) + .Case("fork-events+", Extension::fork) + .Case("vfork-events+", Extension::vfork) + .Default({}); + + m_extensions_supported &= plugin_features; + + // fork & vfork require multiprocess + if (!bool(m_extensions_supported & Extension::multiprocess)) + m_extensions_supported &= ~(Extension::fork | Extension::vfork); + + // report only if actually supported + if (bool(m_extensions_supported & Extension::multiprocess)) + ret.push_back("multiprocess+"); + if (bool(m_extensions_supported & Extension::fork)) + ret.push_back("fork-events+"); + if (bool(m_extensions_supported & Extension::vfork)) + ret.push_back("vfork-events+"); + + for (auto &x : m_debugged_processes) + SetEnabledExtensions(*x.second); + return ret; +} + +void GDBRemoteCommunicationServerLLGS::SetEnabledExtensions( + NativeProcessProtocol &process) { + NativeProcessProtocol::Extension flags = m_extensions_supported; + assert(!bool(flags & ~m_process_factory.GetSupportedExtensions())); + process.SetEnabledExtensions(flags); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h index c51139924559..04d0605fe420 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h @@ -78,6 +78,10 @@ public: void DidExec(NativeProcessProtocol *process) override; + void + NewSubprocess(NativeProcessProtocol *parent_process, + std::unique_ptr<NativeProcessProtocol> child_process) override; + Status InitializeConnection(std::unique_ptr<Connection> connection); protected: @@ -86,8 +90,11 @@ protected: const NativeProcessProtocol::Factory &m_process_factory; lldb::tid_t m_current_tid = LLDB_INVALID_THREAD_ID; lldb::tid_t m_continue_tid = LLDB_INVALID_THREAD_ID; + NativeProcessProtocol *m_current_process; + NativeProcessProtocol *m_continue_process; std::recursive_mutex m_debugged_process_mutex; - std::unique_ptr<NativeProcessProtocol> m_debugged_process_up; + std::unordered_map<lldb::pid_t, std::unique_ptr<NativeProcessProtocol>> + m_debugged_processes; Communication m_stdio_communication; MainLoop::ReadHandleUP m_stdio_handle_up; @@ -98,6 +105,10 @@ protected: std::unordered_map<uint32_t, lldb::DataBufferSP> m_saved_registers_map; uint32_t m_next_saved_registers_id = 1; bool m_handshake_completed = false; + bool m_thread_suffix_supported = false; + bool m_list_threads_in_stop_reply = false; + + NativeProcessProtocol::Extension m_extensions_supported = {}; PacketResult SendONotification(const char *buffer, uint32_t len); @@ -119,6 +130,10 @@ protected: PacketResult Handle_qGetWorkingDir(StringExtractorGDBRemote &packet); + PacketResult Handle_QThreadSuffixSupported(StringExtractorGDBRemote &packet); + + PacketResult Handle_QListThreadsInStopReply(StringExtractorGDBRemote &packet); + PacketResult Handle_C(StringExtractorGDBRemote &packet); PacketResult Handle_c(StringExtractorGDBRemote &packet); @@ -167,15 +182,15 @@ protected: PacketResult Handle_QSaveRegisterState(StringExtractorGDBRemote &packet); - PacketResult Handle_jTraceStart(StringExtractorGDBRemote &packet); + PacketResult Handle_jLLDBTraceSupported(StringExtractorGDBRemote &packet); - PacketResult Handle_jTraceRead(StringExtractorGDBRemote &packet); + PacketResult Handle_jLLDBTraceStart(StringExtractorGDBRemote &packet); - PacketResult Handle_jTraceStop(StringExtractorGDBRemote &packet); + PacketResult Handle_jLLDBTraceStop(StringExtractorGDBRemote &packet); - PacketResult Handle_jTraceConfigRead(StringExtractorGDBRemote &packet); + PacketResult Handle_jLLDBTraceGetState(StringExtractorGDBRemote &packet); - PacketResult Handle_jLLDBTraceSupportedType(StringExtractorGDBRemote &packet); + PacketResult Handle_jLLDBTraceGetBinaryData(StringExtractorGDBRemote &packet); PacketResult Handle_QRestoreRegisterState(StringExtractorGDBRemote &packet); @@ -201,6 +216,10 @@ protected: PacketResult Handle_g(StringExtractorGDBRemote &packet); + PacketResult Handle_qMemTags(StringExtractorGDBRemote &packet); + + PacketResult Handle_QMemTags(StringExtractorGDBRemote &packet); + void SetCurrentThreadID(lldb::tid_t tid); lldb::tid_t GetCurrentThreadID() const; @@ -219,6 +238,9 @@ protected: static std::string XMLEncodeAttributeValue(llvm::StringRef value); + virtual std::vector<std::string> HandleFeatures( + const llvm::ArrayRef<llvm::StringRef> client_features) override; + private: llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> BuildTargetXml(); @@ -244,6 +266,18 @@ private: void StopSTDIOForwarding(); + // Read thread-id from packet. If the thread-id is correct, returns it. + // Otherwise, returns the error. + // + // If allow_all is true, then the pid/tid value of -1 ('all') will be allowed. + // In any case, the function assumes that exactly one inferior is being + // debugged and rejects pid values that do no match that inferior. + llvm::Expected<lldb::tid_t> ReadTid(StringExtractorGDBRemote &packet, + bool allow_all, lldb::pid_t default_pid); + + // Call SetEnabledExtensions() with appropriate flags on the process. + void SetEnabledExtensions(NativeProcessProtocol &process); + // For GDBRemoteCommunicationServerLLGS only GDBRemoteCommunicationServerLLGS(const GDBRemoteCommunicationServerLLGS &) = delete; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp index 3462fb7ec8b9..7c2f80dc76b8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp @@ -8,7 +8,7 @@ #include "GDBRemoteCommunicationServerPlatform.h" -#include <errno.h> +#include <cerrno> #include <chrono> #include <csignal> @@ -153,7 +153,8 @@ GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform( } // Destructor -GDBRemoteCommunicationServerPlatform::~GDBRemoteCommunicationServerPlatform() {} +GDBRemoteCommunicationServerPlatform::~GDBRemoteCommunicationServerPlatform() = + default; Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer( const lldb_private::Args &args, std::string hostname, lldb::pid_t &pid, diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp index 10006616b0c6..65cf9fb2a834 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp @@ -36,7 +36,7 @@ GDBRemoteRegisterContext::GDBRemoteRegisterContext( : RegisterContext(thread, concrete_frame_idx), m_reg_info_sp(std::move(reg_info_sp)), m_reg_valid(), m_reg_data(), m_read_all_at_once(read_all_at_once), - m_write_all_at_once(write_all_at_once) { + m_write_all_at_once(write_all_at_once), m_gpacket_cached(false) { // Resize our vector of bools to contain one bool for every register. We will // use these boolean values to know when a register value is valid in // m_reg_data. @@ -50,13 +50,14 @@ GDBRemoteRegisterContext::GDBRemoteRegisterContext( } // Destructor -GDBRemoteRegisterContext::~GDBRemoteRegisterContext() {} +GDBRemoteRegisterContext::~GDBRemoteRegisterContext() = default; void GDBRemoteRegisterContext::InvalidateAllRegisters() { SetAllRegisterValid(false); } void GDBRemoteRegisterContext::SetAllRegisterValid(bool b) { + m_gpacket_cached = b; std::vector<bool>::iterator pos, end = m_reg_valid.end(); for (pos = m_reg_valid.begin(); pos != end; ++pos) *pos = b; @@ -200,7 +201,7 @@ bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info, const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; if (!GetRegisterIsValid(reg)) { - if (m_read_all_at_once) { + if (m_read_all_at_once && !m_gpacket_cached) { if (DataBufferSP buffer_sp = gdb_comm.ReadAllRegisters(m_thread.GetProtocolID())) { memcpy(const_cast<uint8_t *>(m_reg_data.GetDataStart()), @@ -221,7 +222,10 @@ bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info, m_reg_valid[i] = false; } } - return true; + + m_gpacket_cached = true; + if (GetRegisterIsValid(reg)) + return true; } else { Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_THREAD | GDBR_LOG_PACKETS)); @@ -233,9 +237,9 @@ bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info, " bytes " "but only got %" PRId64 " bytes.", m_reg_data.GetByteSize(), buffer_sp->GetByteSize()); + return false; } } - return false; } if (reg_info->value_regs) { // Process this composite register request by delegating to the @@ -249,7 +253,8 @@ bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info, break; // We have a valid primordial register as our constituent. Grab the // corresponding register info. - const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg); + const RegisterInfo *prim_reg_info = + GetRegisterInfo(eRegisterKindProcessPlugin, prim_reg); if (prim_reg_info == nullptr) success = false; else { @@ -359,7 +364,7 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info, reg_info->byte_size, // dst length m_reg_data.GetByteOrder())) // dst byte order { - GDBRemoteClientBase::Lock lock(gdb_comm, false); + GDBRemoteClientBase::Lock lock(gdb_comm); if (lock) { if (m_write_all_at_once) { // Invalidate all register values @@ -395,7 +400,8 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info, break; // We have a valid primordial register as our constituent. Grab the // corresponding register info. - const RegisterInfo *value_reg_info = GetRegisterInfoAtIndex(reg); + const RegisterInfo *value_reg_info = + GetRegisterInfo(eRegisterKindProcessPlugin, reg); if (value_reg_info == nullptr) success = false; else @@ -414,9 +420,10 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info, if (reg_info->invalidate_regs) { for (uint32_t idx = 0, reg = reg_info->invalidate_regs[0]; reg != LLDB_INVALID_REGNUM; - reg = reg_info->invalidate_regs[++idx]) { - SetRegisterIsValid(reg, false); - } + reg = reg_info->invalidate_regs[++idx]) + SetRegisterIsValid(ConvertRegisterKindToRegisterNumber( + eRegisterKindProcessPlugin, reg), + false); } return success; @@ -501,7 +508,7 @@ bool GDBRemoteRegisterContext::ReadAllRegisterValues( const bool use_g_packet = !gdb_comm.AvoidGPackets((ProcessGDBRemote *)process); - GDBRemoteClientBase::Lock lock(gdb_comm, false); + GDBRemoteClientBase::Lock lock(gdb_comm); if (lock) { if (gdb_comm.SyncThreadState(m_thread.GetProtocolID())) InvalidateAllRegisters(); @@ -567,7 +574,7 @@ bool GDBRemoteRegisterContext::WriteAllRegisterValues( const bool use_g_packet = !gdb_comm.AvoidGPackets((ProcessGDBRemote *)process); - GDBRemoteClientBase::Lock lock(gdb_comm, false); + GDBRemoteClientBase::Lock lock(gdb_comm); if (lock) { // The data_sp contains the G response packet. if (use_g_packet) { diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h index 252d7b359ee8..18fcb73b9815 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h @@ -118,6 +118,7 @@ protected: DataExtractor m_reg_data; bool m_read_all_at_once; bool m_write_all_at_once; + bool m_gpacket_cached; private: // Helper function for ReadRegisterBytes(). diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 1214812b60b0..b8a737586eb4 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -8,8 +8,8 @@ #include "lldb/Host/Config.h" -#include <errno.h> -#include <stdlib.h> +#include <cerrno> +#include <cstdlib> #if LLDB_ENABLE_POSIX #include <netinet/in.h> #include <sys/mman.h> @@ -20,8 +20,8 @@ #if defined(__APPLE__) #include <sys/sysctl.h> #endif +#include <ctime> #include <sys/types.h> -#include <time.h> #include <algorithm> #include <csignal> @@ -137,7 +137,7 @@ public: m_collection_sp->Initialize(g_processgdbremote_properties); } - ~PluginProperties() override {} + ~PluginProperties() override = default; uint64_t GetPacketTimeout() { const uint32_t idx = ePropertyPacketTimeout; @@ -215,6 +215,10 @@ ProcessGDBRemote::CreateInstance(lldb::TargetSP target_sp, return process_sp; } +std::chrono::seconds ProcessGDBRemote::GetPacketTimeout() { + return std::chrono::seconds(GetGlobalPluginProperties()->GetPacketTimeout()); +} + bool ProcessGDBRemote::CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) { if (plugin_specified_by_name) @@ -463,7 +467,7 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) { assert(packet_len < (int)sizeof(packet)); UNUSED_IF_ASSERT_DISABLED(packet_len); StringExtractorGDBRemote response; - if (m_gdb_comm.SendPacketAndWaitForResponse(packet, response, false) == + if (m_gdb_comm.SendPacketAndWaitForResponse(packet, response) == GDBRemoteCommunication::PacketResult::Success) { response_type = response.GetResponseType(); if (response_type == StringExtractorGDBRemote::eResponse) { @@ -1013,7 +1017,7 @@ Status ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) { for (size_t idx = 0; idx < num_cmds; idx++) { StringExtractorGDBRemote response; m_gdb_comm.SendPacketAndWaitForResponse( - GetExtraStartupCommands().GetArgumentAtIndex(idx), response, false); + GetExtraStartupCommands().GetArgumentAtIndex(idx), response); } return error; } @@ -1040,6 +1044,12 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) { process_arch.GetTriple().getTriple()); } + if (int addresssable_bits = m_gdb_comm.GetAddressingBits()) { + lldb::addr_t address_mask = ~((1ULL << addresssable_bits) - 1); + SetCodeAddressMask(address_mask); + SetDataAddressMask(address_mask); + } + if (process_arch.IsValid()) { const ArchSpec &target_arch = GetTarget().GetArchitecture(); if (target_arch.IsValid()) { @@ -1201,34 +1211,26 @@ Status ProcessGDBRemote::DoAttachToProcessWithName( return error; } -lldb::user_id_t ProcessGDBRemote::StartTrace(const TraceOptions &options, - Status &error) { - return m_gdb_comm.SendStartTracePacket(options, error); -} - -Status ProcessGDBRemote::StopTrace(lldb::user_id_t uid, lldb::tid_t thread_id) { - return m_gdb_comm.SendStopTracePacket(uid, thread_id); +llvm::Expected<TraceSupportedResponse> ProcessGDBRemote::TraceSupported() { + return m_gdb_comm.SendTraceSupported(GetInterruptTimeout()); } -Status ProcessGDBRemote::GetData(lldb::user_id_t uid, lldb::tid_t thread_id, - llvm::MutableArrayRef<uint8_t> &buffer, - size_t offset) { - return m_gdb_comm.SendGetDataPacket(uid, thread_id, buffer, offset); +llvm::Error ProcessGDBRemote::TraceStop(const TraceStopRequest &request) { + return m_gdb_comm.SendTraceStop(request, GetInterruptTimeout()); } -Status ProcessGDBRemote::GetMetaData(lldb::user_id_t uid, lldb::tid_t thread_id, - llvm::MutableArrayRef<uint8_t> &buffer, - size_t offset) { - return m_gdb_comm.SendGetMetaDataPacket(uid, thread_id, buffer, offset); +llvm::Error ProcessGDBRemote::TraceStart(const llvm::json::Value &request) { + return m_gdb_comm.SendTraceStart(request, GetInterruptTimeout()); } -Status ProcessGDBRemote::GetTraceConfig(lldb::user_id_t uid, - TraceOptions &options) { - return m_gdb_comm.SendGetTraceConfigPacket(uid, options); +llvm::Expected<std::string> +ProcessGDBRemote::TraceGetState(llvm::StringRef type) { + return m_gdb_comm.SendTraceGetState(type, GetInterruptTimeout()); } -llvm::Expected<TraceTypeInfo> ProcessGDBRemote::GetSupportedTraceType() { - return m_gdb_comm.SendGetSupportedTraceType(); +llvm::Expected<std::vector<uint8_t>> +ProcessGDBRemote::TraceGetBinaryData(const TraceGetBinaryDataRequest &request) { + return m_gdb_comm.SendTraceGetBinaryData(request, GetInterruptTimeout()); } void ProcessGDBRemote::DidExit() { @@ -1473,7 +1475,7 @@ void ProcessGDBRemote::HandleStopReplySequence() { while (true) { // Send vStopped StringExtractorGDBRemote response; - m_gdb_comm.SendPacketAndWaitForResponse("vStopped", response, false); + m_gdb_comm.SendPacketAndWaitForResponse("vStopped", response); // OK represents end of signal list if (response.IsOKResponse()) @@ -1493,22 +1495,22 @@ void ProcessGDBRemote::ClearThreadIDList() { m_thread_pcs.clear(); } -size_t -ProcessGDBRemote::UpdateThreadIDsFromStopReplyThreadsValue(std::string &value) { +size_t ProcessGDBRemote::UpdateThreadIDsFromStopReplyThreadsValue( + llvm::StringRef value) { m_thread_ids.clear(); - size_t comma_pos; - lldb::tid_t tid; - while ((comma_pos = value.find(',')) != std::string::npos) { - value[comma_pos] = '\0'; - // thread in big endian hex - tid = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_THREAD_ID, 16); - if (tid != LLDB_INVALID_THREAD_ID) - m_thread_ids.push_back(tid); - value.erase(0, comma_pos + 1); - } - tid = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_THREAD_ID, 16); - if (tid != LLDB_INVALID_THREAD_ID) - m_thread_ids.push_back(tid); + lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID(); + StringExtractorGDBRemote thread_ids{value}; + + do { + auto pid_tid = thread_ids.GetPidTid(pid); + if (pid_tid && pid_tid->first == pid) { + lldb::tid_t tid = pid_tid->second; + if (tid != LLDB_INVALID_THREAD_ID && + tid != StringExtractorGDBRemote::AllProcesses) + m_thread_ids.push_back(tid); + } + } while (thread_ids.GetChar() == ','); + return m_thread_ids.size(); } @@ -1525,7 +1527,7 @@ ProcessGDBRemote::UpdateThreadPCsFromStopReplyThreadsValue(std::string &value) { value.erase(0, comma_pos + 1); } pc = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16); - if (pc != LLDB_INVALID_THREAD_ID) + if (pc != LLDB_INVALID_ADDRESS) m_thread_pcs.push_back(pc); return m_thread_pcs.size(); } @@ -1750,7 +1752,9 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo( if (thread_sp) { ThreadGDBRemote *gdb_thread = static_cast<ThreadGDBRemote *>(thread_sp.get()); - gdb_thread->GetRegisterContext()->InvalidateIfNeeded(true); + RegisterContextSP gdb_reg_ctx_sp(gdb_thread->GetRegisterContext()); + + gdb_reg_ctx_sp->InvalidateIfNeeded(true); auto iter = std::find(m_thread_ids.begin(), m_thread_ids.end(), tid); if (iter != m_thread_ids.end()) { @@ -1762,7 +1766,10 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo( DataBufferSP buffer_sp(new DataBufferHeap( reg_value_extractor.GetStringRef().size() / 2, 0)); reg_value_extractor.GetHexBytes(buffer_sp->GetData(), '\xcc'); - gdb_thread->PrivateSetRegisterValue(pair.first, buffer_sp->GetData()); + uint32_t lldb_regnum = + gdb_reg_ctx_sp->ConvertRegisterKindToRegisterNumber( + eRegisterKindProcessPlugin, pair.first); + gdb_thread->PrivateSetRegisterValue(lldb_regnum, buffer_sp->GetData()); } // AArch64 SVE specific code below calls AArch64SVEReconfigure to update @@ -1827,8 +1834,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo( // If the current pc is a breakpoint site then the StopInfo // should be set to Breakpoint Otherwise, it will be set to // Trace. - if (bp_site_sp && - bp_site_sp->ValidForThisThread(thread_sp.get())) { + if (bp_site_sp && bp_site_sp->ValidForThisThread(*thread_sp)) { thread_sp->SetStopInfo( StopInfo::CreateStopReasonWithBreakpointSiteID( *thread_sp, bp_site_sp->GetID())); @@ -1848,7 +1854,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo( // breakpoint here, that will be taken care of when the thread // resumes and notices that there's a breakpoint under the pc. handled = true; - if (bp_site_sp->ValidForThisThread(thread_sp.get())) { + if (bp_site_sp->ValidForThisThread(*thread_sp)) { thread_sp->SetStopInfo( StopInfo::CreateStopReasonWithBreakpointSiteID( *thread_sp, bp_site_sp->GetID())); @@ -1899,6 +1905,9 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo( thread_sp->SetStopInfo( StopInfo::CreateStopReasonWithExec(*thread_sp)); handled = true; + } else if (reason == "processor trace") { + thread_sp->SetStopInfo(StopInfo::CreateStopReasonProcessorTrace( + *thread_sp, description.c_str())); } } else if (!signo) { addr_t pc = thread_sp->GetRegisterContext()->GetPC(); @@ -1911,7 +1920,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo( // as such. This can happen when the thread is involuntarily // interrupted (e.g. due to stops on other threads) just as it is // about to execute the breakpoint instruction. - if (bp_site_sp && bp_site_sp->ValidForThisThread(thread_sp.get())) { + if (bp_site_sp && bp_site_sp->ValidForThisThread(*thread_sp)) { thread_sp->SetStopInfo( StopInfo::CreateStopReasonWithBreakpointSiteID( *thread_sp, bp_site_sp->GetID())); @@ -1936,7 +1945,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo( // reason. We don't need to worry about stepping over the // breakpoint here, that will be taken care of when the thread // resumes and notices that there's a breakpoint under the pc. - if (bp_site_sp->ValidForThisThread(thread_sp.get())) { + if (bp_site_sp->ValidForThisThread(*thread_sp)) { if (m_breakpoint_pc_offset != 0) thread_sp->GetRegisterContext()->SetPC(pc); thread_sp->SetStopInfo( @@ -2139,6 +2148,7 @@ ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) { } StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) { + lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID(); stop_packet.SetFilePos(0); const char stop_type = stop_packet.GetChar(); switch (stop_type) { @@ -2153,14 +2163,12 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) { if (stop_id == 0) { // Our first stop, make sure we have a process ID, and also make sure we // know about our registers - if (GetID() == LLDB_INVALID_PROCESS_ID) { - lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID(); - if (pid != LLDB_INVALID_PROCESS_ID) - SetID(pid); - } + if (GetID() == LLDB_INVALID_PROCESS_ID && pid != LLDB_INVALID_PROCESS_ID) + SetID(pid); BuildDynamicRegisterInfo(true); } // Stop with signal and thread info + lldb::pid_t stop_pid = LLDB_INVALID_PROCESS_ID; lldb::tid_t tid = LLDB_INVALID_THREAD_ID; const uint8_t signo = stop_packet.GetHexU8(); llvm::StringRef key; @@ -2189,24 +2197,18 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) { value.getAsInteger(16, x); exc_data.push_back(x); } else if (key.compare("thread") == 0) { - // thread in big endian hex - if (value.getAsInteger(16, tid)) + // thread-id + StringExtractorGDBRemote thread_id{value}; + auto pid_tid = thread_id.GetPidTid(pid); + if (pid_tid) { + stop_pid = pid_tid->first; + tid = pid_tid->second; + } else tid = LLDB_INVALID_THREAD_ID; } else if (key.compare("threads") == 0) { std::lock_guard<std::recursive_mutex> guard( m_thread_list_real.GetMutex()); - - m_thread_ids.clear(); - // A comma separated list of all threads in the current - // process that includes the thread for this stop reply packet - lldb::tid_t tid; - while (!value.empty()) { - llvm::StringRef tid_str; - std::tie(tid_str, value) = value.split(','); - if (tid_str.getAsInteger(16, tid)) - tid = LLDB_INVALID_THREAD_ID; - m_thread_ids.push_back(tid); - } + UpdateThreadIDsFromStopReplyThreadsValue(value); } else if (key.compare("thread-pcs") == 0) { m_thread_pcs.clear(); // A comma separated list of all threads in the current @@ -2319,6 +2321,14 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) { } } + if (stop_pid != LLDB_INVALID_PROCESS_ID && stop_pid != pid) { + Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); + LLDB_LOG(log, + "Received stop for incorrect PID = {0} (inferior PID = {1})", + stop_pid, pid); + return eStateInvalid; + } + if (tid == LLDB_INVALID_THREAD_ID) { // A thread id may be invalid if the response is old style 'S' packet // which does not provide the @@ -2406,7 +2416,7 @@ Status ProcessGDBRemote::DoHalt(bool &caused_stop) { // file handle and debugserver will go away, and we can be done... m_gdb_comm.Disconnect(); } else - caused_stop = m_gdb_comm.Interrupt(); + caused_stop = m_gdb_comm.Interrupt(GetInterruptTimeout()); return error; } @@ -2557,11 +2567,11 @@ Status ProcessGDBRemote::DoDestroy() { if (m_gdb_comm.IsConnected()) { if (m_public_state.GetValue() != eStateAttaching) { StringExtractorGDBRemote response; - bool send_async = true; GDBRemoteCommunication::ScopedTimeout(m_gdb_comm, std::chrono::seconds(3)); - if (m_gdb_comm.SendPacketAndWaitForResponse("k", response, send_async) == + if (m_gdb_comm.SendPacketAndWaitForResponse("k", response, + GetInterruptTimeout()) == GDBRemoteCommunication::PacketResult::Success) { char packet_cmd = response.GetChar(0); @@ -2725,7 +2735,8 @@ size_t ProcessGDBRemote::DoReadMemory(addr_t addr, void *buf, size_t size, assert(packet_len + 1 < (int)sizeof(packet)); UNUSED_IF_ASSERT_DISABLED(packet_len); StringExtractorGDBRemote response; - if (m_gdb_comm.SendPacketAndWaitForResponse(packet, response, true) == + if (m_gdb_comm.SendPacketAndWaitForResponse(packet, response, + GetInterruptTimeout()) == GDBRemoteCommunication::PacketResult::Success) { if (response.IsNormalResponse()) { error.Clear(); @@ -2761,6 +2772,37 @@ size_t ProcessGDBRemote::DoReadMemory(addr_t addr, void *buf, size_t size, return 0; } +bool ProcessGDBRemote::SupportsMemoryTagging() { + return m_gdb_comm.GetMemoryTaggingSupported(); +} + +llvm::Expected<std::vector<uint8_t>> +ProcessGDBRemote::DoReadMemoryTags(lldb::addr_t addr, size_t len, + int32_t type) { + // By this point ReadMemoryTags has validated that tagging is enabled + // for this target/process/address. + DataBufferSP buffer_sp = m_gdb_comm.ReadMemoryTags(addr, len, type); + if (!buffer_sp) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Error reading memory tags from remote"); + } + + // Return the raw tag data + llvm::ArrayRef<uint8_t> tag_data = buffer_sp->GetData(); + std::vector<uint8_t> got; + got.reserve(tag_data.size()); + std::copy(tag_data.begin(), tag_data.end(), std::back_inserter(got)); + return got; +} + +Status ProcessGDBRemote::DoWriteMemoryTags(lldb::addr_t addr, size_t len, + int32_t type, + const std::vector<uint8_t> &tags) { + // By now WriteMemoryTags should have validated that tagging is enabled + // for this target/process. + return m_gdb_comm.WriteMemoryTags(addr, len, type, tags); +} + Status ProcessGDBRemote::WriteObjectFile( std::vector<ObjectFile::LoadableData> entries) { Status error; @@ -2851,7 +2893,7 @@ Status ProcessGDBRemote::FlashErase(lldb::addr_t addr, size_t size) { StringExtractorGDBRemote response; if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response, - true) == + GetInterruptTimeout()) == GDBRemoteCommunication::PacketResult::Success) { if (response.IsOKResponse()) { m_erased_flash_ranges.Insert(range, true); @@ -2880,7 +2922,8 @@ Status ProcessGDBRemote::FlashDone() { if (m_erased_flash_ranges.IsEmpty()) return status; StringExtractorGDBRemote response; - if (m_gdb_comm.SendPacketAndWaitForResponse("vFlashDone", response, true) == + if (m_gdb_comm.SendPacketAndWaitForResponse("vFlashDone", response, + GetInterruptTimeout()) == GDBRemoteCommunication::PacketResult::Success) { if (response.IsOKResponse()) { m_erased_flash_ranges.Clear(); @@ -2941,7 +2984,7 @@ size_t ProcessGDBRemote::DoWriteMemory(addr_t addr, const void *buf, } StringExtractorGDBRemote response; if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response, - true) == + GetInterruptTimeout()) == GDBRemoteCommunication::PacketResult::Success) { if (response.IsOKResponse()) { error.Clear(); @@ -3117,7 +3160,7 @@ Status ProcessGDBRemote::EnableBreakpointSite(BreakpointSite *bp_site) { (!bp_site->HardwareRequired())) { // Try to send off a software breakpoint packet ($Z0) uint8_t error_no = m_gdb_comm.SendGDBStoppointTypePacket( - eBreakpointSoftware, true, addr, bp_op_size); + eBreakpointSoftware, true, addr, bp_op_size, GetInterruptTimeout()); if (error_no == 0) { // The breakpoint was placed successfully bp_site->SetEnabled(true); @@ -3157,7 +3200,7 @@ Status ProcessGDBRemote::EnableBreakpointSite(BreakpointSite *bp_site) { if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointHardware)) { // Try to send off a hardware breakpoint packet ($Z1) uint8_t error_no = m_gdb_comm.SendGDBStoppointTypePacket( - eBreakpointHardware, true, addr, bp_op_size); + eBreakpointHardware, true, addr, bp_op_size, GetInterruptTimeout()); if (error_no == 0) { // The breakpoint was placed successfully bp_site->SetEnabled(true); @@ -3221,13 +3264,15 @@ Status ProcessGDBRemote::DisableBreakpointSite(BreakpointSite *bp_site) { case BreakpointSite::eHardware: if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointHardware, false, - addr, bp_op_size)) + addr, bp_op_size, + GetInterruptTimeout())) error.SetErrorToGenericError(); break; case BreakpointSite::eExternal: { if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointSoftware, false, - addr, bp_op_size)) + addr, bp_op_size, + GetInterruptTimeout())) error.SetErrorToGenericError(); } break; } @@ -3283,7 +3328,8 @@ Status ProcessGDBRemote::EnableWatchpoint(Watchpoint *wp, bool notify) { // Pass down an appropriate z/Z packet... if (m_gdb_comm.SupportsGDBStoppointPacket(type)) { if (m_gdb_comm.SendGDBStoppointTypePacket(type, true, addr, - wp->GetByteSize()) == 0) { + wp->GetByteSize(), + GetInterruptTimeout()) == 0) { wp->SetEnabled(true, notify); return error; } else @@ -3329,7 +3375,8 @@ Status ProcessGDBRemote::DisableWatchpoint(Watchpoint *wp, bool notify) { GDBStoppointType type = GetGDBStoppointType(wp); // Pass down an appropriate z/Z packet... if (m_gdb_comm.SendGDBStoppointTypePacket(type, false, addr, - wp->GetByteSize()) == 0) { + wp->GetByteSize(), + GetInterruptTimeout()) == 0) { wp->SetEnabled(false, notify); return error; } else @@ -3354,7 +3401,7 @@ Status ProcessGDBRemote::DoSignal(int signo) { Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); LLDB_LOGF(log, "ProcessGDBRemote::DoSignal (signal = %d)", signo); - if (!m_gdb_comm.SendAsyncSignal(signo)) + if (!m_gdb_comm.SendAsyncSignal(signo, GetInterruptTimeout())) error.SetErrorStringWithFormat("failed to send signal %i", signo); return error; } @@ -3682,12 +3729,25 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) { __FUNCTION__, arg, process->GetID()); EventSP event_sp; + + // We need to ignore any packets that come in after we have + // have decided the process has exited. There are some + // situations, for instance when we try to interrupt a running + // process and the interrupt fails, where another packet might + // get delivered after we've decided to give up on the process. + // But once we've decided we are done with the process we will + // not be in a state to do anything useful with new packets. + // So it is safer to simply ignore any remaining packets by + // explicitly checking for eStateExited before reentering the + // fetch loop. + bool done = false; - while (!done) { + while (!done && process->GetPrivateState() != eStateExited) { LLDB_LOGF(log, "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp)...", __FUNCTION__, arg, process->GetID()); + if (process->m_async_listener_sp->GetEvent(event_sp, llvm::None)) { const uint32_t event_type = event_sp->GetType(); if (event_sp->BroadcasterIs(&process->m_async_broadcaster)) { @@ -3719,7 +3779,7 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) { // send the vCont packet if (!process->GetGDBRemote().SendvContPacket( llvm::StringRef(continue_cstr, continue_cstr_len), - response)) { + process->GetInterruptTimeout(), response)) { // Something went wrong done = true; break; @@ -3731,6 +3791,7 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) { process->GetGDBRemote().SendContinuePacketAndWaitForResponse( *process, *process->GetUnixSignals(), llvm::StringRef(continue_cstr, continue_cstr_len), + process->GetInterruptTimeout(), response); // We need to immediately clear the thread ID list so we are sure @@ -3786,6 +3847,7 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) { } else { process->SetExitStatus(-1, "lost connection"); } + done = true; break; } @@ -4024,8 +4086,7 @@ ProcessGDBRemote::GetExtendedInfoForThread(lldb::tid_t tid) { StringExtractorGDBRemote response; response.SetResponseValidatorToJSON(); - if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response, - false) == + if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) == GDBRemoteCommunication::PacketResult::Success) { StringExtractorGDBRemote::ResponseType response_type = response.GetResponseType(); @@ -4097,8 +4158,7 @@ ProcessGDBRemote::GetLoadedDynamicLibrariesInfos_sender( StringExtractorGDBRemote response; response.SetResponseValidatorToJSON(); - if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response, - false) == + if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) == GDBRemoteCommunication::PacketResult::Success) { StringExtractorGDBRemote::ResponseType response_type = response.GetResponseType(); @@ -4131,8 +4191,7 @@ StructuredData::ObjectSP ProcessGDBRemote::GetSharedCacheInfo() { StringExtractorGDBRemote response; response.SetResponseValidatorToJSON(); - if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response, - false) == + if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) == GDBRemoteCommunication::PacketResult::Success) { StringExtractorGDBRemote::ResponseType response_type = response.GetResponseType(); @@ -4898,8 +4957,7 @@ Status ProcessGDBRemote::GetFileLoadAddress(const FileSpec &file, packet.PutStringAsRawHex8(file_path); StringExtractorGDBRemote response; - if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response, - false) != + if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) != GDBRemoteCommunication::PacketResult::Success) return Status("Sending qFileLoadAddress packet failed"); @@ -5135,7 +5193,7 @@ public: m_option_group.Finalize(); } - ~CommandObjectProcessGDBRemoteSpeedTest() override {} + ~CommandObjectProcessGDBRemoteSpeedTest() override = default; Options *GetOptions() override { return &m_option_group; } @@ -5186,7 +5244,7 @@ public: : CommandObjectParsed(interpreter, "process plugin packet history", "Dumps the packet history buffer. ", nullptr) {} - ~CommandObjectProcessGDBRemotePacketHistory() override {} + ~CommandObjectProcessGDBRemotePacketHistory() override = default; bool DoExecute(Args &command, CommandReturnObject &result) override { const size_t argc = command.GetArgumentCount(); @@ -5217,7 +5275,7 @@ public: "Maximum size that lldb will try to read/write one one chunk.", nullptr) {} - ~CommandObjectProcessGDBRemotePacketXferSize() override {} + ~CommandObjectProcessGDBRemotePacketXferSize() override = default; bool DoExecute(Args &command, CommandReturnObject &result) override { const size_t argc = command.GetArgumentCount(); @@ -5226,7 +5284,6 @@ public: "amount to be transferred when " "reading/writing", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -5259,7 +5316,7 @@ public: "stripped from the result.", nullptr) {} - ~CommandObjectProcessGDBRemotePacketSend() override {} + ~CommandObjectProcessGDBRemotePacketSend() override = default; bool DoExecute(Args &command, CommandReturnObject &result) override { const size_t argc = command.GetArgumentCount(); @@ -5267,7 +5324,6 @@ public: result.AppendErrorWithFormat( "'%s' takes a one or more packet content arguments", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -5276,10 +5332,9 @@ public: if (process) { for (size_t i = 0; i < argc; ++i) { const char *packet_cstr = command.GetArgumentAtIndex(0); - bool send_async = true; StringExtractorGDBRemote response; process->GetGDBRemote().SendPacketAndWaitForResponse( - packet_cstr, response, send_async); + packet_cstr, response, process->GetInterruptTimeout()); result.SetStatus(eReturnStatusSuccessFinishResult); Stream &output_strm = result.GetOutputStream(); output_strm.Printf(" packet: %s\n", packet_cstr); @@ -5310,14 +5365,13 @@ public: "encoded into a valid 'qRcmd' packet, sent and the " "response will be printed.") {} - ~CommandObjectProcessGDBRemotePacketMonitor() override {} + ~CommandObjectProcessGDBRemotePacketMonitor() override = default; bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override { if (command.empty()) { result.AppendErrorWithFormat("'%s' takes a command string argument", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -5328,11 +5382,10 @@ public: packet.PutCString("qRcmd,"); packet.PutBytesAsRawHex8(command.data(), command.size()); - bool send_async = true; StringExtractorGDBRemote response; Stream &output_strm = result.GetOutputStream(); process->GetGDBRemote().SendPacketAndReceiveResponseWithOutputSupport( - packet.GetString(), response, send_async, + packet.GetString(), response, process->GetInterruptTimeout(), [&output_strm](llvm::StringRef output) { output_strm << output; }); result.SetStatus(eReturnStatusSuccessFinishResult); output_strm.Printf(" packet: %s\n", packet.GetData()); @@ -5374,7 +5427,7 @@ public: interpreter))); } - ~CommandObjectProcessGDBRemotePacket() override {} + ~CommandObjectProcessGDBRemotePacket() override = default; }; class CommandObjectMultiwordProcessGDBRemote : public CommandObjectMultiword { @@ -5389,7 +5442,7 @@ public: CommandObjectSP(new CommandObjectProcessGDBRemotePacket(interpreter))); } - ~CommandObjectMultiwordProcessGDBRemote() override {} + ~CommandObjectMultiwordProcessGDBRemote() override = default; }; CommandObject *ProcessGDBRemote::GetPluginCommandObject() { diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index 0921bf17c4e4..fe04cdddd0f5 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -68,6 +68,8 @@ public: static const char *GetPluginDescriptionStatic(); + static std::chrono::seconds GetPacketTimeout(); + // Check if a given Process bool CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) override; @@ -163,22 +165,16 @@ public: Status GetWatchpointSupportInfo(uint32_t &num) override; - lldb::user_id_t StartTrace(const TraceOptions &options, - Status &error) override; - - Status StopTrace(lldb::user_id_t uid, lldb::tid_t thread_id) override; + llvm::Expected<TraceSupportedResponse> TraceSupported() override; - Status GetData(lldb::user_id_t uid, lldb::tid_t thread_id, - llvm::MutableArrayRef<uint8_t> &buffer, - size_t offset = 0) override; + llvm::Error TraceStop(const TraceStopRequest &request) override; - Status GetMetaData(lldb::user_id_t uid, lldb::tid_t thread_id, - llvm::MutableArrayRef<uint8_t> &buffer, - size_t offset = 0) override; + llvm::Error TraceStart(const llvm::json::Value &request) override; - llvm::Expected<TraceTypeInfo> GetSupportedTraceType() override; + llvm::Expected<std::string> TraceGetState(llvm::StringRef type) override; - Status GetTraceConfig(lldb::user_id_t uid, TraceOptions &options) override; + llvm::Expected<std::vector<uint8_t>> + TraceGetBinaryData(const TraceGetBinaryDataRequest &request) override; Status GetWatchpointSupportInfo(uint32_t &num, bool &after) override; @@ -239,6 +235,8 @@ protected: friend class GDBRemoteCommunicationClient; friend class GDBRemoteRegisterContext; + bool SupportsMemoryTagging() override; + /// Broadcaster event bits definitions. enum { eBroadcastBitAsyncContinue = (1 << 0), @@ -339,7 +337,7 @@ protected: size_t UpdateThreadPCsFromStopReplyThreadsValue(std::string &value); - size_t UpdateThreadIDsFromStopReplyThreadsValue(std::string &value); + size_t UpdateThreadIDsFromStopReplyThreadsValue(llvm::StringRef value); bool HandleNotifyPacket(StringExtractorGDBRemote &packet); @@ -410,6 +408,12 @@ protected: bool HasErased(FlashRange range); + llvm::Expected<std::vector<uint8_t>> + DoReadMemoryTags(lldb::addr_t addr, size_t len, int32_t type) override; + + Status DoWriteMemoryTags(lldb::addr_t addr, size_t len, int32_t type, + const std::vector<uint8_t> &tags) override; + private: // For ProcessGDBRemote only std::string m_partial_profile_data; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp index 05a48acc2f7a..385557422758 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp @@ -138,10 +138,10 @@ private: /// /// \param[in] module_sp The module to grab the .text section from. /// -/// \param[in/out] breakpad_uuid A vector that will receive the calculated +/// \param[in,out] breakpad_uuid A vector that will receive the calculated /// breakpad .text hash. /// -/// \param[in/out] facebook_uuid A vector that will receive the calculated +/// \param[in,out] facebook_uuid A vector that will receive the calculated /// facebook .text hash. /// void HashElfTextSection(ModuleSP module_sp, std::vector<uint8_t> &breakpad_uuid, @@ -548,7 +548,7 @@ void ProcessMinidump::ReadModuleList() { // check if the process is wow64 - a 32 bit windows process running on a // 64 bit windows - if (llvm::StringRef(name).endswith_lower("wow64.dll")) { + if (llvm::StringRef(name).endswith_insensitive("wow64.dll")) { m_is_wow64 = true; } @@ -871,7 +871,7 @@ public: m_option_group.Finalize(); } - ~CommandObjectProcessMinidumpDump() override {} + ~CommandObjectProcessMinidumpDump() override = default; Options *GetOptions() override { return &m_option_group; } @@ -880,7 +880,6 @@ public: if (argc > 0) { result.AppendErrorWithFormat("'%s' take no arguments, only options", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } SetDefaultOptionsIfNoneAreSet(); @@ -1001,7 +1000,7 @@ public: CommandObjectSP(new CommandObjectProcessMinidumpDump(interpreter))); } - ~CommandObjectMultiwordProcessMinidump() override {} + ~CommandObjectMultiwordProcessMinidump() override = default; }; CommandObject *ProcessMinidump::GetPluginCommandObject() { diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp index eb48785263fc..7e309e8322a8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp @@ -16,7 +16,7 @@ #include "lldb/lldb-enumerations.h" // C includes -#include <assert.h> +#include <cassert> // C++ includes diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp index c7809c5f19b6..e2b7c0e362a7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp @@ -14,7 +14,7 @@ #include "lldb/lldb-enumerations.h" // C includes -#include <assert.h> +#include <cassert> // C++ includes diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp index e146a1a1af92..1fbc52815238 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp @@ -38,7 +38,7 @@ ThreadMinidump::ThreadMinidump(Process &process, const minidump::Thread &td, : Thread(process, td.ThreadId), m_thread_reg_ctx_sp(), m_gpregset_data(gpregset_data) {} -ThreadMinidump::~ThreadMinidump() {} +ThreadMinidump::~ThreadMinidump() = default; void ThreadMinidump::RefreshStateAfterStop() {} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp new file mode 100644 index 000000000000..09e9375b6f66 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp @@ -0,0 +1,313 @@ +//===-- ScriptedProcess.cpp -----------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "ScriptedProcess.h" + +#include "lldb/Core/Debugger.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" + +#include "lldb/Host/OptionParser.h" +#include "lldb/Host/ThreadLauncher.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/OptionArgParser.h" +#include "lldb/Interpreter/OptionGroupBoolean.h" +#include "lldb/Interpreter/ScriptInterpreter.h" +#include "lldb/Target/MemoryRegionInfo.h" +#include "lldb/Target/RegisterContext.h" + +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Logging.h" +#include "lldb/Utility/State.h" + +#include <mutex> + +LLDB_PLUGIN_DEFINE(ScriptedProcess) + +using namespace lldb; +using namespace lldb_private; + +ConstString ScriptedProcess::GetPluginNameStatic() { + static ConstString g_name("ScriptedProcess"); + return g_name; +} + +const char *ScriptedProcess::GetPluginDescriptionStatic() { + return "Scripted Process plug-in."; +} + +static constexpr lldb::ScriptLanguage g_supported_script_languages[] = { + ScriptLanguage::eScriptLanguagePython, +}; + +bool ScriptedProcess::IsScriptLanguageSupported(lldb::ScriptLanguage language) { + llvm::ArrayRef<lldb::ScriptLanguage> supported_languages = + llvm::makeArrayRef(g_supported_script_languages); + + return llvm::is_contained(supported_languages, language); +} + +void ScriptedProcess::CheckInterpreterAndScriptObject() const { + lldbassert(m_interpreter && "Invalid Script Interpreter."); + lldbassert(m_script_object_sp && "Invalid Script Object."); +} + +lldb::ProcessSP ScriptedProcess::CreateInstance(lldb::TargetSP target_sp, + lldb::ListenerSP listener_sp, + const FileSpec *file, + bool can_connect) { + if (!target_sp || + !IsScriptLanguageSupported(target_sp->GetDebugger().GetScriptLanguage())) + return nullptr; + + Status error; + ScriptedProcess::ScriptedProcessInfo scripted_process_info( + target_sp->GetProcessLaunchInfo()); + + auto process_sp = std::make_shared<ScriptedProcess>( + target_sp, listener_sp, scripted_process_info, error); + + if (error.Fail() || !process_sp || !process_sp->m_script_object_sp || + !process_sp->m_script_object_sp->IsValid()) { + LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS), "%s", + error.AsCString()); + return nullptr; + } + + return process_sp; +} + +bool ScriptedProcess::CanDebug(lldb::TargetSP target_sp, + bool plugin_specified_by_name) { + return true; +} + +ScriptedProcess::ScriptedProcess( + lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, + const ScriptedProcess::ScriptedProcessInfo &scripted_process_info, + Status &error) + : Process(target_sp, listener_sp), + m_scripted_process_info(scripted_process_info) { + + if (!target_sp) { + error.SetErrorStringWithFormat("ScriptedProcess::%s () - ERROR: %s", + __FUNCTION__, "Invalid target"); + return; + } + + m_interpreter = target_sp->GetDebugger().GetScriptInterpreter(); + + if (!m_interpreter) { + error.SetErrorStringWithFormat("ScriptedProcess::%s () - ERROR: %s", + __FUNCTION__, + "Debugger has no Script Interpreter"); + return; + } + + StructuredData::ObjectSP object_sp = GetInterface().CreatePluginObject( + m_scripted_process_info.GetClassName().c_str(), target_sp, + m_scripted_process_info.GetDictionarySP()); + + if (!object_sp || !object_sp->IsValid()) { + error.SetErrorStringWithFormat("ScriptedProcess::%s () - ERROR: %s", + __FUNCTION__, + "Failed to create valid script object"); + return; + } + + m_script_object_sp = object_sp; +} + +ScriptedProcess::~ScriptedProcess() { + Clear(); + // We need to call finalize on the process before destroying ourselves to + // make sure all of the broadcaster cleanup goes as planned. If we destruct + // this class, then Process::~Process() might have problems trying to fully + // destroy the broadcaster. + Finalize(); +} + +void ScriptedProcess::Initialize() { + static llvm::once_flag g_once_flag; + + llvm::call_once(g_once_flag, []() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), CreateInstance); + }); +} + +void ScriptedProcess::Terminate() { + PluginManager::UnregisterPlugin(ScriptedProcess::CreateInstance); +} + +ConstString ScriptedProcess::GetPluginName() { return GetPluginNameStatic(); } + +uint32_t ScriptedProcess::GetPluginVersion() { return 1; } + +Status ScriptedProcess::DoLoadCore() { + ProcessLaunchInfo launch_info = GetTarget().GetProcessLaunchInfo(); + + return DoLaunch(nullptr, launch_info); +} + +Status ScriptedProcess::DoLaunch(Module *exe_module, + ProcessLaunchInfo &launch_info) { + CheckInterpreterAndScriptObject(); + + /* FIXME: This doesn't reflect how lldb actually launches a process. + In reality, it attaches to debugserver, then resume the process. */ + Status error = GetInterface().Launch(); + SetPrivateState(eStateRunning); + + if (error.Fail()) + return error; + + // TODO: Fetch next state from stopped event queue then send stop event + // const StateType state = SetThreadStopInfo(response); + // if (state != eStateInvalid) { + // SetPrivateState(state); + + SetPrivateState(eStateStopped); + + UpdateThreadListIfNeeded(); + GetThreadList(); + + return {}; +} + +void ScriptedProcess::DidLaunch() { + CheckInterpreterAndScriptObject(); + m_pid = GetInterface().GetProcessID(); +} + +Status ScriptedProcess::DoResume() { + CheckInterpreterAndScriptObject(); + + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + // FIXME: Fetch data from thread. + const StateType thread_resume_state = eStateRunning; + LLDB_LOGF(log, "ScriptedProcess::%s thread_resume_state = %s", __FUNCTION__, + StateAsCString(thread_resume_state)); + + bool resume = (thread_resume_state == eStateRunning); + assert(thread_resume_state == eStateRunning && "invalid thread resume state"); + + Status error; + if (resume) { + LLDB_LOGF(log, "ScriptedProcess::%s sending resume", __FUNCTION__); + + SetPrivateState(eStateRunning); + SetPrivateState(eStateStopped); + error = GetInterface().Resume(); + } + + return error; +} + +Status ScriptedProcess::DoStop() { + CheckInterpreterAndScriptObject(); + + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + + if (GetInterface().ShouldStop()) { + SetPrivateState(eStateStopped); + LLDB_LOGF(log, "ScriptedProcess::%s Immediate stop", __FUNCTION__); + return {}; + } + + LLDB_LOGF(log, "ScriptedProcess::%s Delayed stop", __FUNCTION__); + return GetInterface().Stop(); +} + +Status ScriptedProcess::DoDestroy() { return Status(); } + +bool ScriptedProcess::IsAlive() { + if (m_interpreter && m_script_object_sp) + return GetInterface().IsAlive(); + return false; +} + +size_t ScriptedProcess::DoReadMemory(lldb::addr_t addr, void *buf, size_t size, + Status &error) { + + auto error_with_message = [&error](llvm::StringRef message) { + error.SetErrorString(message); + return 0; + }; + + if (!m_interpreter) + return error_with_message("No interpreter."); + + lldb::DataExtractorSP data_extractor_sp = + GetInterface().ReadMemoryAtAddress(addr, size, error); + + if (!data_extractor_sp || error.Fail()) + return 0; + + offset_t bytes_copied = data_extractor_sp->CopyByteOrderedData( + 0, data_extractor_sp->GetByteSize(), buf, size, GetByteOrder()); + + if (!bytes_copied || bytes_copied == LLDB_INVALID_OFFSET) + return error_with_message("Failed to copy read memory to buffer."); + + return size; +} + +ArchSpec ScriptedProcess::GetArchitecture() { + return GetTarget().GetArchitecture(); +} + +Status ScriptedProcess::GetMemoryRegionInfo(lldb::addr_t load_addr, + MemoryRegionInfo ®ion) { + // TODO: Implement + return Status(); +} + +Status ScriptedProcess::GetMemoryRegions(MemoryRegionInfos ®ion_list) { + CheckInterpreterAndScriptObject(); + + lldb::addr_t address = 0; + lldb::MemoryRegionInfoSP mem_region_sp = nullptr; + + while ((mem_region_sp = + GetInterface().GetMemoryRegionContainingAddress(address))) { + auto range = mem_region_sp->GetRange(); + address += range.GetRangeBase() + range.GetByteSize(); + region_list.push_back(*mem_region_sp.get()); + } + + return {}; +} + +void ScriptedProcess::Clear() { Process::m_thread_list.Clear(); } + +bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list, + ThreadList &new_thread_list) { + // TODO: Implement + // This is supposed to get the current set of threads, if any of them are in + // old_thread_list then they get copied to new_thread_list, and then any + // actually new threads will get added to new_thread_list. + return new_thread_list.GetSize(false) > 0; +} + +bool ScriptedProcess::GetProcessInfo(ProcessInstanceInfo &info) { + info.Clear(); + info.SetProcessID(GetID()); + info.SetArchitecture(GetArchitecture()); + lldb::ModuleSP module_sp = GetTarget().GetExecutableModule(); + if (module_sp) { + const bool add_exe_file_as_first_arg = false; + info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(), + add_exe_file_as_first_arg); + } + return true; +} + +ScriptedProcessInterface &ScriptedProcess::GetInterface() const { + return m_interpreter->GetScriptedProcessInterface(); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.h b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.h new file mode 100644 index 000000000000..98c1a1ca4fe9 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.h @@ -0,0 +1,119 @@ +//===-- ScriptedProcess.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_SOURCE_PLUGINS_SCRIPTED_PROCESS_H +#define LLDB_SOURCE_PLUGINS_SCRIPTED_PROCESS_H + +#include "lldb/Target/Process.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/Status.h" + +#include <mutex> + +namespace lldb_private { + +class ScriptedProcess : public Process { +protected: + class ScriptedProcessInfo { + public: + ScriptedProcessInfo(const ProcessLaunchInfo &launch_info) { + m_class_name = launch_info.GetScriptedProcessClassName(); + m_dictionary_sp = launch_info.GetScriptedProcessDictionarySP(); + } + + std::string GetClassName() const { return m_class_name; } + StructuredData::DictionarySP GetDictionarySP() const { + return m_dictionary_sp; + } + + private: + std::string m_class_name; + StructuredData::DictionarySP m_dictionary_sp; + }; + +public: + static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp, + lldb::ListenerSP listener_sp, + const FileSpec *crash_file_path, + bool can_connect); + + static void Initialize(); + + static void Terminate(); + + static ConstString GetPluginNameStatic(); + + static const char *GetPluginDescriptionStatic(); + + ScriptedProcess(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, + const ScriptedProcess::ScriptedProcessInfo &launch_info, + Status &error); + + ~ScriptedProcess() override; + + bool CanDebug(lldb::TargetSP target_sp, + bool plugin_specified_by_name) override; + + DynamicLoader *GetDynamicLoader() override { return nullptr; } + + ConstString GetPluginName() override; + + uint32_t GetPluginVersion() override; + + SystemRuntime *GetSystemRuntime() override { return nullptr; } + + Status DoLoadCore() override; + + Status DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) override; + + void DidLaunch() override; + + Status DoResume() override; + + Status DoDestroy() override; + + void RefreshStateAfterStop() override{}; + + bool IsAlive() override; + + size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size, + Status &error) override; + + ArchSpec GetArchitecture(); + + Status GetMemoryRegionInfo(lldb::addr_t load_addr, + MemoryRegionInfo &range_info) override; + + Status + GetMemoryRegions(lldb_private::MemoryRegionInfos ®ion_list) override; + + bool GetProcessInfo(ProcessInstanceInfo &info) override; + +protected: + Status DoStop(); + + void Clear(); + + bool DoUpdateThreadList(ThreadList &old_thread_list, + ThreadList &new_thread_list) override; + +private: + void CheckInterpreterAndScriptObject() const; + ScriptedProcessInterface &GetInterface() const; + static bool IsScriptLanguageSupported(lldb::ScriptLanguage language); + + // Member variables. + const ScriptedProcessInfo m_scripted_process_info; + lldb_private::ScriptInterpreter *m_interpreter = nullptr; + lldb_private::StructuredData::ObjectSP m_script_object_sp = nullptr; + //@} +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_SCRIPTED_PROCESS_H diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp index f14e2732f6eb..e99b7b88379a 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp @@ -30,6 +30,9 @@ extern "C" llvm::Expected<bool> LLDBSwigLuaBreakpointCallbackFunction( lua_State *L, lldb::StackFrameSP stop_frame_sp, lldb::BreakpointLocationSP bp_loc_sp, StructuredDataImpl *extra_args_impl); +extern "C" llvm::Expected<bool> LLDBSwigLuaWatchpointCallbackFunction( + lua_State *L, lldb::StackFrameSP stop_frame_sp, lldb::WatchpointSP wp_sp); + #if _MSC_VER #pragma warning (pop) #endif @@ -113,6 +116,32 @@ Lua::CallBreakpointCallback(void *baton, lldb::StackFrameSP stop_frame_sp, bp_loc_sp, extra_args_impl); } +llvm::Error Lua::RegisterWatchpointCallback(void *baton, const char *body) { + lua_pushlightuserdata(m_lua_state, baton); + const char *fmt_str = "return function(frame, wp, ...) {0} end"; + std::string func_str = llvm::formatv(fmt_str, body).str(); + if (luaL_dostring(m_lua_state, func_str.c_str()) != LUA_OK) { + llvm::Error e = llvm::make_error<llvm::StringError>( + llvm::formatv("{0}", lua_tostring(m_lua_state, -1)), + llvm::inconvertibleErrorCode()); + // Pop error message from the stack. + lua_pop(m_lua_state, 2); + return e; + } + lua_settable(m_lua_state, LUA_REGISTRYINDEX); + return llvm::Error::success(); +} + +llvm::Expected<bool> +Lua::CallWatchpointCallback(void *baton, lldb::StackFrameSP stop_frame_sp, + lldb::WatchpointSP wp_sp) { + + lua_pushlightuserdata(m_lua_state, baton); + lua_gettable(m_lua_state, LUA_REGISTRYINDEX); + return LLDBSwigLuaWatchpointCallbackFunction(m_lua_state, stop_frame_sp, + wp_sp); +} + llvm::Error Lua::CheckSyntax(llvm::StringRef buffer) { int error = luaL_loadbuffer(m_lua_state, buffer.data(), buffer.size(), "buffer"); diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h index 873440f0aab3..5daedf835b9b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h @@ -37,6 +37,10 @@ public: CallBreakpointCallback(void *baton, lldb::StackFrameSP stop_frame_sp, lldb::BreakpointLocationSP bp_loc_sp, StructuredData::ObjectSP extra_args_sp); + llvm::Error RegisterWatchpointCallback(void *baton, const char *body); + llvm::Expected<bool> CallWatchpointCallback(void *baton, + lldb::StackFrameSP stop_frame_sp, + lldb::WatchpointSP wp_sp); llvm::Error LoadModule(llvm::StringRef filename); llvm::Error CheckSyntax(llvm::StringRef buffer); llvm::Error ChangeIO(FILE *out, FILE *err); diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp index 920e334f51aa..ef46401c8b46 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp @@ -58,7 +58,13 @@ public: const char *instructions = nullptr; switch (m_active_io_handler) { case eIOHandlerNone: + break; case eIOHandlerWatchpoint: + instructions = "Enter your Lua command(s). Type 'quit' to end.\n" + "The commands are compiled as the body of the following " + "Lua function\n" + "function (frame, wp) end\n"; + SetPrompt(llvm::StringRef("..> ")); break; case eIOHandlerBreakpoint: instructions = "Enter your Lua command(s). Type 'quit' to end.\n" @@ -78,7 +84,8 @@ public: StringList &lines) override { size_t last = lines.GetSize() - 1; if (IsQuitCommand(lines.GetStringAtIndex(last))) { - if (m_active_io_handler == eIOHandlerBreakpoint) + if (m_active_io_handler == eIOHandlerBreakpoint || + m_active_io_handler == eIOHandlerWatchpoint) lines.DeleteStringAtIndex(last); return true; } @@ -90,17 +97,19 @@ public: // Lua always errors out to incomplete code with '<eof>' return error_str.find("<eof>") == std::string::npos; } - // The breakpoint handler only exits with a explicit 'quit' - return m_active_io_handler != eIOHandlerBreakpoint; + // The breakpoint and watchpoint handler only exits with a explicit 'quit' + return m_active_io_handler != eIOHandlerBreakpoint && + m_active_io_handler != eIOHandlerWatchpoint; } void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override { switch (m_active_io_handler) { case eIOHandlerBreakpoint: { - auto *bp_options_vec = static_cast<std::vector<BreakpointOptions *> *>( - io_handler.GetUserData()); - for (auto *bp_options : *bp_options_vec) { + auto *bp_options_vec = + static_cast<std::vector<std::reference_wrapper<BreakpointOptions>> *>( + io_handler.GetUserData()); + for (BreakpointOptions &bp_options : *bp_options_vec) { Status error = m_script_interpreter.SetBreakpointCommandCallback( bp_options, data.c_str()); if (error.Fail()) @@ -108,9 +117,13 @@ public: } io_handler.SetIsDone(true); } break; - case eIOHandlerWatchpoint: + case eIOHandlerWatchpoint: { + auto *wp_options = + static_cast<WatchpointOptions *>(io_handler.GetUserData()); + m_script_interpreter.SetWatchpointCommandCallback(wp_options, + data.c_str()); io_handler.SetIsDone(true); - break; + } break; case eIOHandlerNone: if (IsQuitCommand(data)) { io_handler.SetIsDone(true); @@ -133,7 +146,7 @@ ScriptInterpreterLua::ScriptInterpreterLua(Debugger &debugger) : ScriptInterpreter(debugger, eScriptLanguageLua), m_lua(std::make_unique<Lua>()) {} -ScriptInterpreterLua::~ScriptInterpreterLua() {} +ScriptInterpreterLua::~ScriptInterpreterLua() = default; bool ScriptInterpreterLua::ExecuteOneLine(llvm::StringRef command, CommandReturnObject *result, @@ -194,8 +207,9 @@ void ScriptInterpreterLua::ExecuteInterpreterLoop() { } bool ScriptInterpreterLua::LoadScriptingModule( - const char *filename, bool init_session, lldb_private::Status &error, - StructuredData::ObjectSP *module_sp, FileSpec extra_search_dir) { + const char *filename, const LoadScriptOptions &options, + lldb_private::Status &error, StructuredData::ObjectSP *module_sp, + FileSpec extra_search_dir) { FileSystem::Instance().Collect(filename); if (llvm::Error e = m_lua->LoadModule(filename)) { @@ -275,8 +289,35 @@ bool ScriptInterpreterLua::BreakpointCallbackFunction( return *BoolOrErr; } +bool ScriptInterpreterLua::WatchpointCallbackFunction( + void *baton, StoppointCallbackContext *context, user_id_t watch_id) { + assert(context); + + ExecutionContext exe_ctx(context->exe_ctx_ref); + Target *target = exe_ctx.GetTargetPtr(); + if (target == nullptr) + return true; + + StackFrameSP stop_frame_sp(exe_ctx.GetFrameSP()); + WatchpointSP wp_sp = target->GetWatchpointList().FindByID(watch_id); + + Debugger &debugger = target->GetDebugger(); + ScriptInterpreterLua *lua_interpreter = static_cast<ScriptInterpreterLua *>( + debugger.GetScriptInterpreter(true, eScriptLanguageLua)); + Lua &lua = lua_interpreter->GetLua(); + + llvm::Expected<bool> BoolOrErr = + lua.CallWatchpointCallback(baton, stop_frame_sp, wp_sp); + if (llvm::Error E = BoolOrErr.takeError()) { + debugger.GetErrorStream() << toString(std::move(E)); + return true; + } + + return *BoolOrErr; +} + void ScriptInterpreterLua::CollectDataForBreakpointCommandCallback( - std::vector<BreakpointOptions *> &bp_options_vec, + std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec, CommandReturnObject &result) { IOHandlerSP io_handler_sp( new IOHandlerLuaInterpreter(m_debugger, *this, eIOHandlerBreakpoint)); @@ -284,8 +325,16 @@ void ScriptInterpreterLua::CollectDataForBreakpointCommandCallback( m_debugger.RunIOHandlerAsync(io_handler_sp); } +void ScriptInterpreterLua::CollectDataForWatchpointCommandCallback( + WatchpointOptions *wp_options, CommandReturnObject &result) { + IOHandlerSP io_handler_sp( + new IOHandlerLuaInterpreter(m_debugger, *this, eIOHandlerWatchpoint)); + io_handler_sp->SetUserData(wp_options); + m_debugger.RunIOHandlerAsync(io_handler_sp); +} + Status ScriptInterpreterLua::SetBreakpointCommandCallbackFunction( - BreakpointOptions *bp_options, const char *function_name, + BreakpointOptions &bp_options, const char *function_name, StructuredData::ObjectSP extra_args_sp) { const char *fmt_str = "return {0}(frame, bp_loc, ...)"; std::string oneliner = llvm::formatv(fmt_str, function_name).str(); @@ -294,12 +343,12 @@ Status ScriptInterpreterLua::SetBreakpointCommandCallbackFunction( } Status ScriptInterpreterLua::SetBreakpointCommandCallback( - BreakpointOptions *bp_options, const char *command_body_text) { + BreakpointOptions &bp_options, const char *command_body_text) { return RegisterBreakpointCallback(bp_options, command_body_text, {}); } Status ScriptInterpreterLua::RegisterBreakpointCallback( - BreakpointOptions *bp_options, const char *command_body_text, + BreakpointOptions &bp_options, const char *command_body_text, StructuredData::ObjectSP extra_args_sp) { Status error; auto data_up = std::make_unique<CommandDataLua>(extra_args_sp); @@ -308,7 +357,27 @@ Status ScriptInterpreterLua::RegisterBreakpointCallback( return error; auto baton_sp = std::make_shared<BreakpointOptions::CommandBaton>(std::move(data_up)); - bp_options->SetCallback(ScriptInterpreterLua::BreakpointCallbackFunction, + bp_options.SetCallback(ScriptInterpreterLua::BreakpointCallbackFunction, + baton_sp); + return error; +} + +void ScriptInterpreterLua::SetWatchpointCommandCallback( + WatchpointOptions *wp_options, const char *command_body_text) { + RegisterWatchpointCallback(wp_options, command_body_text, {}); +} + +Status ScriptInterpreterLua::RegisterWatchpointCallback( + WatchpointOptions *wp_options, const char *command_body_text, + StructuredData::ObjectSP extra_args_sp) { + Status error; + auto data_up = std::make_unique<WatchpointOptions::CommandData>(); + error = m_lua->RegisterWatchpointCallback(data_up.get(), command_body_text); + if (error.Fail()) + return error; + auto baton_sp = + std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_up)); + wp_options->SetCallback(ScriptInterpreterLua::WatchpointCallbackFunction, baton_sp); return error; } diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h index 1130ceee3c20..808000b833ec 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h @@ -9,6 +9,9 @@ #ifndef liblldb_ScriptInterpreterLua_h_ #define liblldb_ScriptInterpreterLua_h_ +#include <vector> + +#include "lldb/Breakpoint/WatchpointOptions.h" #include "lldb/Core/StructuredDataImpl.h" #include "lldb/Interpreter/ScriptInterpreter.h" #include "lldb/Utility/Status.h" @@ -40,7 +43,8 @@ public: void ExecuteInterpreterLoop() override; - bool LoadScriptingModule(const char *filename, bool init_session, + bool LoadScriptingModule(const char *filename, + const LoadScriptOptions &options, lldb_private::Status &error, StructuredData::ObjectSP *module_sp = nullptr, FileSpec extra_search_dir = {}) override; @@ -61,6 +65,10 @@ public: lldb::user_id_t break_id, lldb::user_id_t break_loc_id); + static bool WatchpointCallbackFunction(void *baton, + StoppointCallbackContext *context, + lldb::user_id_t watch_id); + // PluginInterface protocol lldb_private::ConstString GetPluginName() override; @@ -72,21 +80,32 @@ public: llvm::Error LeaveSession(); void CollectDataForBreakpointCommandCallback( - std::vector<BreakpointOptions *> &bp_options_vec, + std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec, CommandReturnObject &result) override; - Status SetBreakpointCommandCallback(BreakpointOptions *bp_options, + void + CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options, + CommandReturnObject &result) override; + + Status SetBreakpointCommandCallback(BreakpointOptions &bp_options, const char *command_body_text) override; + void SetWatchpointCommandCallback(WatchpointOptions *wp_options, + const char *command_body_text) override; + Status SetBreakpointCommandCallbackFunction( - BreakpointOptions *bp_options, const char *function_name, + BreakpointOptions &bp_options, const char *function_name, StructuredData::ObjectSP extra_args_sp) override; private: std::unique_ptr<Lua> m_lua; bool m_session_is_active = false; - Status RegisterBreakpointCallback(BreakpointOptions *bp_options, + Status RegisterBreakpointCallback(BreakpointOptions &bp_options, + const char *command_body_text, + StructuredData::ObjectSP extra_args_sp); + + Status RegisterWatchpointCallback(WatchpointOptions *wp_options, const char *command_body_text, StructuredData::ObjectSP extra_args_sp); }; diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp index d9c32cc132d4..f8a385240bd9 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp @@ -25,7 +25,7 @@ LLDB_PLUGIN_DEFINE(ScriptInterpreterNone) ScriptInterpreterNone::ScriptInterpreterNone(Debugger &debugger) : ScriptInterpreter(debugger, eScriptLanguageNone) {} -ScriptInterpreterNone::~ScriptInterpreterNone() {} +ScriptInterpreterNone::~ScriptInterpreterNone() = default; bool ScriptInterpreterNone::ExecuteOneLine(llvm::StringRef command, CommandReturnObject *, diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp index 7c49502f1b57..f51d9b3a796c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp @@ -24,7 +24,7 @@ #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/Errno.h" -#include <stdio.h> +#include <cstdio> using namespace lldb_private; using namespace lldb; diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h index 22f6c67eb7a5..4577253227cd 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h @@ -229,7 +229,7 @@ struct PythonFormat< class PythonObject { public: - PythonObject() : m_py_obj(nullptr) {} + PythonObject() = default; PythonObject(PyRefType type, PyObject *py_obj) { m_py_obj = py_obj; @@ -378,7 +378,7 @@ public: } protected: - PyObject *m_py_obj; + PyObject *m_py_obj = nullptr; }; @@ -421,7 +421,7 @@ public: Py_DECREF(py_obj); } - TypedPythonObject() {} + TypedPythonObject() = default; }; class PythonBytes : public TypedPythonObject<PythonBytes> { diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonReadline.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonReadline.cpp index 5f6429f5cd0e..95a3365ed983 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonReadline.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonReadline.cpp @@ -2,7 +2,7 @@ #ifdef LLDB_USE_LIBEDIT_READLINE_COMPAT_MODULE -#include <stdio.h> +#include <cstdio> #include <editline/readline.h> diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.cpp new file mode 100644 index 000000000000..7c7c5d73680a --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.cpp @@ -0,0 +1,48 @@ +//===-- SWIGPythonBridge.cpp ----------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "lldb/Host/Config.h" +#include "lldb/lldb-enumerations.h" + +#if LLDB_ENABLE_PYTHON + +// LLDB Python header must be included first +#include "lldb-python.h" + +#include "SWIGPythonBridge.h" + +using namespace lldb; + +namespace lldb_private { + +template <typename T> const char *GetPythonValueFormatString(T t); +template <> const char *GetPythonValueFormatString(char *) { return "s"; } +template <> const char *GetPythonValueFormatString(char) { return "b"; } +template <> const char *GetPythonValueFormatString(unsigned char) { + return "B"; +} +template <> const char *GetPythonValueFormatString(short) { return "h"; } +template <> const char *GetPythonValueFormatString(unsigned short) { + return "H"; +} +template <> const char *GetPythonValueFormatString(int) { return "i"; } +template <> const char *GetPythonValueFormatString(unsigned int) { return "I"; } +template <> const char *GetPythonValueFormatString(long) { return "l"; } +template <> const char *GetPythonValueFormatString(unsigned long) { + return "k"; +} +template <> const char *GetPythonValueFormatString(long long) { return "L"; } +template <> const char *GetPythonValueFormatString(unsigned long long) { + return "K"; +} +template <> const char *GetPythonValueFormatString(float) { return "f"; } +template <> const char *GetPythonValueFormatString(double) { return "d"; } + +} // namespace lldb_private + +#endif // LLDB_ENABLE_PYTHON diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h new file mode 100644 index 000000000000..1ef792bcf303 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h @@ -0,0 +1,56 @@ +//===-- ScriptInterpreterPython.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_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H +#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H + +#include <string> + +#include "lldb/Host/Config.h" + +#if LLDB_ENABLE_PYTHON + +#include "lldb/lldb-forward.h" +#include "lldb/lldb-types.h" + +namespace lldb_private { + +// GetPythonValueFormatString provides a system independent type safe way to +// convert a variable's type into a python value format. Python value formats +// are defined in terms of builtin C types and could change from system to as +// the underlying typedef for uint* types, size_t, off_t and other values +// change. + +template <typename T> const char *GetPythonValueFormatString(T t); +template <> const char *GetPythonValueFormatString(char *); +template <> const char *GetPythonValueFormatString(char); +template <> const char *GetPythonValueFormatString(unsigned char); +template <> const char *GetPythonValueFormatString(short); +template <> const char *GetPythonValueFormatString(unsigned short); +template <> const char *GetPythonValueFormatString(int); +template <> const char *GetPythonValueFormatString(unsigned int); +template <> const char *GetPythonValueFormatString(long); +template <> const char *GetPythonValueFormatString(unsigned long); +template <> const char *GetPythonValueFormatString(long long); +template <> const char *GetPythonValueFormatString(unsigned long long); +template <> const char *GetPythonValueFormatString(float t); +template <> const char *GetPythonValueFormatString(double t); + +extern "C" void *LLDBSwigPythonCreateScriptedProcess( + const char *python_class_name, const char *session_dictionary_name, + const lldb::TargetSP &target_sp, StructuredDataImpl *args_impl, + std::string &error_string); + +extern "C" void *LLDBSWIGPython_CastPyObjectToSBData(void *data); +extern "C" void *LLDBSWIGPython_CastPyObjectToSBError(void *data); +extern "C" void *LLDBSWIGPython_CastPyObjectToSBValue(void *data); + +} // namespace lldb_private + +#endif // LLDB_ENABLE_PYTHON +#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp index 6b53bd3a2edc..7ad63722c31c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp @@ -16,7 +16,11 @@ #include "PythonDataObjects.h" #include "PythonReadline.h" +#include "SWIGPythonBridge.h" #include "ScriptInterpreterPythonImpl.h" +#include "ScriptedProcessPythonInterface.h" + +#include "lldb/API/SBError.h" #include "lldb/API/SBFrame.h" #include "lldb/API/SBValue.h" #include "lldb/Breakpoint/StoppointCallbackContext.h" @@ -41,10 +45,10 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/FormatAdapters.h" +#include <cstdio> +#include <cstdlib> #include <memory> #include <mutex> -#include <stdio.h> -#include <stdlib.h> #include <string> using namespace lldb; @@ -148,8 +152,6 @@ extern "C" void *LLDBSwigPython_GetChildAtIndex(void *implementor, extern "C" int LLDBSwigPython_GetIndexOfChildWithName(void *implementor, const char *child_name); -extern "C" void *LLDBSWIGPython_CastPyObjectToSBValue(void *data); - extern lldb::ValueObjectSP LLDBSWIGPython_GetValueObjectSPFromSBValue(void *data); @@ -234,8 +236,7 @@ namespace { // save off initial state at the beginning, and restore it at the end struct InitializePythonRAII { public: - InitializePythonRAII() - : m_gil_state(PyGILState_UNLOCKED), m_was_already_initialized(false) { + InitializePythonRAII() { InitializePythonHome(); #ifdef LLDB_USE_LIBEDIT_READLINE_COMPAT_MODULE @@ -355,8 +356,8 @@ private: } TerminalState m_stdin_tty_state; - PyGILState_STATE m_gil_state; - bool m_was_already_initialized; + PyGILState_STATE m_gil_state = PyGILState_UNLOCKED; + bool m_was_already_initialized = false; }; } // namespace @@ -410,6 +411,32 @@ FileSpec ScriptInterpreterPython::GetPythonDir() { return g_spec; } +void ScriptInterpreterPython::SharedLibraryDirectoryHelper( + FileSpec &this_file) { + // When we're loaded from python, this_file will point to the file inside the + // python package directory. Replace it with the one in the lib directory. +#ifdef _WIN32 + // On windows, we need to manually back out of the python tree, and go into + // the bin directory. This is pretty much the inverse of what ComputePythonDir + // does. + if (this_file.GetFileNameExtension() == ConstString(".pyd")) { + this_file.RemoveLastPathComponent(); // _lldb.pyd or _lldb_d.pyd + this_file.RemoveLastPathComponent(); // lldb + llvm::StringRef libdir = LLDB_PYTHON_RELATIVE_LIBDIR; + for (auto it = llvm::sys::path::begin(libdir), + end = llvm::sys::path::end(libdir); + it != end; ++it) + this_file.RemoveLastPathComponent(); + this_file.AppendPathComponent("bin"); + this_file.AppendPathComponent("liblldb.dll"); + } +#else + // The python file is a symlink, so we can find the real library by resolving + // it. We can do this unconditionally. + FileSystem::Instance().ResolveSymbolicLink(this_file, this_file); +#endif +} + lldb_private::ConstString ScriptInterpreterPython::GetPluginNameStatic() { static ConstString g_name("script-python"); return g_name; @@ -506,6 +533,9 @@ ScriptInterpreterPythonImpl::ScriptInterpreterPythonImpl(Debugger &debugger) m_command_thread_state(nullptr) { InitializePrivate(); + m_scripted_process_interface_up = + std::make_unique<ScriptedProcessPythonInterface>(*this); + m_dictionary_name.append("_dict"); StreamString run_string; run_string.Printf("%s = dict()", m_dictionary_name.c_str()); @@ -605,11 +635,10 @@ void ScriptInterpreterPythonImpl::IOHandlerInputComplete(IOHandler &io_handler, case eIOHandlerNone: break; case eIOHandlerBreakpoint: { - std::vector<BreakpointOptions *> *bp_options_vec = - (std::vector<BreakpointOptions *> *)io_handler.GetUserData(); - for (auto bp_options : *bp_options_vec) { - if (!bp_options) - continue; + std::vector<std::reference_wrapper<BreakpointOptions>> *bp_options_vec = + (std::vector<std::reference_wrapper<BreakpointOptions>> *) + io_handler.GetUserData(); + for (BreakpointOptions &bp_options : *bp_options_vec) { auto data_up = std::make_unique<CommandDataPython>(); if (!data_up) @@ -623,7 +652,7 @@ void ScriptInterpreterPythonImpl::IOHandlerInputComplete(IOHandler &io_handler, .Success()) { auto baton_sp = std::make_shared<BreakpointOptions::CommandBaton>( std::move(data_up)); - bp_options->SetCallback( + bp_options.SetCallback( ScriptInterpreterPythonImpl::BreakpointCallbackFunction, baton_sp); } else if (!batch_mode) { StreamFileSP error_sp = io_handler.GetErrorStreamFileSP(); @@ -1048,11 +1077,24 @@ bool ScriptInterpreterPythonImpl::ExecuteOneLineWithReturn( llvm::StringRef in_string, ScriptInterpreter::ScriptReturnType return_type, void *ret_value, const ExecuteScriptOptions &options) { + llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>> + io_redirect_or_error = ScriptInterpreterIORedirect::Create( + options.GetEnableIO(), m_debugger, /*result=*/nullptr); + + if (!io_redirect_or_error) { + llvm::consumeError(io_redirect_or_error.takeError()); + return false; + } + + ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error; + Locker locker(this, Locker::AcquireLock | Locker::InitSession | (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) | Locker::NoSTDIN, - Locker::FreeAcquiredLock | Locker::TearDownSession); + Locker::FreeAcquiredLock | Locker::TearDownSession, + io_redirect.GetInputFile(), io_redirect.GetOutputFile(), + io_redirect.GetErrorFile()); PythonModule &main_module = GetMainModule(); PythonDictionary globals = main_module.GetDictionary(); @@ -1161,11 +1203,22 @@ Status ScriptInterpreterPythonImpl::ExecuteMultipleLines( if (in_string == nullptr) return Status(); + llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>> + io_redirect_or_error = ScriptInterpreterIORedirect::Create( + options.GetEnableIO(), m_debugger, /*result=*/nullptr); + + if (!io_redirect_or_error) + return Status(io_redirect_or_error.takeError()); + + ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error; + Locker locker(this, Locker::AcquireLock | Locker::InitSession | (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) | Locker::NoSTDIN, - Locker::FreeAcquiredLock | Locker::TearDownSession); + Locker::FreeAcquiredLock | Locker::TearDownSession, + io_redirect.GetInputFile(), io_redirect.GetOutputFile(), + io_redirect.GetErrorFile()); PythonModule &main_module = GetMainModule(); PythonDictionary globals = main_module.GetDictionary(); @@ -1196,7 +1249,7 @@ Status ScriptInterpreterPythonImpl::ExecuteMultipleLines( } void ScriptInterpreterPythonImpl::CollectDataForBreakpointCommandCallback( - std::vector<BreakpointOptions *> &bp_options_vec, + std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec, CommandReturnObject &result) { m_active_io_handler = eIOHandlerBreakpoint; m_debugger.GetCommandInterpreter().GetPythonCommandsFromIOHandler( @@ -1211,7 +1264,7 @@ void ScriptInterpreterPythonImpl::CollectDataForWatchpointCommandCallback( } Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallbackFunction( - BreakpointOptions *bp_options, const char *function_name, + BreakpointOptions &bp_options, const char *function_name, StructuredData::ObjectSP extra_args_sp) { Status error; // For now just cons up a oneliner that calls the provided function. @@ -1253,7 +1306,7 @@ Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallbackFunction( } Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback( - BreakpointOptions *bp_options, + BreakpointOptions &bp_options, std::unique_ptr<BreakpointOptions::CommandData> &cmd_data_up) { Status error; error = GenerateBreakpointCommandCallbackData(cmd_data_up->user_source, @@ -1264,21 +1317,20 @@ Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback( } auto baton_sp = std::make_shared<BreakpointOptions::CommandBaton>(std::move(cmd_data_up)); - bp_options->SetCallback( + bp_options.SetCallback( ScriptInterpreterPythonImpl::BreakpointCallbackFunction, baton_sp); return error; } Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback( - BreakpointOptions *bp_options, const char *command_body_text) { + BreakpointOptions &bp_options, const char *command_body_text) { return SetBreakpointCommandCallback(bp_options, command_body_text, {},false); } // Set a Python one-liner as the callback for the breakpoint. Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback( - BreakpointOptions *bp_options, const char *command_body_text, - StructuredData::ObjectSP extra_args_sp, - bool uses_extra_args) { + BreakpointOptions &bp_options, const char *command_body_text, + StructuredData::ObjectSP extra_args_sp, bool uses_extra_args) { auto data_up = std::make_unique<CommandDataPython>(extra_args_sp); // Split the command_body_text into lines, and pass that to // GenerateBreakpointCommandCallbackData. That will wrap the body in an @@ -1292,7 +1344,7 @@ Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback( if (error.Success()) { auto baton_sp = std::make_shared<BreakpointOptions::CommandBaton>(std::move(data_up)); - bp_options->SetCallback( + bp_options.SetCallback( ScriptInterpreterPythonImpl::BreakpointCallbackFunction, baton_sp); return error; } @@ -1330,7 +1382,7 @@ Status ScriptInterpreterPythonImpl::ExportFunctionDefinitionToInterpreter( Status error = ExecuteMultipleLines( function_def_string.c_str(), - ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false)); + ExecuteScriptOptions().SetEnableIO(false)); return error; } @@ -1678,35 +1730,6 @@ StructuredData::ArraySP ScriptInterpreterPythonImpl::OSPlugin_ThreadsInfo( return StructuredData::ArraySP(); } -// GetPythonValueFormatString provides a system independent type safe way to -// convert a variable's type into a python value format. Python value formats -// are defined in terms of builtin C types and could change from system to as -// the underlying typedef for uint* types, size_t, off_t and other values -// change. - -template <typename T> const char *GetPythonValueFormatString(T t); -template <> const char *GetPythonValueFormatString(char *) { return "s"; } -template <> const char *GetPythonValueFormatString(char) { return "b"; } -template <> const char *GetPythonValueFormatString(unsigned char) { - return "B"; -} -template <> const char *GetPythonValueFormatString(short) { return "h"; } -template <> const char *GetPythonValueFormatString(unsigned short) { - return "H"; -} -template <> const char *GetPythonValueFormatString(int) { return "i"; } -template <> const char *GetPythonValueFormatString(unsigned int) { return "I"; } -template <> const char *GetPythonValueFormatString(long) { return "l"; } -template <> const char *GetPythonValueFormatString(unsigned long) { - return "k"; -} -template <> const char *GetPythonValueFormatString(long long) { return "L"; } -template <> const char *GetPythonValueFormatString(unsigned long long) { - return "K"; -} -template <> const char *GetPythonValueFormatString(float t) { return "f"; } -template <> const char *GetPythonValueFormatString(double t) { return "d"; } - StructuredData::StringSP ScriptInterpreterPythonImpl::OSPlugin_RegisterContextData( StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid) { @@ -2058,7 +2081,10 @@ ScriptInterpreterPythonImpl::LoadPluginModule(const FileSpec &file_spec, StructuredData::ObjectSP module_sp; - if (LoadScriptingModule(file_spec.GetPath().c_str(), true, error, &module_sp)) + LoadScriptOptions load_script_options = + LoadScriptOptions().SetInitSession(true).SetSilent(false); + if (LoadScriptingModule(file_spec.GetPath().c_str(), load_script_options, + error, &module_sp)) return module_sp; return StructuredData::ObjectSP(); @@ -2733,26 +2759,44 @@ uint64_t replace_all(std::string &str, const std::string &oldStr, } bool ScriptInterpreterPythonImpl::LoadScriptingModule( - const char *pathname, bool init_session, lldb_private::Status &error, - StructuredData::ObjectSP *module_sp, FileSpec extra_search_dir) { + const char *pathname, const LoadScriptOptions &options, + lldb_private::Status &error, StructuredData::ObjectSP *module_sp, + FileSpec extra_search_dir) { namespace fs = llvm::sys::fs; namespace path = llvm::sys::path; + ExecuteScriptOptions exc_options = ExecuteScriptOptions() + .SetEnableIO(!options.GetSilent()) + .SetSetLLDBGlobals(false); + if (!pathname || !pathname[0]) { error.SetErrorString("invalid pathname"); return false; } + llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>> + io_redirect_or_error = ScriptInterpreterIORedirect::Create( + exc_options.GetEnableIO(), m_debugger, /*result=*/nullptr); + + if (!io_redirect_or_error) { + error = io_redirect_or_error.takeError(); + return false; + } + + ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error; lldb::DebuggerSP debugger_sp = m_debugger.shared_from_this(); // Before executing Python code, lock the GIL. Locker py_lock(this, Locker::AcquireLock | - (init_session ? Locker::InitSession : 0) | Locker::NoSTDIN, + (options.GetInitSession() ? Locker::InitSession : 0) | + Locker::NoSTDIN, Locker::FreeAcquiredLock | - (init_session ? Locker::TearDownSession : 0)); + (options.GetInitSession() ? Locker::TearDownSession : 0), + io_redirect.GetInputFile(), io_redirect.GetOutputFile(), + io_redirect.GetErrorFile()); - auto ExtendSysPath = [this](std::string directory) -> llvm::Error { + auto ExtendSysPath = [&](std::string directory) -> llvm::Error { if (directory.empty()) { return llvm::make_error<llvm::StringError>( "invalid directory name", llvm::inconvertibleErrorCode()); @@ -2767,11 +2811,7 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule( "sys.path.insert(1,'%s');\n\n", directory.c_str(), directory.c_str()); bool syspath_retval = - ExecuteMultipleLines(command_stream.GetData(), - ScriptInterpreter::ExecuteScriptOptions() - .SetEnableIO(false) - .SetSetLLDBGlobals(false)) - .Success(); + ExecuteMultipleLines(command_stream.GetData(), exc_options).Success(); if (!syspath_retval) { return llvm::make_error<llvm::StringError>( "Python sys.path handling failed", llvm::inconvertibleErrorCode()); @@ -2781,6 +2821,7 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule( }; std::string module_name(pathname); + bool possible_package = false; if (extra_search_dir) { if (llvm::Error e = ExtendSysPath(extra_search_dir.GetPath())) { @@ -2805,6 +2846,7 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule( return false; } // Not a filename, probably a package of some sort, let it go through. + possible_package = true; } else if (is_directory(st) || is_regular_file(st)) { if (module_file.GetDirectory().IsEmpty()) { error.SetErrorString("invalid directory name"); @@ -2831,35 +2873,39 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule( module_name.resize(module_name.length() - 4); } - // check if the module is already import-ed + if (!possible_package && module_name.find('.') != llvm::StringRef::npos) { + error.SetErrorStringWithFormat( + "Python does not allow dots in module names: %s", module_name.c_str()); + return false; + } + + if (module_name.find('-') != llvm::StringRef::npos) { + error.SetErrorStringWithFormat( + "Python discourages dashes in module names: %s", module_name.c_str()); + return false; + } + + // Check if the module is already imported. StreamString command_stream; command_stream.Clear(); command_stream.Printf("sys.modules.__contains__('%s')", module_name.c_str()); bool does_contain = false; - // this call will succeed if the module was ever imported in any Debugger - // in the lifetime of the process in which this LLDB framework is living - bool was_imported_globally = - (ExecuteOneLineWithReturn( - command_stream.GetData(), - ScriptInterpreterPythonImpl::eScriptReturnTypeBool, &does_contain, - ScriptInterpreter::ExecuteScriptOptions() - .SetEnableIO(false) - .SetSetLLDBGlobals(false)) && - does_contain); - // this call will fail if the module was not imported in this Debugger - // before - command_stream.Clear(); - command_stream.Printf("sys.getrefcount(%s)", module_name.c_str()); - bool was_imported_locally = GetSessionDictionary() - .GetItemForKey(PythonString(module_name)) - .IsAllocated(); - - bool was_imported = (was_imported_globally || was_imported_locally); + // This call will succeed if the module was ever imported in any Debugger in + // the lifetime of the process in which this LLDB framework is living. + const bool does_contain_executed = ExecuteOneLineWithReturn( + command_stream.GetData(), + ScriptInterpreterPythonImpl::eScriptReturnTypeBool, &does_contain, exc_options); + + const bool was_imported_globally = does_contain_executed && does_contain; + const bool was_imported_locally = + GetSessionDictionary() + .GetItemForKey(PythonString(module_name)) + .IsAllocated(); // now actually do the import command_stream.Clear(); - if (was_imported) { + if (was_imported_globally || was_imported_locally) { if (!was_imported_locally) command_stream.Printf("import %s ; reload_module(%s)", module_name.c_str(), module_name.c_str()); @@ -2868,10 +2914,7 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule( } else command_stream.Printf("import %s", module_name.c_str()); - error = ExecuteMultipleLines(command_stream.GetData(), - ScriptInterpreter::ExecuteScriptOptions() - .SetEnableIO(false) - .SetSetLLDBGlobals(false)); + error = ExecuteMultipleLines(command_stream.GetData(), exc_options); if (error.Fail()) return false; @@ -2890,7 +2933,8 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule( void *module_pyobj = nullptr; if (ExecuteOneLineWithReturn( command_stream.GetData(), - ScriptInterpreter::eScriptReturnTypeOpaqueObject, &module_pyobj) && + ScriptInterpreter::eScriptReturnTypeOpaqueObject, &module_pyobj, + exc_options) && module_pyobj) *module_sp = std::make_shared<StructuredPythonObject>(module_pyobj); } @@ -3047,7 +3091,7 @@ bool ScriptInterpreterPythonImpl::GetDocumentationForItem(const char *item, if (ExecuteOneLineWithReturn( command, ScriptInterpreter::eScriptReturnTypeCharStrOrNone, &result_ptr, - ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false))) { + ExecuteScriptOptions().SetEnableIO(false))) { if (result_ptr) dest.assign(result_ptr); return true; diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h index e59fedbd0971..b8b978118218 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h @@ -13,6 +13,8 @@ #if LLDB_ENABLE_PYTHON +#include "ScriptedProcessPythonInterface.h" + #include "lldb/Breakpoint/BreakpointOptions.h" #include "lldb/Core/IOHandler.h" #include "lldb/Core/StructuredDataImpl.h" @@ -51,6 +53,7 @@ public: static lldb_private::ConstString GetPluginNameStatic(); static const char *GetPluginDescriptionStatic(); static FileSpec GetPythonDir(); + static void SharedLibraryDirectoryHelper(FileSpec &this_file); protected: static void ComputePythonDirForApple(llvm::SmallVectorImpl<char> &path); diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h index 45dad4217005..d1b0b3fda1ef 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h @@ -6,6 +6,9 @@ // //===----------------------------------------------------------------------===// +#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H +#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H + #include "lldb/Host/Config.h" #if LLDB_ENABLE_PYTHON @@ -231,7 +234,8 @@ public: bool RunScriptFormatKeyword(const char *impl_function, ValueObject *value, std::string &output, Status &error) override; - bool LoadScriptingModule(const char *filename, bool init_session, + bool LoadScriptingModule(const char *filename, + const LoadScriptOptions &options, lldb_private::Status &error, StructuredData::ObjectSP *module_sp = nullptr, FileSpec extra_search_dir = {}) override; @@ -241,7 +245,7 @@ public: std::unique_ptr<ScriptInterpreterLocker> AcquireInterpreterLock() override; void CollectDataForBreakpointCommandCallback( - std::vector<BreakpointOptions *> &bp_options_vec, + std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec, CommandReturnObject &result) override; void @@ -249,20 +253,19 @@ public: CommandReturnObject &result) override; /// Set the callback body text into the callback for the breakpoint. - Status SetBreakpointCommandCallback(BreakpointOptions *bp_options, + Status SetBreakpointCommandCallback(BreakpointOptions &bp_options, const char *callback_body) override; Status SetBreakpointCommandCallbackFunction( - BreakpointOptions *bp_options, - const char *function_name, + BreakpointOptions &bp_options, const char *function_name, StructuredData::ObjectSP extra_args_sp) override; /// This one is for deserialization: Status SetBreakpointCommandCallback( - BreakpointOptions *bp_options, + BreakpointOptions &bp_options, std::unique_ptr<BreakpointOptions::CommandData> &data_up) override; - Status SetBreakpointCommandCallback(BreakpointOptions *bp_options, + Status SetBreakpointCommandCallback(BreakpointOptions &bp_options, const char *command_body_text, StructuredData::ObjectSP extra_args_sp, bool uses_extra_args); @@ -416,7 +419,7 @@ public: : IOHandler(debugger, IOHandler::Type::PythonInterpreter), m_python(python) {} - ~IOHandlerPythonInterpreter() override {} + ~IOHandlerPythonInterpreter() override = default; ConstString GetControlSequence(char ch) override { if (ch == 'd') @@ -483,4 +486,5 @@ protected: } // namespace lldb_private -#endif +#endif // LLDB_ENABLE_PYTHON +#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp new file mode 100644 index 000000000000..ce262c930f8b --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp @@ -0,0 +1,306 @@ +//===-- ScriptedProcessPythonInterface.cpp --------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "lldb/Host/Config.h" +#include "lldb/lldb-enumerations.h" + +#if LLDB_ENABLE_PYTHON + +// LLDB Python header must be included first +#include "lldb-python.h" + +#include "SWIGPythonBridge.h" +#include "ScriptInterpreterPythonImpl.h" +#include "ScriptedProcessPythonInterface.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::python; +using Locker = ScriptInterpreterPythonImpl::Locker; + +StructuredData::GenericSP ScriptedProcessPythonInterface::CreatePluginObject( + const llvm::StringRef class_name, lldb::TargetSP target_sp, + StructuredData::DictionarySP args_sp) { + if (class_name.empty()) + return {}; + + std::string error_string; + StructuredDataImpl *args_impl = nullptr; + if (args_sp) { + args_impl = new StructuredDataImpl(); + args_impl->SetObjectSP(args_sp); + } + + void *ret_val; + + { + + Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, + Locker::FreeLock); + + ret_val = LLDBSwigPythonCreateScriptedProcess( + class_name.str().c_str(), m_interpreter.GetDictionaryName(), target_sp, + args_impl, error_string); + } + + m_object_instance_sp = + StructuredData::GenericSP(new StructuredPythonObject(ret_val)); + + return m_object_instance_sp; +} + +Status ScriptedProcessPythonInterface::Launch() { + return GetStatusFromMethod("launch"); +} + +Status ScriptedProcessPythonInterface::Resume() { + return GetStatusFromMethod("resume"); +} + +bool ScriptedProcessPythonInterface::ShouldStop() { + llvm::Optional<unsigned long long> should_stop = + GetGenericInteger("should_stop"); + + if (!should_stop) + return false; + + return static_cast<bool>(*should_stop); +} + +Status ScriptedProcessPythonInterface::Stop() { + return GetStatusFromMethod("stop"); +} + +Status ScriptedProcessPythonInterface::GetStatusFromMethod( + llvm::StringRef method_name) { + Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, + Locker::FreeLock); + + if (!m_object_instance_sp) + return Status("Python object ill-formed."); + + if (!m_object_instance_sp) + return Status("Cannot convert Python object to StructuredData::Generic."); + PythonObject implementor(PyRefType::Borrowed, + (PyObject *)m_object_instance_sp->GetValue()); + + if (!implementor.IsAllocated()) + return Status("Python implementor not allocated."); + + PythonObject pmeth( + PyRefType::Owned, + PyObject_GetAttrString(implementor.get(), method_name.str().c_str())); + + if (PyErr_Occurred()) + PyErr_Clear(); + + if (!pmeth.IsAllocated()) + return Status("Python method not allocated."); + + if (PyCallable_Check(pmeth.get()) == 0) { + if (PyErr_Occurred()) + PyErr_Clear(); + return Status("Python method not callable."); + } + + if (PyErr_Occurred()) + PyErr_Clear(); + + PythonObject py_return(PyRefType::Owned, + PyObject_CallMethod(implementor.get(), + method_name.str().c_str(), + nullptr)); + + if (PyErr_Occurred()) { + PyErr_Print(); + PyErr_Clear(); + return Status("Python method could not be called."); + } + + if (PyObject *py_ret_ptr = py_return.get()) { + lldb::SBError *sb_error = + (lldb::SBError *)LLDBSWIGPython_CastPyObjectToSBError(py_ret_ptr); + + if (!sb_error) + return Status("Couldn't cast lldb::SBError to lldb::Status."); + + Status status = m_interpreter.GetStatusFromSBError(*sb_error); + + if (status.Fail()) + return Status("error: %s", status.AsCString()); + + return status; + } + + return Status("Returned object is null."); +} + +llvm::Optional<unsigned long long> +ScriptedProcessPythonInterface::GetGenericInteger(llvm::StringRef method_name) { + Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, + Locker::FreeLock); + + if (!m_object_instance_sp) + return llvm::None; + + if (!m_object_instance_sp) + return llvm::None; + PythonObject implementor(PyRefType::Borrowed, + (PyObject *)m_object_instance_sp->GetValue()); + + if (!implementor.IsAllocated()) + return llvm::None; + + PythonObject pmeth( + PyRefType::Owned, + PyObject_GetAttrString(implementor.get(), method_name.str().c_str())); + + if (PyErr_Occurred()) + PyErr_Clear(); + + if (!pmeth.IsAllocated()) + return llvm::None; + + if (PyCallable_Check(pmeth.get()) == 0) { + if (PyErr_Occurred()) + PyErr_Clear(); + return llvm::None; + } + + if (PyErr_Occurred()) + PyErr_Clear(); + + PythonObject py_return(PyRefType::Owned, + PyObject_CallMethod(implementor.get(), + method_name.str().c_str(), + nullptr)); + + if (PyErr_Occurred()) { + PyErr_Print(); + PyErr_Clear(); + } + + if (!py_return.get()) + return llvm::None; + + llvm::Expected<unsigned long long> size = py_return.AsUnsignedLongLong(); + // FIXME: Handle error. + if (!size) + return llvm::None; + + return *size; +} + +lldb::MemoryRegionInfoSP +ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress( + lldb::addr_t address) { + // TODO: Implement + return nullptr; +} + +StructuredData::DictionarySP +ScriptedProcessPythonInterface::GetThreadWithID(lldb::tid_t tid) { + // TODO: Implement + return nullptr; +} + +StructuredData::DictionarySP +ScriptedProcessPythonInterface::GetRegistersForThread(lldb::tid_t tid) { + // TODO: Implement + return nullptr; +} + +lldb::DataExtractorSP ScriptedProcessPythonInterface::ReadMemoryAtAddress( + lldb::addr_t address, size_t size, Status &error) { + Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, + Locker::FreeLock); + + auto error_with_message = [&error](llvm::StringRef message) { + error.SetErrorString(message); + return nullptr; + }; + + static char callee_name[] = "read_memory_at_address"; + std::string param_format = GetPythonValueFormatString(address); + param_format += GetPythonValueFormatString(size); + + if (!m_object_instance_sp) + return error_with_message("Python object ill-formed."); + + if (!m_object_instance_sp) + return error_with_message("Python method not callable."); + + PythonObject implementor(PyRefType::Borrowed, + (PyObject *)m_object_instance_sp->GetValue()); + + if (!implementor.IsAllocated()) + return error_with_message("Python implementor not allocated."); + + PythonObject pmeth(PyRefType::Owned, + PyObject_GetAttrString(implementor.get(), callee_name)); + + if (PyErr_Occurred()) + PyErr_Clear(); + + if (!pmeth.IsAllocated()) + return error_with_message("Python method not allocated."); + + if (PyCallable_Check(pmeth.get()) == 0) { + if (PyErr_Occurred()) + PyErr_Clear(); + return error_with_message("Python method not callable."); + } + + if (PyErr_Occurred()) + PyErr_Clear(); + + PythonObject py_return(PyRefType::Owned, + PyObject_CallMethod(implementor.get(), callee_name, + param_format.c_str(), address, + size)); + + if (PyErr_Occurred()) { + PyErr_Print(); + PyErr_Clear(); + return error_with_message("Python method could not be called."); + } + + if (PyObject *py_ret_ptr = py_return.get()) { + lldb::SBData *sb_data = + (lldb::SBData *)LLDBSWIGPython_CastPyObjectToSBData(py_ret_ptr); + + if (!sb_data) + return error_with_message( + "Couldn't cast lldb::SBData to lldb::DataExtractor."); + + return m_interpreter.GetDataExtractorFromSBData(*sb_data); + } + + return error_with_message("Returned object is null."); +} + +StructuredData::DictionarySP ScriptedProcessPythonInterface::GetLoadedImages() { + // TODO: Implement + return nullptr; +} + +lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() { + llvm::Optional<unsigned long long> pid = GetGenericInteger("get_process_id"); + return (!pid) ? LLDB_INVALID_PROCESS_ID : *pid; +} + +bool ScriptedProcessPythonInterface::IsAlive() { + llvm::Optional<unsigned long long> is_alive = GetGenericInteger("is_alive"); + + if (!is_alive) + return false; + + return static_cast<bool>(*is_alive); +} + +#endif diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h new file mode 100644 index 000000000000..30cb5a882af2 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h @@ -0,0 +1,66 @@ +//===-- ScriptedProcessPythonInterface.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_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPROCESSPYTHONINTERFACE_H +#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPROCESSPYTHONINTERFACE_H + +#include "lldb/Host/Config.h" + +#if LLDB_ENABLE_PYTHON + +#include "lldb/Interpreter/ScriptedProcessInterface.h" + +namespace lldb_private { +class ScriptInterpreterPythonImpl; +class ScriptedProcessPythonInterface : public ScriptedProcessInterface { +public: + ScriptedProcessPythonInterface(ScriptInterpreterPythonImpl &interpreter) + : ScriptedProcessInterface(), m_interpreter(interpreter) {} + + StructuredData::GenericSP + CreatePluginObject(const llvm::StringRef class_name, lldb::TargetSP target_sp, + StructuredData::DictionarySP args_sp) override; + + Status Launch() override; + + Status Resume() override; + + bool ShouldStop() override; + + Status Stop() override; + + lldb::MemoryRegionInfoSP + GetMemoryRegionContainingAddress(lldb::addr_t address) override; + + StructuredData::DictionarySP GetThreadWithID(lldb::tid_t tid) override; + + StructuredData::DictionarySP GetRegistersForThread(lldb::tid_t tid) override; + + lldb::DataExtractorSP ReadMemoryAtAddress(lldb::addr_t address, size_t size, + Status &error) override; + + StructuredData::DictionarySP GetLoadedImages() override; + + lldb::pid_t GetProcessID() override; + + bool IsAlive() override; + +protected: + llvm::Optional<unsigned long long> + GetGenericInteger(llvm::StringRef method_name); + Status GetStatusFromMethod(llvm::StringRef method_name); + +private: + // The lifetime is managed by the ScriptInterpreter + ScriptInterpreterPythonImpl &m_interpreter; + StructuredData::GenericSP m_object_instance_sp; +}; +} // namespace lldb_private + +#endif // LLDB_ENABLE_PYTHON +#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPROCESSPYTHONINTERFACE_H diff --git a/contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp b/contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp index f669e5873d2d..87edf7789f0d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp @@ -8,7 +8,7 @@ #include "StructuredDataDarwinLog.h" -#include <string.h> +#include <cstring> #include <memory> #include <sstream> @@ -126,7 +126,7 @@ public: m_collection_sp->Initialize(g_darwinlog_properties); } - ~StructuredDataDarwinLogProperties() override {} + ~StructuredDataDarwinLogProperties() override = default; bool GetEnableOnStartup() const { const uint32_t idx = ePropertyEnableOnStartup; @@ -181,7 +181,7 @@ using FilterRuleSP = std::shared_ptr<FilterRule>; class FilterRule { public: - virtual ~FilterRule() {} + virtual ~FilterRule() = default; using OperationCreationFunc = std::function<FilterRuleSP(bool accept, size_t attribute_index, @@ -473,13 +473,9 @@ static constexpr OptionDefinition g_enable_option_table[] = { class EnableOptions : public Options { public: EnableOptions() - : Options(), m_include_debug_level(false), m_include_info_level(false), - m_include_any_process(false), + : Options(), m_filter_fall_through_accepts(DEFAULT_FILTER_FALLTHROUGH_ACCEPTS), - m_echo_to_stderr(false), m_display_timestamp_relative(false), - m_display_subsystem(false), m_display_category(false), - m_display_activity_chain(false), m_broadcast_events(true), - m_live_stream(true), m_filter_rules() {} + m_filter_rules() {} void OptionParsingStarting(ExecutionContext *execution_context) override { m_include_debug_level = false; @@ -728,17 +724,17 @@ private: return -1; } - bool m_include_debug_level; - bool m_include_info_level; - bool m_include_any_process; + bool m_include_debug_level = false; + bool m_include_info_level = false; + bool m_include_any_process = false; bool m_filter_fall_through_accepts; - bool m_echo_to_stderr; - bool m_display_timestamp_relative; - bool m_display_subsystem; - bool m_display_category; - bool m_display_activity_chain; - bool m_broadcast_events; - bool m_live_stream; + bool m_echo_to_stderr = false; + bool m_display_timestamp_relative = false; + bool m_display_subsystem = false; + bool m_display_category = false; + bool m_display_activity_chain = false; + bool m_broadcast_events = true; + bool m_live_stream = true; FilterRules m_filter_rules; }; @@ -813,7 +809,6 @@ protected: StructuredDataDarwinLog::GetStaticPluginName())) { result.AppendError("failed to get StructuredDataPlugin for " "the process"); - result.SetStatus(eReturnStatusFailed); } StructuredDataDarwinLog &plugin = *static_cast<StructuredDataDarwinLog *>(plugin_sp.get()); @@ -837,7 +832,6 @@ protected: // Report results. if (!error.Success()) { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); // Our configuration failed, so we're definitely disabled. plugin.SetEnabled(false); } else { diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp index 07e5b284eab8..b815ebb3c07a 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp @@ -278,7 +278,7 @@ SymbolFileBreakpad::ResolveSymbolContext(const Address &so_addr, } uint32_t SymbolFileBreakpad::ResolveSymbolContext( - const FileSpec &file_spec, uint32_t line, bool check_inlines, + const SourceLocationSpec &src_location_spec, lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); if (!(resolve_scope & eSymbolContextCompUnit)) @@ -287,8 +287,7 @@ uint32_t SymbolFileBreakpad::ResolveSymbolContext( uint32_t old_size = sc_list.GetSize(); for (size_t i = 0, size = GetNumCompileUnits(); i < size; ++i) { CompileUnit &cu = *GetCompileUnitAtIndex(i); - cu.ResolveSymbolContext(file_spec, line, check_inlines, - /*exact*/ false, resolve_scope, sc_list); + cu.ResolveSymbolContext(src_location_spec, resolve_scope, sc_list); } return sc_list.GetSize() - old_size; } @@ -716,10 +715,10 @@ void SymbolFileBreakpad::ParseLineTableAndSupportFiles(CompileUnit &cu, llvm::Optional<addr_t> next_addr; auto finish_sequence = [&]() { LineTable::AppendLineEntryToSequence( - line_seq_up.get(), *next_addr, /*line*/ 0, /*column*/ 0, - /*file_idx*/ 0, /*is_start_of_statement*/ false, - /*is_start_of_basic_block*/ false, /*is_prologue_end*/ false, - /*is_epilogue_begin*/ false, /*is_terminal_entry*/ true); + line_seq_up.get(), *next_addr, /*line=*/0, /*column=*/0, + /*file_idx=*/0, /*is_start_of_statement=*/false, + /*is_start_of_basic_block=*/false, /*is_prologue_end=*/false, + /*is_epilogue_begin=*/false, /*is_terminal_entry=*/true); sequences.push_back(std::move(line_seq_up)); line_seq_up = LineTable::CreateLineSequenceContainer(); }; @@ -739,10 +738,10 @@ void SymbolFileBreakpad::ParseLineTableAndSupportFiles(CompileUnit &cu, finish_sequence(); } LineTable::AppendLineEntryToSequence( - line_seq_up.get(), record->Address, record->LineNum, /*column*/ 0, - map[record->FileNum], /*is_start_of_statement*/ true, - /*is_start_of_basic_block*/ false, /*is_prologue_end*/ false, - /*is_epilogue_begin*/ false, /*is_terminal_entry*/ false); + line_seq_up.get(), record->Address, record->LineNum, /*column=*/0, + map[record->FileNum], /*is_start_of_statement=*/true, + /*is_start_of_basic_block=*/false, /*is_prologue_end=*/false, + /*is_epilogue_begin=*/false, /*is_terminal_entry=*/false); next_addr = record->Address + record->Size; } if (next_addr) diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h index 90dbcc77627a..b0a35fa11de4 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h @@ -51,7 +51,7 @@ public: SymbolFileBreakpad(lldb::ObjectFileSP objfile_sp) : SymbolFile(std::move(objfile_sp)) {} - ~SymbolFileBreakpad() override {} + ~SymbolFileBreakpad() override = default; uint32_t CalculateAbilities() override; @@ -101,8 +101,7 @@ public: lldb::SymbolContextItem resolve_scope, SymbolContext &sc) override; - uint32_t ResolveSymbolContext(const FileSpec &file_spec, uint32_t line, - bool check_inlines, + uint32_t ResolveSymbolContext(const SourceLocationSpec &src_location_spec, lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) override; diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h index 2e0a7fd3ecd3..ffe24836955f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h @@ -24,7 +24,7 @@ class SymbolFileDWARF; class DWARFASTParser { public: - virtual ~DWARFASTParser() {} + virtual ~DWARFASTParser() = default; virtual lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, const DWARFDIE &die, diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 188a667ca564..46015f7b43b1 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include <stdlib.h> +#include <cstdlib> #include "DWARFASTParserClang.h" #include "DWARFDebugInfo.h" @@ -49,7 +49,7 @@ //#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN #ifdef ENABLE_DEBUG_PRINTF -#include <stdio.h> +#include <cstdio> #define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__) #else #define DEBUG_PRINTF(fmt, ...) @@ -60,7 +60,7 @@ using namespace lldb_private; DWARFASTParserClang::DWARFASTParserClang(TypeSystemClang &ast) : m_ast(ast), m_die_to_decl_ctx(), m_decl_ctx_to_die() {} -DWARFASTParserClang::~DWARFASTParserClang() {} +DWARFASTParserClang::~DWARFASTParserClang() = default; static AccessType DW_ACCESS_to_AccessType(uint32_t dwarf_accessibility) { switch (dwarf_accessibility) { @@ -157,7 +157,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc, // The type in the Clang module must have the same language as the current CU. LanguageSet languages; - languages.Insert(SymbolFileDWARF::GetLanguage(*die.GetCU())); + languages.Insert(SymbolFileDWARF::GetLanguageFamily(*die.GetCU())); llvm::DenseSet<SymbolFile *> searched_symbol_files; clang_module_sp->GetSymbolFile()->FindTypes(decl_context, languages, searched_symbol_files, pcm_types); @@ -666,8 +666,7 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc, // Blocks have a __FuncPtr inside them which is a pointer to a // function of the proper type. - for (DWARFDIE child_die = target_die.GetFirstChild(); - child_die.IsValid(); child_die = child_die.GetSibling()) { + for (DWARFDIE child_die : target_die.children()) { if (!strcmp(child_die.GetAttributeValueAsString(DW_AT_name, ""), "__FuncPtr")) { DWARFDIE function_pointer_type = @@ -1226,6 +1225,7 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, } if (!function_decl) { + char *name_buf = nullptr; llvm::StringRef name = attrs.name.GetStringRef(); // We currently generate function templates with template parameters in @@ -1233,8 +1233,10 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, // we want to strip these from the name when creating the AST. if (attrs.mangled_name) { llvm::ItaniumPartialDemangler D; - if (!D.partialDemangle(attrs.mangled_name)) - name = D.getFunctionBaseName(nullptr, nullptr); + if (!D.partialDemangle(attrs.mangled_name)) { + name_buf = D.getFunctionBaseName(nullptr, nullptr); + name = name_buf; + } } // We just have a function that isn't part of a class @@ -1243,6 +1245,7 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, : containing_decl_ctx, GetOwningClangModule(die), name, clang_type, attrs.storage, attrs.is_inline); + std::free(name_buf); if (has_template_params) { TypeSystemClang::TemplateParameterInfos template_param_infos; @@ -1266,13 +1269,10 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, LinkDeclContextToDIE(function_decl, die); if (!function_param_decls.empty()) { - m_ast.SetFunctionParameters(function_decl, - &function_param_decls.front(), - function_param_decls.size()); + m_ast.SetFunctionParameters(function_decl, function_param_decls); if (template_function_decl) m_ast.SetFunctionParameters(template_function_decl, - &function_param_decls.front(), - function_param_decls.size()); + function_param_decls); } ClangASTMetadata metadata; @@ -1357,7 +1357,7 @@ TypeSP DWARFASTParserClang::ParsePointerToMemberType( dwarf->ResolveTypeUID(attrs.containing_type.Reference(), true); CompilerType pointee_clang_type = pointee_type->GetForwardCompilerType(); - CompilerType class_clang_type = class_type->GetLayoutCompilerType(); + CompilerType class_clang_type = class_type->GetForwardCompilerType(); CompilerType clang_type = TypeSystemClang::CreateMemberPointerType( class_clang_type, pointee_clang_type); @@ -1684,14 +1684,18 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, die.GetOffset(), attrs.name.GetCString()); } - if (tag == DW_TAG_structure_type) // this only applies in C - { + // If the byte size of the record is specified then overwrite the size + // that would be computed by Clang. This is only needed as LLDB's + // TypeSystemClang is always in C++ mode, but some compilers such as + // GCC and Clang give empty structs a size of 0 in C mode (in contrast to + // the size of 1 for empty structs that would be computed in C++ mode). + if (attrs.byte_size) { clang::RecordDecl *record_decl = TypeSystemClang::GetAsRecordDecl(clang_type); - if (record_decl) { - GetClangASTImporter().SetRecordLayout( - record_decl, ClangASTImporter::LayoutInfo()); + ClangASTImporter::LayoutInfo layout; + layout.bit_size = *attrs.byte_size * 8; + GetClangASTImporter().SetRecordLayout(record_decl, layout); } } } else if (clang_type_was_created) { @@ -1822,8 +1826,7 @@ bool DWARFASTParserClang::ParseTemplateDIE( case DW_TAG_GNU_template_parameter_pack: { template_param_infos.packed_args = std::make_unique<TypeSystemClang::TemplateParameterInfos>(); - for (DWARFDIE child_die = die.GetFirstChild(); child_die.IsValid(); - child_die = child_die.GetSibling()) { + for (DWARFDIE child_die : die.children()) { if (!ParseTemplateDIE(child_die, *template_param_infos.packed_args)) return false; } @@ -1928,8 +1931,7 @@ bool DWARFASTParserClang::ParseTemplateParameterInfos( if (!parent_die) return false; - for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); - die = die.GetSibling()) { + for (DWARFDIE die : parent_die.children()) { const dw_tag_t tag = die.Tag(); switch (tag) { @@ -1978,15 +1980,12 @@ bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die, } std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases; - std::vector<int> member_accessibilities; - bool is_a_class = false; // Parse members and base classes first std::vector<DWARFDIE> member_function_dies; DelayedPropertyList delayed_properties; - ParseChildMembers(die, clang_type, bases, member_accessibilities, - member_function_dies, delayed_properties, - default_accessibility, is_a_class, layout_info); + ParseChildMembers(die, clang_type, bases, member_function_dies, + delayed_properties, default_accessibility, layout_info); // Now parse any methods if there were any... for (const DWARFDIE &die : member_function_dies) @@ -2007,31 +2006,6 @@ bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die, } } - // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we - // need to tell the clang type it is actually a class. - if (!type_is_objc_object_or_interface) { - if (is_a_class && tag_decl_kind != clang::TTK_Class) - m_ast.SetTagTypeKind(ClangUtil::GetQualType(clang_type), - clang::TTK_Class); - } - - // Since DW_TAG_structure_type gets used for both classes and - // structures, we may need to set any DW_TAG_member fields to have a - // "private" access if none was specified. When we parsed the child - // members we tracked that actual accessibility value for each - // DW_TAG_member in the "member_accessibilities" array. If the value - // for the member is zero, then it was set to the - // "default_accessibility" which for structs was "public". Below we - // correct this by setting any fields to "private" that weren't - // correctly set. - if (is_a_class && !member_accessibilities.empty()) { - // This is a class and all members that didn't have their access - // specified are private. - m_ast.SetDefaultAccessForRecordFields( - m_ast.GetAsRecordDecl(clang_type), eAccessPrivate, - &member_accessibilities.front(), member_accessibilities.size()); - } - if (!bases.empty()) { // Make sure all base classes refer to complete types and not forward // declarations. If we don't do this, clang will crash with an @@ -2131,8 +2105,7 @@ void DWARFASTParserClang::EnsureAllDIEsInDeclContextHaveBeenParsed( for (auto it = m_decl_ctx_to_die.find(opaque_decl_ctx); it != m_decl_ctx_to_die.end() && it->first == opaque_decl_ctx; it = m_decl_ctx_to_die.erase(it)) - for (DWARFDIE decl = it->second.GetFirstChild(); decl; - decl = decl.GetSibling()) + for (DWARFDIE decl : it->second.children()) GetClangDeclForDIE(decl); } @@ -2168,8 +2141,7 @@ size_t DWARFASTParserClang::ParseChildEnumerators( size_t enumerators_added = 0; - for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); - die = die.GetSibling()) { + for (DWARFDIE die : parent_die.children()) { const dw_tag_t tag = die.Tag(); if (tag == DW_TAG_enumerator) { DWARFAttributes attributes; @@ -2201,7 +2173,8 @@ size_t DWARFASTParserClang::ParseChildEnumerators( case DW_AT_description: default: case DW_AT_decl_file: - decl.SetFile(die.GetCU()->GetFile(form_value.Unsigned())); + decl.SetFile(attributes.CompileUnitAtIndex(i)->GetFile( + form_value.Unsigned())); break; case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); @@ -2343,7 +2316,6 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit, void DWARFASTParserClang::ParseSingleMember( const DWARFDIE &die, const DWARFDIE &parent_die, const lldb_private::CompilerType &class_clang_type, - std::vector<int> &member_accessibilities, lldb::AccessType default_accessibility, DelayedPropertyList &delayed_properties, lldb_private::ClangASTImporter::LayoutInfo &layout_info, @@ -2533,7 +2505,7 @@ void DWARFASTParserClang::ParseSingleMember( if (accessibility == eAccessNone) accessibility = eAccessPublic; TypeSystemClang::AddVariableToRecordType( - class_clang_type, name, var_type->GetLayoutCompilerType(), + class_clang_type, name, var_type->GetForwardCompilerType(), accessibility); } return; @@ -2551,7 +2523,6 @@ void DWARFASTParserClang::ParseSingleMember( if (accessibility == eAccessNone) accessibility = default_accessibility; - member_accessibilities.push_back(accessibility); uint64_t field_bit_offset = (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8)); @@ -2666,7 +2637,7 @@ void DWARFASTParserClang::ParseSingleMember( last_field_info.bit_offset = field_bit_offset; if (llvm::Optional<uint64_t> clang_type_size = - member_clang_type.GetByteSize(nullptr)) { + member_type->GetByteSize(nullptr)) { last_field_info.bit_size = *clang_type_size * character_width; } @@ -2761,10 +2732,9 @@ void DWARFASTParserClang::ParseSingleMember( bool DWARFASTParserClang::ParseChildMembers( const DWARFDIE &parent_die, CompilerType &class_clang_type, std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes, - std::vector<int> &member_accessibilities, std::vector<DWARFDIE> &member_function_dies, DelayedPropertyList &delayed_properties, AccessType &default_accessibility, - bool &is_a_class, ClangASTImporter::LayoutInfo &layout_info) { + ClangASTImporter::LayoutInfo &layout_info) { if (!parent_die) return false; @@ -2776,16 +2746,15 @@ bool DWARFASTParserClang::ParseChildMembers( if (ast == nullptr) return false; - for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); - die = die.GetSibling()) { + for (DWARFDIE die : parent_die.children()) { dw_tag_t tag = die.Tag(); switch (tag) { case DW_TAG_member: case DW_TAG_APPLE_property: ParseSingleMember(die, parent_die, class_clang_type, - member_accessibilities, default_accessibility, - delayed_properties, layout_info, last_field_info); + default_accessibility, delayed_properties, layout_info, + last_field_info); break; case DW_TAG_subprogram: @@ -2794,9 +2763,6 @@ bool DWARFASTParserClang::ParseChildMembers( break; case DW_TAG_inheritance: { - is_a_class = true; - if (default_accessibility == eAccessNone) - default_accessibility = eAccessPrivate; // TODO: implement DW_TAG_inheritance type parsing DWARFAttributes attributes; const size_t num_attributes = die.GetAttributes(attributes); @@ -2926,8 +2892,7 @@ size_t DWARFASTParserClang::ParseChildParameters( return 0; size_t arg_idx = 0; - for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); - die = die.GetSibling()) { + for (DWARFDIE die : parent_die.children()) { const dw_tag_t tag = die.Tag(); switch (tag) { case DW_TAG_formal_parameter: { @@ -3046,8 +3011,7 @@ DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die, if (!parent_die) return llvm::None; - for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); - die = die.GetSibling()) { + for (DWARFDIE die : parent_die.children()) { const dw_tag_t tag = die.Tag(); if (tag != DW_TAG_subrange_type) continue; @@ -3349,8 +3313,7 @@ static DWARFDIE GetContainingFunctionWithAbstractOrigin(const DWARFDIE &die) { } static DWARFDIE FindAnyChildWithAbstractOrigin(const DWARFDIE &context) { - for (DWARFDIE candidate = context.GetFirstChild(); candidate.IsValid(); - candidate = candidate.GetSibling()) { + for (DWARFDIE candidate : context.children()) { if (candidate.GetReferencedDIE(DW_AT_abstract_origin)) { return candidate; } @@ -3514,8 +3477,7 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes( UniqueCStringMap<DWARFDIE> dst_name_to_die; UniqueCStringMap<DWARFDIE> src_name_to_die_artificial; UniqueCStringMap<DWARFDIE> dst_name_to_die_artificial; - for (src_die = src_class_die.GetFirstChild(); src_die.IsValid(); - src_die = src_die.GetSibling()) { + for (DWARFDIE src_die : src_class_die.children()) { if (src_die.Tag() == DW_TAG_subprogram) { // Make sure this is a declaration and not a concrete instance by looking // for DW_AT_declaration set to 1. Sometimes concrete function instances @@ -3533,8 +3495,7 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes( } } } - for (dst_die = dst_class_die.GetFirstChild(); dst_die.IsValid(); - dst_die = dst_die.GetSibling()) { + for (DWARFDIE dst_die : dst_class_die.children()) { if (dst_die.Tag() == DW_TAG_subprogram) { // Make sure this is a declaration and not a concrete instance by looking // for DW_AT_declaration set to 1. Sometimes concrete function instances diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h index e13716b95c1c..9bf6240b7554 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h @@ -111,10 +111,9 @@ protected: bool ParseChildMembers( const DWARFDIE &die, lldb_private::CompilerType &class_compiler_type, std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes, - std::vector<int> &member_accessibilities, std::vector<DWARFDIE> &member_function_dies, DelayedPropertyList &delayed_properties, - lldb::AccessType &default_accessibility, bool &is_a_class, + lldb::AccessType &default_accessibility, lldb_private::ClangASTImporter::LayoutInfo &layout_info); size_t @@ -194,7 +193,6 @@ private: void ParseSingleMember(const DWARFDIE &die, const DWARFDIE &parent_die, const lldb_private::CompilerType &class_clang_type, - std::vector<int> &member_accessibilities, lldb::AccessType default_accessibility, DelayedPropertyList &delayed_properties, lldb_private::ClangASTImporter::LayoutInfo &layout_info, diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp index 0e9370be15fb..2f6b36c79b80 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp @@ -17,9 +17,7 @@ using namespace lldb_private; -DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() - : m_code(InvalidCode), m_tag(llvm::dwarf::DW_TAG_null), m_has_children(0), - m_attributes() {} +DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() : m_attributes() {} DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration(dw_tag_t tag, uint8_t has_children) @@ -58,7 +56,7 @@ DWARFAbbreviationDeclaration::extract(const DWARFDataExtractor &data, DWARFFormValue::ValueType val; if (form == DW_FORM_implicit_const) - val.value.sval = data.GetULEB128(offset_ptr); + val.value.sval = data.GetSLEB128(offset_ptr); m_attributes.push_back(DWARFAttribute(attr, form, val)); } @@ -82,9 +80,3 @@ DWARFAbbreviationDeclaration::FindAttributeIndex(dw_attr_t attr) const { } return DW_INVALID_INDEX; } - -bool DWARFAbbreviationDeclaration:: -operator==(const DWARFAbbreviationDeclaration &rhs) const { - return Tag() == rhs.Tag() && HasChildren() == rhs.HasChildren() && - m_attributes == rhs.m_attributes; -} diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h index f70aa71a5958..378ba888f4e0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h @@ -53,12 +53,11 @@ public: extract(const lldb_private::DWARFDataExtractor &data, lldb::offset_t *offset_ptr); bool IsValid(); - bool operator==(const DWARFAbbreviationDeclaration &rhs) const; protected: - dw_uleb128_t m_code; - dw_tag_t m_tag; - uint8_t m_has_children; + dw_uleb128_t m_code = InvalidCode; + dw_tag_t m_tag = llvm::dwarf::DW_TAG_null; + uint8_t m_has_children = 0; DWARFAttribute::collection m_attributes; }; diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp index ef98d7e33a90..134f6b2bd114 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp @@ -12,7 +12,7 @@ DWARFAttributes::DWARFAttributes() : m_infos() {} -DWARFAttributes::~DWARFAttributes() {} +DWARFAttributes::~DWARFAttributes() = default; uint32_t DWARFAttributes::FindAttributeIndex(dw_attr_t attr) const { collection::const_iterator end = m_infos.end(); @@ -25,10 +25,11 @@ uint32_t DWARFAttributes::FindAttributeIndex(dw_attr_t attr) const { return UINT32_MAX; } -void DWARFAttributes::Append(DWARFUnit *cu, dw_offset_t attr_die_offset, - dw_attr_t attr, dw_form_t form) { - AttributeValue attr_value = { - cu, attr_die_offset, {attr, form, DWARFFormValue::ValueType()}}; +void DWARFAttributes::Append(const DWARFFormValue &form_value, + dw_offset_t attr_die_offset, dw_attr_t attr) { + AttributeValue attr_value = {const_cast<DWARFUnit *>(form_value.GetUnit()), + attr_die_offset, + {attr, form_value.Form(), form_value.Value()}}; m_infos.push_back(attr_value); } @@ -37,6 +38,10 @@ bool DWARFAttributes::ExtractFormValueAtIndex( const DWARFUnit *cu = CompileUnitAtIndex(i); form_value.SetUnit(cu); form_value.SetForm(FormAtIndex(i)); + if (form_value.Form() == DW_FORM_implicit_const) { + form_value.SetValue(ValueAtIndex(i)); + return true; + } lldb::offset_t offset = DIEOffsetAtIndex(i); return form_value.ExtractValue(cu->GetData(), &offset); } diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h index 8c21404610d7..a31ee861179c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h @@ -22,21 +22,15 @@ public: DWARFFormValue::ValueType value) : m_attr(attr), m_form(form), m_value(value) {} - void set(dw_attr_t attr, dw_form_t form) { - m_attr = attr; - m_form = form; - } dw_attr_t get_attr() const { return m_attr; } dw_form_t get_form() const { return m_form; } + DWARFFormValue::ValueType get_value() const { return m_value; } void get(dw_attr_t &attr, dw_form_t &form, DWARFFormValue::ValueType &val) const { attr = m_attr; form = m_form; val = m_value; } - bool operator==(const DWARFAttribute &rhs) const { - return m_attr == rhs.m_attr && m_form == rhs.m_form; - } typedef std::vector<DWARFAttribute> collection; typedef collection::iterator iterator; typedef collection::const_iterator const_iterator; @@ -52,8 +46,8 @@ public: DWARFAttributes(); ~DWARFAttributes(); - void Append(DWARFUnit *cu, dw_offset_t attr_die_offset, dw_attr_t attr, - dw_form_t form); + void Append(const DWARFFormValue &form_value, dw_offset_t attr_die_offset, + dw_attr_t attr); DWARFUnit *CompileUnitAtIndex(uint32_t i) const { return m_infos[i].cu; } dw_offset_t DIEOffsetAtIndex(uint32_t i) const { return m_infos[i].die_offset; @@ -62,6 +56,9 @@ public: return m_infos[i].attr.get_attr(); } dw_attr_t FormAtIndex(uint32_t i) const { return m_infos[i].attr.get_form(); } + DWARFFormValue::ValueType ValueAtIndex(uint32_t i) const { + return m_infos[i].attr.get_value(); + } bool ExtractFormValueAtIndex(uint32_t i, DWARFFormValue &form_value) const; DWARFDIE FormValueAsReferenceAtIndex(uint32_t i) const; DWARFDIE FormValueAsReference(dw_attr_t attr) const; diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h index 059b84864be7..36df980f6ef0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h @@ -24,7 +24,7 @@ class SymbolFileDWARF; class DWARFBaseDIE { public: - DWARFBaseDIE() : m_cu(nullptr), m_die(nullptr) {} + DWARFBaseDIE() = default; DWARFBaseDIE(DWARFUnit *cu, DWARFDebugInfoEntry *die) : m_cu(cu), m_die(die) {} @@ -115,8 +115,8 @@ public: Recurse recurse = Recurse::yes) const; protected: - DWARFUnit *m_cu; - DWARFDebugInfoEntry *m_die; + DWARFUnit *m_cu = nullptr; + DWARFDebugInfoEntry *m_die = nullptr; }; bool operator==(const DWARFBaseDIE &lhs, const DWARFBaseDIE &rhs); diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp index 8e995e627978..dda691eecacc 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp @@ -54,7 +54,7 @@ public: explicit ElaboratingDIEIterator(DWARFDIE d) : m_worklist(1, d) {} /// End marker - ElaboratingDIEIterator() {} + ElaboratingDIEIterator() = default; const DWARFDIE &operator*() const { return m_worklist.back(); } ElaboratingDIEIterator &operator++() { @@ -192,7 +192,7 @@ DWARFDIE::LookupDeepestBlock(lldb::addr_t address) const { } if (check_children) { - for (DWARFDIE child = GetFirstChild(); child; child = child.GetSibling()) { + for (DWARFDIE child : children()) { if (DWARFDIE child_result = child.LookupDeepestBlock(address)) return child_result; } diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h index 13737280926c..56154055c44d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h @@ -11,9 +11,11 @@ #include "DWARFBaseDIE.h" #include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/iterator_range.h" class DWARFDIE : public DWARFBaseDIE { public: + class child_iterator; using DWARFBaseDIE::DWARFBaseDIE; // Tests @@ -88,6 +90,47 @@ public: int &decl_line, int &decl_column, int &call_file, int &call_line, int &call_column, lldb_private::DWARFExpression *frame_base) const; + /// The range of all the children of this DIE. + /// + /// This is a template just because child_iterator is not completely defined + /// at this point. + template <typename T = child_iterator> + llvm::iterator_range<T> children() const { + return llvm::make_range(T(*this), T()); + } +}; + +class DWARFDIE::child_iterator + : public llvm::iterator_facade_base<DWARFDIE::child_iterator, + std::forward_iterator_tag, DWARFDIE> { + /// The current child or an invalid DWARFDie. + DWARFDIE m_die; + +public: + child_iterator() = default; + child_iterator(const DWARFDIE &parent) : m_die(parent.GetFirstChild()) {} + bool operator==(const child_iterator &it) const { + // DWARFDIE's operator== differentiates between an invalid DWARFDIE that + // has a CU but no DIE and one that has neither CU nor DIE. The 'end' + // iterator could be default constructed, so explicitly allow + // (CU, (DIE)nullptr) == (nullptr, nullptr) -> true + if (!m_die.IsValid() && !it.m_die.IsValid()) + return true; + return m_die == it.m_die; + } + const DWARFDIE &operator*() const { + assert(m_die.IsValid() && "Derefencing invalid iterator?"); + return m_die; + } + DWARFDIE &operator*() { + assert(m_die.IsValid() && "Derefencing invalid iterator?"); + return m_die; + } + child_iterator &operator++() { + assert(m_die.IsValid() && "Incrementing invalid iterator?"); + m_die = m_die.GetSibling(); + return *this; + } }; #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDIE_H diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h index 555864f44967..ec6b93ce0e7f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h @@ -26,8 +26,7 @@ typedef DWARFAbbreviationDeclarationColl::const_iterator class DWARFAbbreviationDeclarationSet { public: - DWARFAbbreviationDeclarationSet() - : m_offset(DW_INVALID_OFFSET), m_idx_offset(0), m_decls() {} + DWARFAbbreviationDeclarationSet() : m_offset(DW_INVALID_OFFSET), m_decls() {} DWARFAbbreviationDeclarationSet(dw_offset_t offset, uint32_t idx_offset) : m_offset(offset), m_idx_offset(idx_offset), m_decls() {} @@ -51,7 +50,7 @@ public: /// @} private: dw_offset_t m_offset; - uint32_t m_idx_offset; + uint32_t m_idx_offset = 0; std::vector<DWARFAbbreviationDeclaration> m_decls; }; diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp index 728cefe620a5..ce514381ee39 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp @@ -8,22 +8,18 @@ #include "DWARFDebugArangeSet.h" #include "DWARFDataExtractor.h" +#include "LogChannelDWARF.h" #include "llvm/Object/Error.h" #include <cassert> using namespace lldb_private; DWARFDebugArangeSet::DWARFDebugArangeSet() - : m_offset(DW_INVALID_OFFSET), m_header(), m_arange_descriptors() { - m_header.length = 0; - m_header.version = 0; - m_header.cu_offset = 0; - m_header.addr_size = 0; - m_header.seg_size = 0; -} + : m_offset(DW_INVALID_OFFSET), m_next_offset(DW_INVALID_OFFSET) {} void DWARFDebugArangeSet::Clear() { m_offset = DW_INVALID_OFFSET; + m_next_offset = DW_INVALID_OFFSET; m_header.length = 0; m_header.version = 0; m_header.cu_offset = 0; @@ -54,6 +50,12 @@ llvm::Error DWARFDebugArangeSet::extract(const DWARFDataExtractor &data, // consists of an address and a length, each in the size appropriate for an // address on the target architecture. m_header.length = data.GetDWARFInitialLength(offset_ptr); + // The length could be 4 bytes or 12 bytes, so use the current offset to + // determine the next offset correctly. + if (m_header.length > 0) + m_next_offset = *offset_ptr + m_header.length; + else + m_next_offset = DW_INVALID_OFFSET; m_header.version = data.GetU16(offset_ptr); m_header.cu_offset = data.GetDWARFOffset(offset_ptr); m_header.addr_size = data.GetU8(offset_ptr); @@ -105,17 +107,45 @@ llvm::Error DWARFDebugArangeSet::extract(const DWARFDataExtractor &data, "DWARFDebugArangeSet::Descriptor.address and " "DWARFDebugArangeSet::Descriptor.length must have same size"); - while (data.ValidOffset(*offset_ptr)) { + const lldb::offset_t next_offset = GetNextOffset(); + assert(next_offset != DW_INVALID_OFFSET); + uint32_t num_terminators = 0; + bool last_was_terminator = false; + while (*offset_ptr < next_offset) { arangeDescriptor.address = data.GetMaxU64(offset_ptr, m_header.addr_size); arangeDescriptor.length = data.GetMaxU64(offset_ptr, m_header.addr_size); // Each set of tuples is terminated by a 0 for the address and 0 for - // the length. - if (!arangeDescriptor.address && !arangeDescriptor.length) - return llvm::ErrorSuccess(); - - m_arange_descriptors.push_back(arangeDescriptor); + // the length. Some linkers can emit .debug_aranges with multiple + // terminator pair entries that are still withing the length of the + // DWARFDebugArangeSet. We want to be sure to parse all entries for + // this DWARFDebugArangeSet so that we don't stop parsing early and end up + // treating addresses as a header of the next DWARFDebugArangeSet. We also + // need to make sure we parse all valid address pairs so we don't omit them + // from the aranges result, so we can't stop at the first terminator entry + // we find. + if (arangeDescriptor.address == 0 && arangeDescriptor.length == 0) { + ++num_terminators; + last_was_terminator = true; + } else { + last_was_terminator = false; + // Only add .debug_aranges address entries that have a non zero size. + // Some linkers will zero out the length field for some .debug_aranges + // entries if they were stripped. We also could watch out for multiple + // entries at address zero and remove those as well. + if (arangeDescriptor.length > 0) + m_arange_descriptors.push_back(arangeDescriptor); + } + } + if (num_terminators > 1) { + Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO); + LLDB_LOG(log, + "warning: DWARFDebugArangeSet at %#" PRIx64 " contains %u " + "terminator entries", + m_offset, num_terminators); } + if (last_was_terminator) + return llvm::ErrorSuccess(); return llvm::make_error<llvm::object::GenericBinaryError>( "arange descriptors not terminated by null entry"); diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h index 6b5b69a70a80..3c8633eaa3cc 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h @@ -16,18 +16,21 @@ class DWARFDebugArangeSet { public: struct Header { - uint32_t length; // The total length of the entries for that set, not - // including the length field itself. - uint16_t version; // The DWARF version number - uint32_t cu_offset; // The offset from the beginning of the .debug_info - // section of the compilation unit entry referenced by - // the table. - uint8_t addr_size; // The size in bytes of an address on the target - // architecture. For segmented addressing, this is the - // size of the offset portion of the address - uint8_t seg_size; // The size in bytes of a segment descriptor on the target - // architecture. If the target system uses a flat address - // space, this value is 0. + /// The total length of the entries for that set, not including the length + /// field itself. + uint32_t length = 0; + /// The DWARF version number. + uint16_t version = 0; + /// The offset from the beginning of the .debug_info section of the + /// compilation unit entry referenced by the table. + uint32_t cu_offset = 0; + /// The size in bytes of an address on the target architecture. For + /// segmented addressing, this is the size of the offset portion of the + /// address. + uint8_t addr_size = 0; + /// The size in bytes of a segment descriptor on the target architecture. + /// If the target system uses a flat address space, this value is 0. + uint8_t seg_size = 0; }; struct Descriptor { @@ -44,7 +47,7 @@ public: dw_offset_t FindAddress(dw_addr_t address) const; size_t NumDescriptors() const { return m_arange_descriptors.size(); } const Header &GetHeader() const { return m_header; } - + dw_offset_t GetNextOffset() const { return m_next_offset; } const Descriptor &GetDescriptorRef(uint32_t i) const { return m_arange_descriptors[i]; } @@ -54,7 +57,8 @@ protected: typedef DescriptorColl::iterator DescriptorIter; typedef DescriptorColl::const_iterator DescriptorConstIter; - uint32_t m_offset; + dw_offset_t m_offset; + dw_offset_t m_next_offset; Header m_header; DescriptorColl m_arange_descriptors; }; diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp index 9f190fbcee87..65923cb4ad6b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp @@ -9,6 +9,7 @@ #include "DWARFDebugAranges.h" #include "DWARFDebugArangeSet.h" #include "DWARFUnit.h" +#include "LogChannelDWARF.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Timer.h" @@ -31,31 +32,40 @@ public: }; // Extract -llvm::Error -DWARFDebugAranges::extract(const DWARFDataExtractor &debug_aranges_data) { +void DWARFDebugAranges::extract(const DWARFDataExtractor &debug_aranges_data) { lldb::offset_t offset = 0; DWARFDebugArangeSet set; Range range; while (debug_aranges_data.ValidOffset(offset)) { - llvm::Error error = set.extract(debug_aranges_data, &offset); - if (error) - return error; + const lldb::offset_t set_offset = offset; + if (llvm::Error error = set.extract(debug_aranges_data, &offset)) { + Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO); + LLDB_LOG_ERROR(log, std::move(error), + "DWARFDebugAranges::extract failed to extract " + ".debug_aranges set at offset %#" PRIx64, + set_offset); + } else { + const uint32_t num_descriptors = set.NumDescriptors(); + if (num_descriptors > 0) { + const dw_offset_t cu_offset = set.GetHeader().cu_offset; - const uint32_t num_descriptors = set.NumDescriptors(); - if (num_descriptors > 0) { - const dw_offset_t cu_offset = set.GetHeader().cu_offset; - - for (uint32_t i = 0; i < num_descriptors; ++i) { - const DWARFDebugArangeSet::Descriptor &descriptor = - set.GetDescriptorRef(i); - m_aranges.Append(RangeToDIE::Entry(descriptor.address, - descriptor.length, cu_offset)); + for (uint32_t i = 0; i < num_descriptors; ++i) { + const DWARFDebugArangeSet::Descriptor &descriptor = + set.GetDescriptorRef(i); + m_aranges.Append(RangeToDIE::Entry(descriptor.address, + descriptor.length, cu_offset)); + } } } + // Always use the previous DWARFDebugArangeSet's information to calculate + // the offset of the next DWARFDebugArangeSet in case we entouncter an + // error in the current DWARFDebugArangeSet and our offset position is + // still in the middle of the data. If we do this, we can parse all valid + // DWARFDebugArangeSet objects without returning invalid errors. + offset = set.GetNextOffset(); set.Clear(); } - return llvm::ErrorSuccess(); } void DWARFDebugAranges::Dump(Log *log) const { diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h index 96e82619f985..5ff37e400c88 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h @@ -26,8 +26,7 @@ public: void Clear() { m_aranges.Clear(); } - llvm::Error - extract(const lldb_private::DWARFDataExtractor &debug_aranges_data); + void extract(const lldb_private::DWARFDataExtractor &debug_aranges_data); // Use append range multiple times and then call sort void AppendRange(dw_offset_t cu_offset, dw_addr_t low_pc, dw_addr_t high_pc); diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp index 8d393b295443..e43afa104413 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp @@ -34,17 +34,18 @@ DWARFDebugInfo::DWARFDebugInfo(SymbolFileDWARF &dwarf, lldb_private::DWARFContext &context) : m_dwarf(dwarf), m_context(context), m_units(), m_cu_aranges_up() {} -llvm::Expected<DWARFDebugAranges &> DWARFDebugInfo::GetCompileUnitAranges() { +const DWARFDebugAranges &DWARFDebugInfo::GetCompileUnitAranges() { if (m_cu_aranges_up) return *m_cu_aranges_up; m_cu_aranges_up = std::make_unique<DWARFDebugAranges>(); const DWARFDataExtractor &debug_aranges_data = m_context.getOrLoadArangesData(); - if (llvm::Error error = m_cu_aranges_up->extract(debug_aranges_data)) - return std::move(error); - // Make a list of all CUs represented by the arange data in the file. + // Extract what we can from the .debug_aranges first. + m_cu_aranges_up->extract(debug_aranges_data); + + // Make a list of all CUs represented by the .debug_aranges data. std::set<dw_offset_t> cus_with_data; for (size_t n = 0; n < m_cu_aranges_up->GetNumRanges(); n++) { dw_offset_t offset = m_cu_aranges_up->OffsetAtIndex(n); @@ -52,8 +53,7 @@ llvm::Expected<DWARFDebugAranges &> DWARFDebugInfo::GetCompileUnitAranges() { cus_with_data.insert(offset); } - // Manually build arange data for everything that wasn't in the - // .debug_aranges table. + // Manually build arange data for everything that wasn't in .debug_aranges. const size_t num_units = GetNumUnits(); for (size_t idx = 0; idx < num_units; ++idx) { DWARFUnit *cu = GetUnitAtIndex(idx); @@ -72,16 +72,10 @@ void DWARFDebugInfo::ParseUnitsFor(DIERef::Section section) { DWARFDataExtractor data = section == DIERef::Section::DebugTypes ? m_context.getOrLoadDebugTypesData() : m_context.getOrLoadDebugInfoData(); - const llvm::DWARFUnitIndex *index = nullptr; - if (m_context.isDwo()) - index = &llvm::getDWARFUnitIndex(m_context.GetAsLLVM(), - section == DIERef::Section::DebugTypes - ? llvm::DW_SECT_EXT_TYPES - : llvm::DW_SECT_INFO); lldb::offset_t offset = 0; while (data.ValidOffset(offset)) { llvm::Expected<DWARFUnitSP> unit_sp = DWARFUnit::extract( - m_dwarf, m_units.size(), data, section, &offset, index); + m_dwarf, m_units.size(), data, section, &offset); if (!unit_sp) { // FIXME: Propagate this error up. diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h index bdc718a5c2fa..46c04d749c46 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h @@ -54,7 +54,7 @@ public: (1 << 2) // Show all parent DIEs when dumping single DIEs }; - llvm::Expected<DWARFDebugAranges &> GetCompileUnitAranges(); + const DWARFDebugAranges &GetCompileUnitAranges(); protected: typedef std::vector<DWARFUnitSP> UnitColl; diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp index 421298802645..39915aa889ff 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -8,7 +8,7 @@ #include "DWARFDebugInfoEntry.h" -#include <assert.h> +#include <cassert> #include <algorithm> @@ -49,156 +49,159 @@ bool DWARFDebugInfoEntry::Extract(const DWARFDataExtractor &data, // assert (fixed_form_sizes); // For best performance this should be // specified! - if (m_abbr_idx) { - lldb::offset_t offset = *offset_ptr; - const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu); - if (abbrevDecl == nullptr) { - cu->GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( - "{0x%8.8x}: invalid abbreviation code %u, please file a bug and " - "attach the file at the start of this error message", - m_offset, (unsigned)abbr_idx); - // WE can't parse anymore if the DWARF is borked... - *offset_ptr = UINT32_MAX; - return false; - } - m_tag = abbrevDecl->Tag(); - m_has_children = abbrevDecl->HasChildren(); - // Skip all data in the .debug_info or .debug_types for the attributes - const uint32_t numAttributes = abbrevDecl->NumAttributes(); - uint32_t i; - dw_form_t form; - for (i = 0; i < numAttributes; ++i) { - form = abbrevDecl->GetFormByIndexUnchecked(i); - llvm::Optional<uint8_t> fixed_skip_size = - DWARFFormValue::GetFixedSize(form, cu); - if (fixed_skip_size) - offset += *fixed_skip_size; - else { - bool form_is_indirect = false; - do { - form_is_indirect = false; - uint32_t form_size = 0; - switch (form) { - // Blocks if inlined data that have a length field and the data bytes - // inlined in the .debug_info/.debug_types - case DW_FORM_exprloc: - case DW_FORM_block: - form_size = data.GetULEB128(&offset); - break; - case DW_FORM_block1: - form_size = data.GetU8_unchecked(&offset); - break; - case DW_FORM_block2: - form_size = data.GetU16_unchecked(&offset); - break; - case DW_FORM_block4: - form_size = data.GetU32_unchecked(&offset); - break; - - // Inlined NULL terminated C-strings - case DW_FORM_string: - data.GetCStr(&offset); - break; - - // Compile unit address sized values - case DW_FORM_addr: - form_size = cu->GetAddressByteSize(); - break; - case DW_FORM_ref_addr: - if (cu->GetVersion() <= 2) - form_size = cu->GetAddressByteSize(); - else - form_size = 4; - break; - - // 0 sized form - case DW_FORM_flag_present: - form_size = 0; - break; - - // 1 byte values - case DW_FORM_addrx1: - case DW_FORM_data1: - case DW_FORM_flag: - case DW_FORM_ref1: - case DW_FORM_strx1: - form_size = 1; - break; - - // 2 byte values - case DW_FORM_addrx2: - case DW_FORM_data2: - case DW_FORM_ref2: - case DW_FORM_strx2: - form_size = 2; - break; - - // 3 byte values - case DW_FORM_addrx3: - case DW_FORM_strx3: - form_size = 3; - break; - - // 4 byte values - case DW_FORM_addrx4: - case DW_FORM_data4: - case DW_FORM_ref4: - case DW_FORM_strx4: - form_size = 4; - break; - - // 8 byte values - case DW_FORM_data8: - case DW_FORM_ref8: - case DW_FORM_ref_sig8: - form_size = 8; - break; - - // signed or unsigned LEB 128 values - case DW_FORM_addrx: - case DW_FORM_loclistx: - case DW_FORM_rnglistx: - case DW_FORM_sdata: - case DW_FORM_udata: - case DW_FORM_ref_udata: - case DW_FORM_GNU_addr_index: - case DW_FORM_GNU_str_index: - case DW_FORM_strx: - data.Skip_LEB128(&offset); - break; - - case DW_FORM_indirect: - form_is_indirect = true; - form = data.GetULEB128(&offset); - break; - - case DW_FORM_strp: - case DW_FORM_sec_offset: - data.GetU32(&offset); - break; - - case DW_FORM_implicit_const: - form_size = 0; - break; - - default: - *offset_ptr = m_offset; - return false; - } - offset += form_size; - - } while (form_is_indirect); - } - } - *offset_ptr = offset; - return true; - } else { + if (m_abbr_idx == 0) { m_tag = llvm::dwarf::DW_TAG_null; m_has_children = false; return true; // NULL debug tag entry } - return false; + lldb::offset_t offset = *offset_ptr; + const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu); + if (abbrevDecl == nullptr) { + cu->GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( + "{0x%8.8x}: invalid abbreviation code %u, please file a bug and " + "attach the file at the start of this error message", + m_offset, (unsigned)abbr_idx); + // WE can't parse anymore if the DWARF is borked... + *offset_ptr = UINT32_MAX; + return false; + } + m_tag = abbrevDecl->Tag(); + m_has_children = abbrevDecl->HasChildren(); + // Skip all data in the .debug_info or .debug_types for the attributes + const uint32_t numAttributes = abbrevDecl->NumAttributes(); + uint32_t i; + dw_form_t form; + for (i = 0; i < numAttributes; ++i) { + form = abbrevDecl->GetFormByIndexUnchecked(i); + llvm::Optional<uint8_t> fixed_skip_size = + DWARFFormValue::GetFixedSize(form, cu); + if (fixed_skip_size) + offset += *fixed_skip_size; + else { + bool form_is_indirect = false; + do { + form_is_indirect = false; + uint32_t form_size = 0; + switch (form) { + // Blocks if inlined data that have a length field and the data bytes + // inlined in the .debug_info/.debug_types + case DW_FORM_exprloc: + case DW_FORM_block: + form_size = data.GetULEB128(&offset); + break; + case DW_FORM_block1: + form_size = data.GetU8_unchecked(&offset); + break; + case DW_FORM_block2: + form_size = data.GetU16_unchecked(&offset); + break; + case DW_FORM_block4: + form_size = data.GetU32_unchecked(&offset); + break; + + // Inlined NULL terminated C-strings + case DW_FORM_string: + data.GetCStr(&offset); + break; + + // Compile unit address sized values + case DW_FORM_addr: + form_size = cu->GetAddressByteSize(); + break; + case DW_FORM_ref_addr: + if (cu->GetVersion() <= 2) + form_size = cu->GetAddressByteSize(); + else + form_size = 4; + break; + + // 0 sized form + case DW_FORM_flag_present: + form_size = 0; + break; + + // 1 byte values + case DW_FORM_addrx1: + case DW_FORM_data1: + case DW_FORM_flag: + case DW_FORM_ref1: + case DW_FORM_strx1: + form_size = 1; + break; + + // 2 byte values + case DW_FORM_addrx2: + case DW_FORM_data2: + case DW_FORM_ref2: + case DW_FORM_strx2: + form_size = 2; + break; + + // 3 byte values + case DW_FORM_addrx3: + case DW_FORM_strx3: + form_size = 3; + break; + + // 4 byte values + case DW_FORM_addrx4: + case DW_FORM_data4: + case DW_FORM_ref4: + case DW_FORM_strx4: + form_size = 4; + break; + + // 8 byte values + case DW_FORM_data8: + case DW_FORM_ref8: + case DW_FORM_ref_sig8: + form_size = 8; + break; + + // signed or unsigned LEB 128 values + case DW_FORM_addrx: + case DW_FORM_loclistx: + case DW_FORM_rnglistx: + case DW_FORM_sdata: + case DW_FORM_udata: + case DW_FORM_ref_udata: + case DW_FORM_GNU_addr_index: + case DW_FORM_GNU_str_index: + case DW_FORM_strx: + data.Skip_LEB128(&offset); + break; + + case DW_FORM_indirect: + form_is_indirect = true; + form = data.GetULEB128(&offset); + break; + + case DW_FORM_strp: + case DW_FORM_line_strp: + case DW_FORM_sec_offset: + data.GetU32(&offset); + break; + + case DW_FORM_implicit_const: + form_size = 0; + break; + + default: + cu->GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( + "{0x%8.8x}: Unsupported DW_FORM_0x%x, please file a bug and " + "attach the file at the start of this error message", + m_offset, (unsigned)form); + *offset_ptr = m_offset; + return false; + } + offset += form_size; + + } while (form_is_indirect); + } + } + *offset_ptr = offset; + return true; } static DWARFRangeList GetRangesOrReportError(DWARFUnit &unit, @@ -211,11 +214,12 @@ static DWARFRangeList GetRangesOrReportError(DWARFUnit &unit, if (expected_ranges) return std::move(*expected_ranges); unit.GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( - "{0x%8.8x}: DIE has DW_AT_ranges(0x%" PRIx64 ") attribute, but " + "{0x%8.8x}: DIE has DW_AT_ranges(%s 0x%" PRIx64 ") attribute, but " "range extraction failed (%s), please file a bug " "and attach the file at the start of this error message", - die.GetOffset(), value.Unsigned(), - toString(expected_ranges.takeError()).c_str()); + die.GetOffset(), + llvm::dwarf::FormEncodingString(value.Form()).str().c_str(), + value.Unsigned(), toString(expected_ranges.takeError()).c_str()); return DWARFRangeList(); } @@ -429,7 +433,7 @@ size_t DWARFDebugInfoEntry::GetAttributes(DWARFUnit *cu, } LLVM_FALLTHROUGH; default: - attributes.Append(cu, offset, attr, form); + attributes.Append(form_value, offset, attr); break; } diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h index 0ba56a0a4161..64e86c71ac09 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h @@ -35,8 +35,7 @@ public: typedef collection::const_iterator const_iterator; DWARFDebugInfoEntry() - : m_offset(DW_INVALID_OFFSET), m_parent_idx(0), m_sibling_idx(0), - m_has_children(false), m_abbr_idx(0), m_tag(llvm::dwarf::DW_TAG_null) {} + : m_offset(DW_INVALID_OFFSET), m_sibling_idx(0), m_has_children(false) {} explicit operator bool() const { return m_offset != DW_INVALID_OFFSET; } bool operator==(const DWARFDebugInfoEntry &rhs) const; @@ -167,14 +166,14 @@ protected: GetDWARFDeclContextStatic(const DWARFDebugInfoEntry *die, DWARFUnit *cu); dw_offset_t m_offset; // Offset within the .debug_info/.debug_types - uint32_t m_parent_idx; // How many to subtract from "this" to get the parent. - // If zero this die has no parent + uint32_t m_parent_idx = 0; // How many to subtract from "this" to get the + // parent. If zero this die has no parent uint32_t m_sibling_idx : 31, // How many to add to "this" to get the sibling. // If it is zero, then the DIE doesn't have children, or the // DWARF claimed it had children but the DIE only contained // a single NULL terminating child. m_has_children : 1; - uint16_t m_abbr_idx; + uint16_t m_abbr_idx = 0; /// A copy of the DW_TAG value so we don't have to go through the compile /// unit abbrev table dw_tag_t m_tag = llvm::dwarf::DW_TAG_null; diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h index 9072b2dc0115..e46694405415 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h @@ -23,7 +23,7 @@ class DWARFDeclContext { public: struct Entry { - Entry() : tag(llvm::dwarf::DW_TAG_null), name(nullptr) {} + Entry() = default; Entry(dw_tag_t t, const char *n) : tag(t), name(n) {} bool NameMatches(const Entry &rhs) const { @@ -37,11 +37,11 @@ public: // Test operator explicit operator bool() const { return tag != 0; } - dw_tag_t tag; - const char *name; + dw_tag_t tag = llvm::dwarf::DW_TAG_null; + const char *name = nullptr; }; - DWARFDeclContext() : m_entries(), m_language(lldb::eLanguageTypeUnknown) {} + DWARFDeclContext() : m_entries() {} void AppendDeclContext(dw_tag_t tag, const char *name) { m_entries.push_back(Entry(tag, name)); @@ -83,7 +83,7 @@ protected: typedef std::vector<Entry> collection; collection m_entries; mutable std::string m_qualified_name; - lldb::LanguageType m_language; + lldb::LanguageType m_language = lldb::eLanguageTypeUnknown; }; #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDECLCONTEXT_H diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h index 1b7102cd7e31..2d0d5cad4612 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h @@ -10,7 +10,7 @@ #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEFINES_H #include "lldb/Core/dwarf.h" -#include <stdint.h> +#include <cstdint> namespace lldb_private { diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp index 305f1cbd2826..4c498705da45 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include <assert.h> +#include <cassert> #include "lldb/Core/Module.h" #include "lldb/Core/dwarf.h" @@ -150,40 +150,40 @@ struct FormSize { uint8_t valid:1, size:7; }; static FormSize g_form_sizes[] = { - {0,0}, // 0x00 unused - {0,0}, // 0x01 DW_FORM_addr - {0,0}, // 0x02 unused - {0,0}, // 0x03 DW_FORM_block2 - {0,0}, // 0x04 DW_FORM_block4 - {1,2}, // 0x05 DW_FORM_data2 - {1,4}, // 0x06 DW_FORM_data4 - {1,8}, // 0x07 DW_FORM_data8 - {0,0}, // 0x08 DW_FORM_string - {0,0}, // 0x09 DW_FORM_block - {0,0}, // 0x0a DW_FORM_block1 - {1,1}, // 0x0b DW_FORM_data1 - {1,1}, // 0x0c DW_FORM_flag - {0,0}, // 0x0d DW_FORM_sdata - {1,4}, // 0x0e DW_FORM_strp - {0,0}, // 0x0f DW_FORM_udata - {0,0}, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for - // DWARF32, 8 bytes for DWARF32 in DWARF 3 and later - {1,1}, // 0x11 DW_FORM_ref1 - {1,2}, // 0x12 DW_FORM_ref2 - {1,4}, // 0x13 DW_FORM_ref4 - {1,8}, // 0x14 DW_FORM_ref8 - {0,0}, // 0x15 DW_FORM_ref_udata - {0,0}, // 0x16 DW_FORM_indirect - {1,4}, // 0x17 DW_FORM_sec_offset - {0,0}, // 0x18 DW_FORM_exprloc - {1,0}, // 0x19 DW_FORM_flag_present - {0,0}, // 0x1a - {0,0}, // 0x1b - {0,0}, // 0x1c - {0,0}, // 0x1d - {0,0}, // 0x1e - {0,0}, // 0x1f - {1,8}, // 0x20 DW_FORM_ref_sig8 + {0, 0}, // 0x00 unused + {0, 0}, // 0x01 DW_FORM_addr + {0, 0}, // 0x02 unused + {0, 0}, // 0x03 DW_FORM_block2 + {0, 0}, // 0x04 DW_FORM_block4 + {1, 2}, // 0x05 DW_FORM_data2 + {1, 4}, // 0x06 DW_FORM_data4 + {1, 8}, // 0x07 DW_FORM_data8 + {0, 0}, // 0x08 DW_FORM_string + {0, 0}, // 0x09 DW_FORM_block + {0, 0}, // 0x0a DW_FORM_block1 + {1, 1}, // 0x0b DW_FORM_data1 + {1, 1}, // 0x0c DW_FORM_flag + {0, 0}, // 0x0d DW_FORM_sdata + {1, 4}, // 0x0e DW_FORM_strp + {0, 0}, // 0x0f DW_FORM_udata + {0, 0}, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes + // for DWARF32, 8 bytes for DWARF32 in DWARF 3 and later + {1, 1}, // 0x11 DW_FORM_ref1 + {1, 2}, // 0x12 DW_FORM_ref2 + {1, 4}, // 0x13 DW_FORM_ref4 + {1, 8}, // 0x14 DW_FORM_ref8 + {0, 0}, // 0x15 DW_FORM_ref_udata + {0, 0}, // 0x16 DW_FORM_indirect + {1, 4}, // 0x17 DW_FORM_sec_offset + {0, 0}, // 0x18 DW_FORM_exprloc + {1, 0}, // 0x19 DW_FORM_flag_present + {0, 0}, // 0x1a DW_FORM_strx (ULEB128) + {0, 0}, // 0x1b DW_FORM_addrx (ULEB128) + {1, 4}, // 0x1c DW_FORM_ref_sup4 + {0, 0}, // 0x1d DW_FORM_strp_sup (4 bytes for DWARF32, 8 bytes for DWARF64) + {1, 16}, // 0x1e DW_FORM_data16 + {1, 4}, // 0x1f DW_FORM_line_strp + {1, 8}, // 0x20 DW_FORM_ref_sig8 }; llvm::Optional<uint8_t> @@ -286,6 +286,7 @@ bool DWARFFormValue::SkipValue(dw_form_t form, // 32 bit for DWARF 32, 64 for DWARF 64 case DW_FORM_sec_offset: case DW_FORM_strp: + case DW_FORM_line_strp: *offset_ptr += 4; return true; @@ -398,7 +399,8 @@ void DWARFFormValue::Dump(Stream &s) const { case DW_FORM_udata: s.PutULEB128(uvalue); break; - case DW_FORM_strp: { + case DW_FORM_strp: + case DW_FORM_line_strp: { const char *dbg_str = AsCString(); if (dbg_str) { s.QuotedCString(dbg_str); @@ -606,6 +608,7 @@ bool DWARFFormValue::FormIsSupported(dw_form_t form) { case DW_FORM_flag: case DW_FORM_sdata: case DW_FORM_strp: + case DW_FORM_line_strp: case DW_FORM_strx: case DW_FORM_strx1: case DW_FORM_strx2: diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h index fe6a55520978..9406bcf0c038 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h @@ -10,8 +10,8 @@ #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFFORMVALUE_H #include "DWARFDataExtractor.h" -#include <stddef.h> #include "llvm/ADT/Optional.h" +#include <cstddef> class DWARFUnit; class SymbolFileDWARF; @@ -20,14 +20,14 @@ class DWARFDIE; class DWARFFormValue { public: typedef struct ValueTypeTag { - ValueTypeTag() : value(), data(nullptr) { value.uval = 0; } + ValueTypeTag() : value() { value.uval = 0; } union { uint64_t uval; int64_t sval; const char *cstr; } value; - const uint8_t *data; + const uint8_t *data = nullptr; } ValueType; enum { diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp index a761dd3daac4..824e43872269 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -236,6 +236,11 @@ void DWARFUnit::ExtractDIEsRWLocked() { } if (!m_die_array.empty()) { + // The last die cannot have children (if it did, it wouldn't be the last one). + // This only makes a difference for malformed dwarf that does not have a + // terminating null die. + m_die_array.back().SetHasChildren(false); + if (m_first_die) { // Only needed for the assertion. m_first_die.SetHasChildren(m_die_array.front().HasChildren()); @@ -292,8 +297,7 @@ uint64_t DWARFUnit::GetDWOId() { // m_die_array_mutex must be already held as read/write. void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) { - llvm::Optional<uint64_t> addr_base, gnu_addr_base, ranges_base, - gnu_ranges_base; + llvm::Optional<uint64_t> addr_base, gnu_addr_base, gnu_ranges_base; DWARFAttributes attributes; size_t num_attributes = cu_die.GetAttributes(this, attributes); @@ -320,8 +324,7 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) { SetLoclistsBase(form_value.Unsigned()); break; case DW_AT_rnglists_base: - ranges_base = form_value.Unsigned(); - SetRangesBase(*ranges_base); + SetRangesBase(form_value.Unsigned()); break; case DW_AT_str_offsets_base: SetStrOffsetsBase(form_value.Unsigned()); @@ -482,19 +485,46 @@ DWARFDataExtractor DWARFUnit::GetLocationData() const { } void DWARFUnit::SetRangesBase(dw_addr_t ranges_base) { + lldbassert(!m_rnglist_table_done); + m_ranges_base = ranges_base; +} - if (GetVersion() < 5) - return; +const llvm::Optional<llvm::DWARFDebugRnglistTable> & +DWARFUnit::GetRnglistTable() { + if (GetVersion() >= 5 && !m_rnglist_table_done) { + m_rnglist_table_done = true; + if (auto table_or_error = + ParseListTableHeader<llvm::DWARFDebugRnglistTable>( + m_dwarf.GetDWARFContext().getOrLoadRngListsData().GetAsLLVM(), + m_ranges_base, DWARF32)) + m_rnglist_table = std::move(table_or_error.get()); + else + GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( + "Failed to extract range list table at offset 0x%" PRIx64 ": %s", + m_ranges_base, toString(table_or_error.takeError()).c_str()); + } + return m_rnglist_table; +} - if (auto table_or_error = ParseListTableHeader<llvm::DWARFDebugRnglistTable>( - m_dwarf.GetDWARFContext().getOrLoadRngListsData().GetAsLLVM(), - ranges_base, DWARF32)) - m_rnglist_table = std::move(table_or_error.get()); - else - GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( - "Failed to extract range list table at offset 0x%" PRIx64 ": %s", - ranges_base, toString(table_or_error.takeError()).c_str()); +// This function is called only for DW_FORM_rnglistx. +llvm::Expected<uint64_t> DWARFUnit::GetRnglistOffset(uint32_t Index) { + if (!GetRnglistTable()) + return llvm::createStringError(errc::invalid_argument, + "missing or invalid range list table"); + if (!m_ranges_base) + return llvm::createStringError(errc::invalid_argument, + "DW_FORM_rnglistx cannot be used without " + "DW_AT_rnglists_base for CU at 0x%8.8x", + GetOffset()); + if (llvm::Optional<uint64_t> off = GetRnglistTable()->getOffsetEntry( + m_dwarf.GetDWARFContext().getOrLoadRngListsData().GetAsLLVM(), Index)) + return *off + m_ranges_base; + return llvm::createStringError( + errc::invalid_argument, + "invalid range list table index %u; OffsetEntryCount is %u, " + "DW_AT_rnglists_base is %" PRIu64, + Index, GetRnglistTable()->getOffsetEntryCount(), m_ranges_base); } void DWARFUnit::SetStrOffsetsBase(dw_offset_t str_offsets_base) { @@ -784,12 +814,11 @@ const DWARFDebugAranges &DWARFUnit::GetFunctionAranges() { llvm::Expected<DWARFUnitHeader> DWARFUnitHeader::extract(const DWARFDataExtractor &data, - DIERef::Section section, lldb::offset_t *offset_ptr, - const llvm::DWARFUnitIndex *index) { + DIERef::Section section, + lldb_private::DWARFContext &context, + lldb::offset_t *offset_ptr) { DWARFUnitHeader header; header.m_offset = *offset_ptr; - if (index) - header.m_index_entry = index->getFromOffset(*offset_ptr); header.m_length = data.GetDWARFInitialLength(offset_ptr); header.m_version = data.GetU16(offset_ptr); if (header.m_version == 5) { @@ -806,6 +835,16 @@ DWARFUnitHeader::extract(const DWARFDataExtractor &data, section == DIERef::Section::DebugTypes ? DW_UT_type : DW_UT_compile; } + if (context.isDwo()) { + if (header.IsTypeUnit()) { + header.m_index_entry = + context.GetAsLLVM().getTUIndex().getFromOffset(header.m_offset); + } else { + header.m_index_entry = + context.GetAsLLVM().getCUIndex().getFromOffset(header.m_offset); + } + } + if (header.m_index_entry) { if (header.m_abbr_offset) { return llvm::createStringError( @@ -856,12 +895,11 @@ DWARFUnitHeader::extract(const DWARFDataExtractor &data, llvm::Expected<DWARFUnitSP> DWARFUnit::extract(SymbolFileDWARF &dwarf, user_id_t uid, const DWARFDataExtractor &debug_info, - DIERef::Section section, lldb::offset_t *offset_ptr, - const llvm::DWARFUnitIndex *index) { + DIERef::Section section, lldb::offset_t *offset_ptr) { assert(debug_info.ValidOffset(*offset_ptr)); - auto expected_header = - DWARFUnitHeader::extract(debug_info, section, offset_ptr, index); + auto expected_header = DWARFUnitHeader::extract( + debug_info, section, dwarf.GetDWARFContext(), offset_ptr); if (!expected_header) return expected_header.takeError(); @@ -930,11 +968,11 @@ DWARFUnit::FindRnglistFromOffset(dw_offset_t offset) { return ranges; } - if (!m_rnglist_table) + if (!GetRnglistTable()) return llvm::createStringError(errc::invalid_argument, "missing or invalid range list table"); - auto range_list_or_error = m_rnglist_table->findList( + auto range_list_or_error = GetRnglistTable()->findList( m_dwarf.GetDWARFContext().getOrLoadRngListsData().GetAsLLVM(), offset); if (!range_list_or_error) return range_list_or_error.takeError(); @@ -963,12 +1001,8 @@ DWARFUnit::FindRnglistFromOffset(dw_offset_t offset) { llvm::Expected<DWARFRangeList> DWARFUnit::FindRnglistFromIndex(uint32_t index) { - if (llvm::Optional<uint64_t> offset = GetRnglistOffset(index)) - return FindRnglistFromOffset(*offset); - if (m_rnglist_table) - return llvm::createStringError(errc::invalid_argument, - "invalid range list table index %d", index); - - return llvm::createStringError(errc::invalid_argument, - "missing or invalid range list table"); + llvm::Expected<uint64_t> maybe_offset = GetRnglistOffset(index); + if (!maybe_offset) + return maybe_offset.takeError(); + return FindRnglistFromOffset(*maybe_offset); } diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h index 5739c36bbacb..da79a6aaf64e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -73,7 +73,8 @@ public: static llvm::Expected<DWARFUnitHeader> extract(const lldb_private::DWARFDataExtractor &data, DIERef::Section section, - lldb::offset_t *offset_ptr, const llvm::DWARFUnitIndex *index); + lldb_private::DWARFContext &dwarf_context, + lldb::offset_t *offset_ptr); }; class DWARFUnit : public lldb_private::UserID { @@ -84,8 +85,7 @@ public: static llvm::Expected<DWARFUnitSP> extract(SymbolFileDWARF &dwarf2Data, lldb::user_id_t uid, const lldb_private::DWARFDataExtractor &debug_info, - DIERef::Section section, lldb::offset_t *offset_ptr, - const llvm::DWARFUnitIndex *index); + DIERef::Section section, lldb::offset_t *offset_ptr); virtual ~DWARFUnit(); bool IsDWOUnit() { return m_is_dwo; } @@ -235,15 +235,7 @@ public: /// Return a rangelist's offset based on an index. The index designates /// an entry in the rangelist table's offset array and is supplied by /// DW_FORM_rnglistx. - llvm::Optional<uint64_t> GetRnglistOffset(uint32_t Index) const { - if (!m_rnglist_table) - return llvm::None; - if (llvm::Optional<uint64_t> off = m_rnglist_table->getOffsetEntry( - m_dwarf.GetDWARFContext().getOrLoadRngListsData().GetAsLLVM(), - Index)) - return *off + m_ranges_base; - return llvm::None; - } + llvm::Expected<uint64_t> GetRnglistOffset(uint32_t Index); llvm::Optional<uint64_t> GetLoclistOffset(uint32_t Index) { if (!m_loclist_table_header) @@ -291,6 +283,8 @@ protected: return &m_die_array[0]; } + const llvm::Optional<llvm::DWARFDebugRnglistTable> &GetRnglistTable(); + SymbolFileDWARF &m_dwarf; std::shared_ptr<DWARFUnit> m_dwo; DWARFUnitHeader m_header; @@ -331,6 +325,7 @@ protected: dw_offset_t m_str_offsets_base = 0; // Value of DW_AT_str_offsets_base. llvm::Optional<llvm::DWARFDebugRnglistTable> m_rnglist_table; + bool m_rnglist_table_done = false; llvm::Optional<llvm::DWARFListTableHeader> m_loclist_table_header; const DIERef::Section m_section; diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp index d36f2a8bccf7..ce71281db8bd 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp @@ -130,8 +130,7 @@ DWARFMappedHash::DIEInfo::DIEInfo(dw_offset_t o, dw_tag_t t, uint32_t f, : die_offset(o), tag(t), type_flags(f), qualified_name_hash(h) {} DWARFMappedHash::Prologue::Prologue(dw_offset_t _die_base_offset) - : die_base_offset(_die_base_offset), atoms(), atom_mask(0), - min_hash_data_byte_size(0), hash_data_has_fixed_byte_size(true) { + : die_base_offset(_die_base_offset), atoms() { // Define an array of DIE offsets by first defining an array, and then define // the atom type for the array, in this case we have an array of DIE offsets. AppendAtom(eAtomTypeDIEOffset, DW_FORM_data4); diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h index ad178fc6a987..efc08e47a280 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h @@ -101,9 +101,9 @@ public: /// DIE offset base so die offsets in hash_data can be CU relative. dw_offset_t die_base_offset; AtomArray atoms; - uint32_t atom_mask; - size_t min_hash_data_byte_size; - bool hash_data_has_fixed_byte_size; + uint32_t atom_mask = 0; + size_t min_hash_data_byte_size = 0; + bool hash_data_has_fixed_byte_size = true; }; class Header : public MappedHash::Header<Prologue> { diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp index dda599baffeb..1f40d880ea34 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp @@ -13,9 +13,11 @@ #include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h" #include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h" #include "lldb/Core/Module.h" +#include "lldb/Core/Progress.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/Timer.h" +#include "llvm/Support/FormatVariadic.h" #include "llvm/Support/ThreadPool.h" using namespace lldb_private; @@ -56,6 +58,17 @@ void ManualDWARFIndex::Index() { if (units_to_index.empty()) return; + StreamString module_desc; + m_module.GetDescription(module_desc.AsRawOstream(), + lldb::eDescriptionLevelBrief); + + // Include 2 passes per unit to index for extracting DIEs from the unit and + // indexing the unit, and then 8 extra entries for finalizing each index set. + const uint64_t total_progress = units_to_index.size() * 2 + 8; + Progress progress( + llvm::formatv("Manually indexing DWARF for {0}", module_desc.GetData()), + total_progress); + std::vector<IndexSet> sets(units_to_index.size()); // Keep memory down by clearing DIEs for any units if indexing @@ -64,10 +77,12 @@ void ManualDWARFIndex::Index() { units_to_index.size()); auto parser_fn = [&](size_t cu_idx) { IndexUnit(*units_to_index[cu_idx], dwp_dwarf, sets[cu_idx]); + progress.Increment(); }; - auto extract_fn = [&units_to_index, &clear_cu_dies](size_t cu_idx) { + auto extract_fn = [&](size_t cu_idx) { clear_cu_dies[cu_idx] = units_to_index[cu_idx]->ExtractDIEsScoped(); + progress.Increment(); }; // Share one thread pool across operations to avoid the overhead of @@ -92,11 +107,12 @@ void ManualDWARFIndex::Index() { pool.async(parser_fn, i); pool.wait(); - auto finalize_fn = [this, &sets](NameToDIE(IndexSet::*index)) { + auto finalize_fn = [this, &sets, &progress](NameToDIE(IndexSet::*index)) { NameToDIE &result = m_set.*index; for (auto &set : sets) result.Append(set.*index); result.Finalize(); + progress.Increment(); }; pool.async(finalize_fn, &IndexSet::function_basenames); diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h index 5aa841cf3d10..a6863f6c9549 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h @@ -22,7 +22,7 @@ class NameToDIE { public: NameToDIE() : m_map() {} - ~NameToDIE() {} + ~NameToDIE() = default; void Dump(lldb_private::Stream *s); diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 3656c7333f27..ccaf31317d75 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -16,6 +16,7 @@ #include "lldb/Core/ModuleList.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" +#include "lldb/Core/Progress.h" #include "lldb/Core/Section.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/Value.h" @@ -74,18 +75,19 @@ #include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/FormatVariadic.h" #include <algorithm> #include <map> #include <memory> -#include <ctype.h> -#include <string.h> +#include <cctype> +#include <cstring> //#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN #ifdef ENABLE_DEBUG_PRINTF -#include <stdio.h> +#include <cstdio> #define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__) #else #define DEBUG_PRINTF(fmt, ...) @@ -238,9 +240,12 @@ ParseSupportFilesFromPrologue(const lldb::ModuleSP &module, const size_t number_of_files = prologue.FileNames.size(); for (size_t idx = first_file; idx <= number_of_files; ++idx) { std::string remapped_file; - if (auto file_path = GetFileByIndex(prologue, idx, compile_dir, style)) - if (!module->RemapSourceFile(llvm::StringRef(*file_path), remapped_file)) + if (auto file_path = GetFileByIndex(prologue, idx, compile_dir, style)) { + if (auto remapped = module->RemapSourceFile(llvm::StringRef(*file_path))) + remapped_file = *remapped; + else remapped_file = std::move(*file_path); + } // Unconditionally add an entry, so the indices match up. support_files.EmplaceBack(remapped_file, style); @@ -358,8 +363,7 @@ void SymbolFileDWARF::GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset, } } - for (DWARFDIE child_die = die.GetFirstChild(); child_die.IsValid(); - child_die = child_die.GetSibling()) { + for (DWARFDIE child_die : die.children()) { GetTypes(child_die, min_die_offset, max_die_offset, type_mask, type_set); } } @@ -435,7 +439,7 @@ SymbolFileDWARF::SymbolFileDWARF(ObjectFileSP objfile_sp, m_fetched_external_modules(false), m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {} -SymbolFileDWARF::~SymbolFileDWARF() {} +SymbolFileDWARF::~SymbolFileDWARF() = default; static ConstString GetDWARFMachOSegmentName() { static ConstString g_dwarf_section_name("__DWARF"); @@ -467,22 +471,32 @@ void SymbolFileDWARF::InitializeObject() { Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO); if (!GetGlobalPluginProperties()->IgnoreFileIndexes()) { + StreamString module_desc; + GetObjectFile()->GetModule()->GetDescription(module_desc.AsRawOstream(), + lldb::eDescriptionLevelBrief); DWARFDataExtractor apple_names, apple_namespaces, apple_types, apple_objc; LoadSectionData(eSectionTypeDWARFAppleNames, apple_names); LoadSectionData(eSectionTypeDWARFAppleNamespaces, apple_namespaces); LoadSectionData(eSectionTypeDWARFAppleTypes, apple_types); LoadSectionData(eSectionTypeDWARFAppleObjC, apple_objc); - m_index = AppleDWARFIndex::Create( - *GetObjectFile()->GetModule(), apple_names, apple_namespaces, - apple_types, apple_objc, m_context.getOrLoadStrData()); + if (apple_names.GetByteSize() > 0 || apple_namespaces.GetByteSize() > 0 || + apple_types.GetByteSize() > 0 || apple_objc.GetByteSize() > 0) { + Progress progress(llvm::formatv("Loading Apple DWARF index for {0}", + module_desc.GetData())); + m_index = AppleDWARFIndex::Create( + *GetObjectFile()->GetModule(), apple_names, apple_namespaces, + apple_types, apple_objc, m_context.getOrLoadStrData()); - if (m_index) - return; + if (m_index) + return; + } DWARFDataExtractor debug_names; LoadSectionData(eSectionTypeDWARFDebugNames, debug_names); if (debug_names.GetByteSize() > 0) { + Progress progress( + llvm::formatv("Loading DWARF5 index for {0}", module_desc.GetData())); llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>> index_or = DebugNamesDWARFIndex::Create(*GetObjectFile()->GetModule(), debug_names, @@ -669,9 +683,8 @@ static void MakeAbsoluteAndRemap(FileSpec &file_spec, DWARFUnit &dwarf_cu, // files are NFS mounted. file_spec.MakeAbsolute(dwarf_cu.GetCompilationDirectory()); - std::string remapped_file; - if (module_sp->RemapSourceFile(file_spec.GetPath(), remapped_file)) - file_spec.SetFile(remapped_file, FileSpec::Style::native); + if (auto remapped_file = module_sp->RemapSourceFile(file_spec.GetPath())) + file_spec.SetFile(*remapped_file, FileSpec::Style::native); } lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) { @@ -973,8 +986,7 @@ bool SymbolFileDWARF::ParseImportedModules( if (!die) return false; - for (DWARFDIE child_die = die.GetFirstChild(); child_die; - child_die = child_die.GetSibling()) { + for (DWARFDIE child_die : die.children()) { if (child_die.Tag() != DW_TAG_imported_declaration) continue; @@ -1233,8 +1245,7 @@ size_t SymbolFileDWARF::ParseBlocksRecursive( bool SymbolFileDWARF::ClassOrStructIsVirtual(const DWARFDIE &parent_die) { if (parent_die) { - for (DWARFDIE die = parent_die.GetFirstChild(); die; - die = die.GetSibling()) { + for (DWARFDIE die : parent_die.children()) { dw_tag_t tag = die.Tag(); bool check_virtuality = false; switch (tag) { @@ -1639,6 +1650,13 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit( return nullptr; dwo_file.SetFile(comp_dir, FileSpec::Style::native); + if (dwo_file.IsRelative()) { + // if DW_AT_comp_dir is relative, it should be relative to the location + // of the executable, not to the location from which the debugger was + // launched. + dwo_file.PrependPathComponent( + m_objfile_sp->GetFileSpec().GetDirectory().GetStringRef()); + } FileSystem::Instance().Resolve(dwo_file); dwo_file.AppendPathComponent(dwo_name); } @@ -1784,7 +1802,7 @@ SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() { if (location.Evaluate(nullptr, LLDB_INVALID_ADDRESS, nullptr, nullptr, location_result, &error)) { if (location_result.GetValueType() == - Value::eValueTypeFileAddress) { + Value::ValueType::FileAddress) { lldb::addr_t file_addr = location_result.GetScalar().ULongLong(); lldb::addr_t byte_size = 1; @@ -1850,17 +1868,8 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr, lldb::addr_t file_vm_addr = so_addr.GetFileAddress(); DWARFDebugInfo &debug_info = DebugInfo(); - llvm::Expected<DWARFDebugAranges &> aranges = - debug_info.GetCompileUnitAranges(); - if (!aranges) { - Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO); - LLDB_LOG_ERROR(log, aranges.takeError(), - "SymbolFileDWARF::ResolveSymbolContext failed to get cu " - "aranges. {0}"); - return 0; - } - - const dw_offset_t cu_offset = aranges->FindAddress(file_vm_addr); + const DWARFDebugAranges &aranges = debug_info.GetCompileUnitAranges(); + const dw_offset_t cu_offset = aranges.FindAddress(file_vm_addr); if (cu_offset == DW_INVALID_OFFSET) { // Global variables are not in the compile unit address ranges. The only // way to currently find global variables is to iterate over the @@ -1949,12 +1958,11 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr, return resolved; } -uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec, - uint32_t line, - bool check_inlines, - SymbolContextItem resolve_scope, - SymbolContextList &sc_list) { +uint32_t SymbolFileDWARF::ResolveSymbolContext( + const SourceLocationSpec &src_location_spec, + SymbolContextItem resolve_scope, SymbolContextList &sc_list) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); + const bool check_inlines = src_location_spec.GetCheckInlines(); const uint32_t prev_size = sc_list.GetSize(); if (resolve_scope & eSymbolContextCompUnit) { for (uint32_t cu_idx = 0, num_cus = GetNumCompileUnits(); cu_idx < num_cus; @@ -1963,69 +1971,10 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec, if (!dc_cu) continue; - bool file_spec_matches_cu_file_spec = - FileSpec::Match(file_spec, dc_cu->GetPrimaryFile()); + bool file_spec_matches_cu_file_spec = FileSpec::Match( + src_location_spec.GetFileSpec(), dc_cu->GetPrimaryFile()); if (check_inlines || file_spec_matches_cu_file_spec) { - SymbolContext sc(m_objfile_sp->GetModule()); - sc.comp_unit = dc_cu; - uint32_t file_idx = UINT32_MAX; - - // If we are looking for inline functions only and we don't find it - // in the support files, we are done. - if (check_inlines) { - file_idx = - sc.comp_unit->GetSupportFiles().FindFileIndex(1, file_spec, true); - if (file_idx == UINT32_MAX) - continue; - } - - if (line != 0) { - LineTable *line_table = sc.comp_unit->GetLineTable(); - - if (line_table != nullptr && line != 0) { - // We will have already looked up the file index if we are - // searching for inline entries. - if (!check_inlines) - file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex( - 1, file_spec, true); - - if (file_idx != UINT32_MAX) { - uint32_t found_line; - uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex( - 0, file_idx, line, false, &sc.line_entry); - found_line = sc.line_entry.line; - - while (line_idx != UINT32_MAX) { - sc.function = nullptr; - sc.block = nullptr; - if (resolve_scope & - (eSymbolContextFunction | eSymbolContextBlock)) { - const lldb::addr_t file_vm_addr = - sc.line_entry.range.GetBaseAddress().GetFileAddress(); - if (file_vm_addr != LLDB_INVALID_ADDRESS) { - ResolveFunctionAndBlock( - file_vm_addr, resolve_scope & eSymbolContextBlock, sc); - } - } - - sc_list.Append(sc); - line_idx = line_table->FindLineEntryIndexByFileIndex( - line_idx + 1, file_idx, found_line, true, &sc.line_entry); - } - } - } else if (file_spec_matches_cu_file_spec && !check_inlines) { - // only append the context if we aren't looking for inline call - // sites by file and line and if the file spec matches that of - // the compile unit - sc_list.Append(sc); - } - } else if (file_spec_matches_cu_file_spec && !check_inlines) { - // only append the context if we aren't looking for inline call - // sites by file and line and if the file spec matches that of - // the compile unit - sc_list.Append(sc); - } - + dc_cu->ResolveSymbolContext(src_location_spec, resolve_scope, sc_list); if (!check_inlines) break; } @@ -2462,7 +2411,7 @@ void SymbolFileDWARF::FindTypes( return; m_index->GetTypes(name, [&](DWARFDIE die) { - if (!languages[GetLanguage(*die.GetCU())]) + if (!languages[GetLanguageFamily(*die.GetCU())]) return true; llvm::SmallVector<CompilerContext, 4> die_context; @@ -3126,8 +3075,8 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, continue; switch (attr) { case DW_AT_decl_file: - decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex( - form_value.Unsigned())); + decl.SetFile( + attributes.CompileUnitAtIndex(i)->GetFile(form_value.Unsigned())); break; case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); @@ -3469,8 +3418,7 @@ SymbolFileDWARF::FindBlockContainingSpecification( // Give the concrete function die specified by "func_die_offset", find the // concrete block whose DW_AT_specification or DW_AT_abstract_origin points // to "spec_block_die_offset" - for (DWARFDIE child_die = die.GetFirstChild(); child_die; - child_die = child_die.GetSibling()) { + for (DWARFDIE child_die : die.children()) { DWARFDIE result_die = FindBlockContainingSpecification(child_die, spec_block_die_offset); if (result_die) @@ -3599,8 +3547,7 @@ size_t SymbolFileDWARF::ParseVariables(const SymbolContext &sc, static CallSiteParameterArray CollectCallSiteParameters(ModuleSP module, DWARFDIE call_site_die) { CallSiteParameterArray parameters; - for (DWARFDIE child = call_site_die.GetFirstChild(); child.IsValid(); - child = child.GetSibling()) { + for (DWARFDIE child : call_site_die.children()) { if (child.Tag() != DW_TAG_call_site_parameter && child.Tag() != DW_TAG_GNU_call_site_parameter) continue; @@ -3665,8 +3612,7 @@ SymbolFileDWARF::CollectCallEdges(ModuleSP module, DWARFDIE function_die) { // For now, assume that all entries are nested directly under the subprogram // (this is the kind of DWARF LLVM produces) and parse them eagerly. std::vector<std::unique_ptr<CallEdge>> call_edges; - for (DWARFDIE child = function_die.GetFirstChild(); child.IsValid(); - child = child.GetSibling()) { + for (DWARFDIE child : function_die.children()) { if (child.Tag() != DW_TAG_call_site && child.Tag() != DW_TAG_GNU_call_site) continue; @@ -3842,7 +3788,7 @@ void SymbolFileDWARF::DumpClangAST(Stream &s) { } SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() { - if (m_debug_map_symfile == nullptr && !m_debug_map_module_wp.expired()) { + if (m_debug_map_symfile == nullptr) { lldb::ModuleSP module_sp(m_debug_map_module_wp.lock()); if (module_sp) { m_debug_map_symfile = @@ -3936,3 +3882,10 @@ LanguageType SymbolFileDWARF::LanguageTypeFromDWARF(uint64_t val) { LanguageType SymbolFileDWARF::GetLanguage(DWARFUnit &unit) { return LanguageTypeFromDWARF(unit.GetDWARFLanguageType()); } + +LanguageType SymbolFileDWARF::GetLanguageFamily(DWARFUnit &unit) { + auto lang = (llvm::dwarf::SourceLanguage)unit.GetDWARFLanguageType(); + if (llvm::dwarf::isCPlusPlus(lang)) + lang = DW_LANG_C_plus_plus; + return LanguageTypeFromDWARF(lang); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index 019f76c67c63..d9feeef549ed 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -161,11 +161,10 @@ public: lldb::SymbolContextItem resolve_scope, lldb_private::SymbolContext &sc) override; - uint32_t - ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line, - bool check_inlines, - lldb::SymbolContextItem resolve_scope, - lldb_private::SymbolContextList &sc_list) override; + uint32_t ResolveSymbolContext( + const lldb_private::SourceLocationSpec &src_location_spec, + lldb::SymbolContextItem resolve_scope, + lldb_private::SymbolContextList &sc_list) override; void FindGlobalVariables(lldb_private::ConstString name, @@ -318,6 +317,8 @@ public: static lldb::LanguageType LanguageTypeFromDWARF(uint64_t val); static lldb::LanguageType GetLanguage(DWARFUnit &unit); + /// Same as GetLanguage() but reports all C++ versions as C++ (no version). + static lldb::LanguageType GetLanguageFamily(DWARFUnit &unit); protected: typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *> diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp index fa24f975b073..4e2e5e16637b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -16,7 +16,6 @@ #include "lldb/Host/FileSystem.h" #include "lldb/Utility/RangeMap.h" #include "lldb/Utility/RegularExpression.h" -#include "lldb/Utility/Timer.h" //#define DEBUG_OSO_DMAP // DO NOT CHECKIN WITH THIS NOT COMMENTED OUT #if defined(DEBUG_OSO_DMAP) @@ -34,6 +33,9 @@ #include "LogChannelDWARF.h" #include "SymbolFileDWARF.h" +// Work around the fact that Timer.h pulls in the system Mach-O headers. +#include "lldb/Utility/Timer.h" + #include <memory> using namespace lldb; @@ -246,7 +248,7 @@ SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap(ObjectFileSP objfile_sp) m_func_indexes(), m_glob_indexes(), m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {} -SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap() {} +SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap() = default; void SymbolFileDWARFDebugMap::InitializeObject() {} @@ -806,7 +808,7 @@ SymbolFileDWARFDebugMap::ResolveSymbolContext(const Address &exe_so_addr, } uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext( - const FileSpec &file_spec, uint32_t line, bool check_inlines, + const SourceLocationSpec &src_location_spec, SymbolContextItem resolve_scope, SymbolContextList &sc_list) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); const uint32_t initial = sc_list.GetSize(); @@ -815,18 +817,19 @@ uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext( for (uint32_t i = 0; i < cu_count; ++i) { // If we are checking for inlines, then we need to look through all compile // units no matter if "file_spec" matches. - bool resolve = check_inlines; + bool resolve = src_location_spec.GetCheckInlines(); if (!resolve) { FileSpec so_file_spec; if (GetFileSpecForSO(i, so_file_spec)) - resolve = FileSpec::Match(file_spec, so_file_spec); + resolve = + FileSpec::Match(src_location_spec.GetFileSpec(), so_file_spec); } if (resolve) { SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(i); if (oso_dwarf) - oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines, - resolve_scope, sc_list); + oso_dwarf->ResolveSymbolContext(src_location_spec, resolve_scope, + sc_list); } } return sc_list.GetSize() - initial; diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h index 06f0d48c04ca..8b6624e70869 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -97,11 +97,10 @@ public: uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr, lldb::SymbolContextItem resolve_scope, lldb_private::SymbolContext &sc) override; - uint32_t - ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line, - bool check_inlines, - lldb::SymbolContextItem resolve_scope, - lldb_private::SymbolContextList &sc_list) override; + uint32_t ResolveSymbolContext( + const lldb_private::SourceLocationSpec &src_location_spec, + lldb::SymbolContextItem resolve_scope, + lldb_private::SymbolContextList &sc_list) override; void FindGlobalVariables(lldb_private::ConstString name, const lldb_private::CompilerDeclContext &parent_decl_ctx, @@ -171,18 +170,17 @@ protected: llvm::sys::TimePoint<> oso_mod_time; OSOInfoSP oso_sp; lldb::CompUnitSP compile_unit_sp; - uint32_t first_symbol_index; - uint32_t last_symbol_index; - uint32_t first_symbol_id; - uint32_t last_symbol_id; + uint32_t first_symbol_index = UINT32_MAX; + uint32_t last_symbol_index = UINT32_MAX; + uint32_t first_symbol_id = UINT32_MAX; + uint32_t last_symbol_id = UINT32_MAX; FileRangeMap file_range_map; - bool file_range_map_valid; + bool file_range_map_valid = false; CompileUnitInfo() : so_file(), oso_path(), oso_mod_time(), oso_sp(), compile_unit_sp(), - first_symbol_index(UINT32_MAX), last_symbol_index(UINT32_MAX), - first_symbol_id(UINT32_MAX), last_symbol_id(UINT32_MAX), - file_range_map(), file_range_map_valid(false) {} + + file_range_map() {} const FileRangeMap &GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile); }; @@ -280,8 +278,7 @@ protected: // OSOEntry class OSOEntry { public: - OSOEntry() - : m_exe_sym_idx(UINT32_MAX), m_oso_file_addr(LLDB_INVALID_ADDRESS) {} + OSOEntry() = default; OSOEntry(uint32_t exe_sym_idx, lldb::addr_t oso_file_addr) : m_exe_sym_idx(exe_sym_idx), m_oso_file_addr(oso_file_addr) {} @@ -299,8 +296,8 @@ protected: } protected: - uint32_t m_exe_sym_idx; - lldb::addr_t m_oso_file_addr; + uint32_t m_exe_sym_idx = UINT32_MAX; + lldb::addr_t m_oso_file_addr = LLDB_INVALID_ADDRESS; }; typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, OSOEntry> diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp index 2181989cd37a..34ff23667465 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp @@ -8,7 +8,7 @@ #include "UniqueDWARFASTType.h" -#include "lldb/Symbol/Declaration.h" +#include "lldb/Core/Declaration.h" bool UniqueDWARFASTTypeList::Find(const DWARFDIE &die, const lldb_private::Declaration &decl, diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h index a1b1a3009787..0947d1e581c5 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h @@ -14,16 +14,12 @@ #include "llvm/ADT/DenseMap.h" #include "DWARFDIE.h" -#include "lldb/Symbol/Declaration.h" +#include "lldb/Core/Declaration.h" class UniqueDWARFASTType { public: // Constructors and Destructors - UniqueDWARFASTType() - : m_type_sp(), m_die(), m_declaration(), - m_byte_size( - -1) // Set to negative value to make sure we have a valid value - {} + UniqueDWARFASTType() : m_type_sp(), m_die(), m_declaration() {} UniqueDWARFASTType(lldb::TypeSP &type_sp, const DWARFDIE &die, const lldb_private::Declaration &decl, int32_t byte_size) @@ -34,7 +30,7 @@ public: : m_type_sp(rhs.m_type_sp), m_die(rhs.m_die), m_declaration(rhs.m_declaration), m_byte_size(rhs.m_byte_size) {} - ~UniqueDWARFASTType() {} + ~UniqueDWARFASTType() = default; UniqueDWARFASTType &operator=(const UniqueDWARFASTType &rhs) { if (this != &rhs) { @@ -49,14 +45,14 @@ public: lldb::TypeSP m_type_sp; DWARFDIE m_die; lldb_private::Declaration m_declaration; - int32_t m_byte_size; + int32_t m_byte_size = -1; }; class UniqueDWARFASTTypeList { public: UniqueDWARFASTTypeList() : m_collection() {} - ~UniqueDWARFASTTypeList() {} + ~UniqueDWARFASTTypeList() = default; uint32_t GetSize() { return (uint32_t)m_collection.size(); } @@ -76,7 +72,7 @@ class UniqueDWARFASTTypeMap { public: UniqueDWARFASTTypeMap() : m_collection() {} - ~UniqueDWARFASTTypeMap() {} + ~UniqueDWARFASTTypeMap() = default; void Insert(lldb_private::ConstString name, const UniqueDWARFASTType &entry) { diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp index f25dc84fb342..9f09c0accc87 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp @@ -43,7 +43,7 @@ static bool IsMainFile(llvm::StringRef main, llvm::StringRef other) { llvm::SmallString<64> normalized(other); llvm::sys::path::native(normalized); - return main.equals_lower(normalized); + return main.equals_insensitive(normalized); } static void ParseCompile3(const CVSymbol &sym, CompilandIndexItem &cci) { diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp index 5b4ab78ac219..43cf262016c2 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp @@ -1093,7 +1093,7 @@ void PdbAstBuilder::CreateFunctionParameters(PdbCompilandSymId func_id, } if (!params.empty()) - m_clang.SetFunctionParameters(&function_decl, params.data(), params.size()); + m_clang.SetFunctionParameters(&function_decl, params); } clang::QualType PdbAstBuilder::CreateEnumType(PdbTypeSymId id, diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp index ecae767e4469..4f570d5e6788 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp @@ -41,7 +41,7 @@ static uint32_t ResolveLLDBRegisterNum(llvm::StringRef reg_name, llvm::Triple::A auto it = llvm::find_if( register_names, [®_name](const llvm::EnumEntry<uint16_t> ®ister_entry) { - return reg_name.compare_lower(register_entry.Name) == 0; + return reg_name.compare_insensitive(register_entry.Name) == 0; }); if (it == register_names.end()) diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp index 24b4c64a91bc..b9b075d83b6a 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -256,7 +256,7 @@ SymbolFile *SymbolFileNativePDB::CreateInstance(ObjectFileSP objfile_sp) { SymbolFileNativePDB::SymbolFileNativePDB(ObjectFileSP objfile_sp) : SymbolFile(std::move(objfile_sp)) {} -SymbolFileNativePDB::~SymbolFileNativePDB() {} +SymbolFileNativePDB::~SymbolFileNativePDB() = default; uint32_t SymbolFileNativePDB::CalculateAbilities() { uint32_t abilities = 0; @@ -1001,7 +1001,7 @@ uint32_t SymbolFileNativePDB::ResolveSymbolContext( } uint32_t SymbolFileNativePDB::ResolveSymbolContext( - const FileSpec &file_spec, uint32_t line, bool check_inlines, + const SourceLocationSpec &src_location_spec, lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) { return 0; } @@ -1039,7 +1039,7 @@ static void TerminateLineSequence(LineTable &table, table.AppendLineEntryToSequence(seq.get(), base_addr + block.CodeSize, last_line, 0, file_number, false, false, false, false, true); - table.InsertSequence(seq.release()); + table.InsertSequence(seq.get()); } bool SymbolFileNativePDB::ParseLineTable(CompileUnit &comp_unit) { diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h index 61c1d77164b7..def0995065ca 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h @@ -120,8 +120,7 @@ public: uint32_t ResolveSymbolContext(const Address &so_addr, lldb::SymbolContextItem resolve_scope, SymbolContext &sc) override; - uint32_t ResolveSymbolContext(const FileSpec &file_spec, uint32_t line, - bool check_inlines, + uint32_t ResolveSymbolContext(const SourceLocationSpec &src_location_spec, lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) override; diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp index f9c12e634140..78a0d09a681a 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp @@ -17,8 +17,8 @@ #include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h" #include "Plugins/ExpressionParser/Clang/ClangUtil.h" #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" +#include "lldb/Core/Declaration.h" #include "lldb/Core/Module.h" -#include "lldb/Symbol/Declaration.h" #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/TypeMap.h" #include "lldb/Symbol/TypeSystem.h" @@ -326,7 +326,7 @@ GetDeclFromContextByName(const clang::ASTContext &ast, if (result.empty()) return nullptr; - return result[0]; + return *result.begin(); } static bool IsAnonymousNamespaceName(llvm::StringRef name) { @@ -355,7 +355,7 @@ static clang::CallingConv TranslateCallingConvention(PDB_CallingConv pdb_cc) { PDBASTParser::PDBASTParser(lldb_private::TypeSystemClang &ast) : m_ast(ast) {} -PDBASTParser::~PDBASTParser() {} +PDBASTParser::~PDBASTParser() = default; // DebugInfoASTParser interface @@ -534,8 +534,12 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { auto type_def = llvm::dyn_cast<PDBSymbolTypeTypedef>(&type); assert(type_def); + SymbolFile *symbol_file = m_ast.GetSymbolFile(); + if (!symbol_file) + return nullptr; + lldb_private::Type *target_type = - m_ast.GetSymbolFile()->ResolveTypeUID(type_def->getTypeId()); + symbol_file->ResolveTypeUID(type_def->getTypeId()); if (!target_type) return nullptr; @@ -609,8 +613,13 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { auto arg = arg_enum->getChildAtIndex(arg_idx); if (!arg) break; + + SymbolFile *symbol_file = m_ast.GetSymbolFile(); + if (!symbol_file) + return nullptr; + lldb_private::Type *arg_type = - m_ast.GetSymbolFile()->ResolveTypeUID(arg->getSymIndexId()); + symbol_file->ResolveTypeUID(arg->getSymIndexId()); // If there's some error looking up one of the dependent types of this // function signature, bail. if (!arg_type) @@ -621,8 +630,12 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { lldbassert(arg_list.size() <= num_args); auto pdb_return_type = func_sig->getReturnType(); + SymbolFile *symbol_file = m_ast.GetSymbolFile(); + if (!symbol_file) + return nullptr; + lldb_private::Type *return_type = - m_ast.GetSymbolFile()->ResolveTypeUID(pdb_return_type->getSymIndexId()); + symbol_file->ResolveTypeUID(pdb_return_type->getSymIndexId()); // If there's some error looking up one of the dependent types of this // function signature, bail. if (!return_type) @@ -654,10 +667,13 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { if (uint64_t size = array_type->getLength()) bytes = size; + SymbolFile *symbol_file = m_ast.GetSymbolFile(); + if (!symbol_file) + return nullptr; + // If array rank > 0, PDB gives the element type at N=0. So element type // will parsed in the order N=0, N=1,..., N=rank sequentially. - lldb_private::Type *element_type = - m_ast.GetSymbolFile()->ResolveTypeUID(element_uid); + lldb_private::Type *element_type = symbol_file->ResolveTypeUID(element_uid); if (!element_type) return nullptr; @@ -711,7 +727,12 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { case PDB_SymType::PointerType: { auto *pointer_type = llvm::dyn_cast<PDBSymbolTypePointer>(&type); assert(pointer_type); - Type *pointee_type = m_ast.GetSymbolFile()->ResolveTypeUID( + + SymbolFile *symbol_file = m_ast.GetSymbolFile(); + if (!symbol_file) + return nullptr; + + Type *pointee_type = symbol_file->ResolveTypeUID( pointer_type->getPointeeType()->getSymIndexId()); if (!pointee_type) return nullptr; @@ -719,8 +740,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { if (pointer_type->isPointerToDataMember() || pointer_type->isPointerToMemberFunction()) { auto class_parent_uid = pointer_type->getRawSymbol().getClassParentId(); - auto class_parent_type = - m_ast.GetSymbolFile()->ResolveTypeUID(class_parent_uid); + auto class_parent_type = symbol_file->ResolveTypeUID(class_parent_uid); assert(class_parent_type); CompilerType pointer_ast_type; @@ -950,7 +970,7 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) { } } if (params.size()) - m_ast.SetFunctionParameters(decl, params.data(), params.size()); + m_ast.SetFunctionParameters(decl, params); m_uid_to_decl[sym_id] = decl; diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp index befc08158cea..6b30ad26dca7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -84,8 +84,10 @@ bool ShouldAddLine(uint32_t requested_line, uint32_t actual_line, static bool ShouldUseNativeReader() { #if defined(_WIN32) llvm::StringRef use_native = ::getenv("LLDB_USE_NATIVE_PDB_READER"); - return use_native.equals_lower("on") || use_native.equals_lower("yes") || - use_native.equals_lower("1") || use_native.equals_lower("true"); + return use_native.equals_insensitive("on") || + use_native.equals_insensitive("yes") || + use_native.equals_insensitive("1") || + use_native.equals_insensitive("true"); #else return true; #endif @@ -128,7 +130,7 @@ SymbolFilePDB::CreateInstance(ObjectFileSP objfile_sp) { SymbolFilePDB::SymbolFilePDB(lldb::ObjectFileSP objfile_sp) : SymbolFile(std::move(objfile_sp)), m_session_up(), m_global_scope_up() {} -SymbolFilePDB::~SymbolFilePDB() {} +SymbolFilePDB::~SymbolFilePDB() = default; uint32_t SymbolFilePDB::CalculateAbilities() { uint32_t abilities = 0; @@ -784,10 +786,12 @@ SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr, } uint32_t SymbolFilePDB::ResolveSymbolContext( - const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines, + const lldb_private::SourceLocationSpec &src_location_spec, SymbolContextItem resolve_scope, lldb_private::SymbolContextList &sc_list) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); const size_t old_size = sc_list.GetSize(); + const FileSpec &file_spec = src_location_spec.GetFileSpec(); + const uint32_t line = src_location_spec.GetLine().getValueOr(0); if (resolve_scope & lldb::eSymbolContextCompUnit) { // Locate all compilation units with line numbers referencing the specified // file. For example, if `file_spec` is <vector>, then this should return @@ -806,7 +810,7 @@ uint32_t SymbolFilePDB::ResolveSymbolContext( // this file unless the FileSpec matches. For inline functions, we don't // have to match the FileSpec since they could be defined in headers // other than file specified in FileSpec. - if (!check_inlines) { + if (!src_location_spec.GetCheckInlines()) { std::string source_file = compiland->getSourceFileFullPath(); if (source_file.empty()) continue; @@ -1813,7 +1817,7 @@ bool SymbolFilePDB::ParseCompileUnitLineTable(CompileUnit &comp_unit, sequence.get(), prev_addr + prev_length, prev_line, 0, prev_source_idx, false, false, false, false, true); - line_table->InsertSequence(sequence.release()); + line_table->InsertSequence(sequence.get()); sequence = line_table->CreateLineSequenceContainer(); } diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h index 928cbffc5f63..2171b7f686cc 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -104,11 +104,10 @@ public: lldb::SymbolContextItem resolve_scope, lldb_private::SymbolContext &sc) override; - uint32_t - ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line, - bool check_inlines, - lldb::SymbolContextItem resolve_scope, - lldb_private::SymbolContextList &sc_list) override; + uint32_t ResolveSymbolContext( + const lldb_private::SourceLocationSpec &src_location_spec, + lldb::SymbolContextItem resolve_scope, + lldb_private::SymbolContextList &sc_list) override; void FindGlobalVariables(lldb_private::ConstString name, diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp index 4df5140bd7e1..9130eed63e43 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp @@ -8,7 +8,7 @@ #include "SymbolVendorELF.h" -#include <string.h> +#include <cstring> #include "Plugins/ObjectFile/ELF/ObjectFileELF.h" #include "lldb/Core/Module.h" diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp index 67a1ef5e4e51..2b2840796579 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp @@ -8,7 +8,7 @@ #include "SymbolVendorWasm.h" -#include <string.h> +#include <cstring> #include "Plugins/ObjectFile/wasm/ObjectFileWasm.h" #include "lldb/Core/Module.h" diff --git a/contrib/llvm-project/lldb/source/Target/ThreadTrace.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/common/ThreadPostMortemTrace.cpp index 346f36a737d7..45d6f3b0e098 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadTrace.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/common/ThreadPostMortemTrace.cpp @@ -1,4 +1,4 @@ -//===-- ThreadTrace.cpp ---------------------------------------------------===// +//===-- ThreadPostMortemTrace.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Target/ThreadTrace.h" +#include "ThreadPostMortemTrace.h" #include <memory> @@ -17,9 +17,9 @@ using namespace lldb; using namespace lldb_private; -void ThreadTrace::RefreshStateAfterStop() {} +void ThreadPostMortemTrace::RefreshStateAfterStop() {} -RegisterContextSP ThreadTrace::GetRegisterContext() { +RegisterContextSP ThreadPostMortemTrace::GetRegisterContext() { if (!m_reg_context_sp) m_reg_context_sp = CreateRegisterContextForFrame(nullptr); @@ -27,13 +27,15 @@ RegisterContextSP ThreadTrace::GetRegisterContext() { } RegisterContextSP -ThreadTrace::CreateRegisterContextForFrame(StackFrame *frame) { +ThreadPostMortemTrace::CreateRegisterContextForFrame(StackFrame *frame) { // Eventually this will calculate the register context based on the current // trace position. return std::make_shared<RegisterContextHistory>( *this, 0, GetProcess()->GetAddressByteSize(), LLDB_INVALID_ADDRESS); } -bool ThreadTrace::CalculateStopInfo() { return false; } +bool ThreadPostMortemTrace::CalculateStopInfo() { return false; } -const FileSpec &ThreadTrace::GetTraceFile() const { return m_trace_file; } +const FileSpec &ThreadPostMortemTrace::GetTraceFile() const { + return m_trace_file; +} diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ThreadTrace.h b/contrib/llvm-project/lldb/source/Plugins/Trace/common/ThreadPostMortemTrace.h index a32b33867c26..9cfe754ae0e4 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/ThreadTrace.h +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/common/ThreadPostMortemTrace.h @@ -1,4 +1,4 @@ -//===-- ThreadTrace.h -------------------------------------------*- C++ -*-===// +//===-- ThreadPostMortemTrace.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. @@ -6,21 +6,21 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_TARGET_THREADTRACE_H -#define LLDB_TARGET_THREADTRACE_H +#ifndef LLDB_TARGET_THREADPOSTMORTEMTRACE_H +#define LLDB_TARGET_THREADPOSTMORTEMTRACE_H #include "lldb/Target/Thread.h" namespace lldb_private { -/// \class ThreadTrace ThreadTrace.h +/// \class ThreadPostMortemTrace ThreadPostMortemTrace.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 { +class ThreadPostMortemTrace : public Thread { public: /// \param[in] process /// The process who owns this thread. @@ -28,10 +28,11 @@ public: /// \param[in] tid /// The tid of this thread. /// - /// \param[in] trace_file. + /// \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) + ThreadPostMortemTrace(Process &process, lldb::tid_t tid, + const FileSpec &trace_file) : Thread(process, tid), m_trace_file(trace_file) {} void RefreshStateAfterStop() override; @@ -54,8 +55,6 @@ private: FileSpec m_trace_file; }; -typedef std::shared_ptr<ThreadTrace> ThreadTraceSP; - } // namespace lldb_private -#endif // LLDB_TARGET_THREADTRACE_H +#endif // LLDB_TARGET_THREADPOSTMORTEMTRACE_H diff --git a/contrib/llvm-project/lldb/source/Target/TraceSessionFileParser.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.cpp index 713fadc1eb4f..c88ad9dc6a59 100644 --- a/contrib/llvm-project/lldb/source/Target/TraceSessionFileParser.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.cpp @@ -6,7 +6,8 @@ // //===----------------------------------------------------------------------===/ -#include "lldb/Target/TraceSessionFileParser.h" +#include "TraceSessionFileParser.h" +#include "ThreadPostMortemTrace.h" #include <sstream> @@ -14,7 +15,6 @@ #include "lldb/Core/Module.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" -#include "lldb/Target/ThreadTrace.h" using namespace lldb; using namespace lldb_private; @@ -96,15 +96,16 @@ std::string TraceSessionFileParser::BuildSchema(StringRef plugin_schema) { return schema_builder.str(); } -ThreadTraceSP TraceSessionFileParser::ParseThread(ProcessSP &process_sp, - const JSONThread &thread) { +ThreadPostMortemTraceSP +TraceSessionFileParser::ParseThread(ProcessSP &process_sp, + const JSONThread &thread) { lldb::tid_t tid = static_cast<lldb::tid_t>(thread.tid); FileSpec trace_file(thread.trace_file); NormalizePath(trace_file); - ThreadTraceSP thread_sp = - std::make_shared<ThreadTrace>(*process_sp, tid, trace_file); + ThreadPostMortemTraceSP thread_sp = + std::make_shared<ThreadPostMortemTrace>(*process_sp, tid, trace_file); process_sp->GetThreadList().AddThread(thread_sp); return thread_sp; } diff --git a/contrib/llvm-project/lldb/include/lldb/Target/TraceSessionFileParser.h b/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.h index 52cc27c1a485..6abaffcecd3a 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/TraceSessionFileParser.h +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.h @@ -11,7 +11,7 @@ #include "llvm/Support/JSON.h" -#include "lldb/Target/ThreadTrace.h" +#include "ThreadPostMortemTrace.h" namespace lldb_private { @@ -68,7 +68,7 @@ public: /// Helper struct holding the objects created when parsing a process struct ParsedProcess { lldb::TargetSP target_sp; - std::vector<ThreadTraceSP> threads; + std::vector<lldb::ThreadPostMortemTraceSP> threads; }; TraceSessionFileParser(Debugger &debugger, llvm::StringRef session_file_dir, @@ -103,8 +103,8 @@ protected: /// modifies the given file_spec. void NormalizePath(lldb_private::FileSpec &file_spec); - ThreadTraceSP ParseThread(lldb::ProcessSP &process_sp, - const JSONThread &thread); + lldb::ThreadPostMortemTraceSP ParseThread(lldb::ProcessSP &process_sp, + const JSONThread &thread); llvm::Expected<ParsedProcess> ParseProcess(const JSONProcess &process); diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.cpp index e1758dfcfc41..5650af657c5e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.cpp @@ -8,7 +8,10 @@ #include "CommandObjectTraceStartIntelPT.h" +#include "TraceIntelPT.h" +#include "TraceIntelPTConstants.h" #include "lldb/Host/OptionParser.h" +#include "lldb/Target/Process.h" #include "lldb/Target/Trace.h" using namespace lldb; @@ -16,10 +19,12 @@ using namespace lldb_private; using namespace lldb_private::trace_intel_pt; using namespace llvm; +// CommandObjectThreadTraceStartIntelPT + #define LLDB_OPTIONS_thread_trace_start_intel_pt #include "TraceIntelPTCommandOptions.inc" -Status CommandObjectTraceStartIntelPT::CommandOptions::SetOptionValue( +Status CommandObjectThreadTraceStartIntelPT::CommandOptions::SetOptionValue( uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) { Status error; @@ -27,23 +32,27 @@ Status CommandObjectTraceStartIntelPT::CommandOptions::SetOptionValue( switch (short_option) { case 's': { - int32_t size_in_kb; - if (option_arg.empty() || option_arg.getAsInteger(0, size_in_kb) || - size_in_kb < 0) + int64_t thread_buffer_size; + if (option_arg.empty() || option_arg.getAsInteger(0, thread_buffer_size) || + thread_buffer_size < 0) error.SetErrorStringWithFormat("invalid integer value for option '%s'", option_arg.str().c_str()); else - m_size_in_kb = size_in_kb; + m_thread_buffer_size = thread_buffer_size; + break; + } + case 't': { + m_enable_tsc = true; break; } - case 'c': { - int32_t custom_config; - if (option_arg.empty() || option_arg.getAsInteger(0, custom_config) || - custom_config < 0) + case 'p': { + int64_t psb_period; + if (option_arg.empty() || option_arg.getAsInteger(0, psb_period) || + psb_period < 0) error.SetErrorStringWithFormat("invalid integer value for option '%s'", option_arg.str().c_str()); else - m_custom_config = custom_config; + m_psb_period = psb_period; break; } default: @@ -52,22 +61,104 @@ Status CommandObjectTraceStartIntelPT::CommandOptions::SetOptionValue( return error; } -void CommandObjectTraceStartIntelPT::CommandOptions::OptionParsingStarting( - ExecutionContext *execution_context) { - m_size_in_kb = 4; - m_custom_config = 0; +void CommandObjectThreadTraceStartIntelPT::CommandOptions:: + OptionParsingStarting(ExecutionContext *execution_context) { + m_thread_buffer_size = kDefaultThreadBufferSize; + m_enable_tsc = kDefaultEnableTscValue; + m_psb_period = kDefaultPsbPeriod; } llvm::ArrayRef<OptionDefinition> -CommandObjectTraceStartIntelPT::CommandOptions::GetDefinitions() { +CommandObjectThreadTraceStartIntelPT::CommandOptions::GetDefinitions() { return llvm::makeArrayRef(g_thread_trace_start_intel_pt_options); } -bool CommandObjectTraceStartIntelPT::HandleOneThread( - lldb::tid_t tid, CommandReturnObject &result) { - result.AppendMessageWithFormat( - "would trace tid %" PRIu64 " with size_in_kb %zu and custom_config %d\n", - tid, m_options.m_size_in_kb, m_options.m_custom_config); - result.SetStatus(eReturnStatusSuccessFinishResult); +bool CommandObjectThreadTraceStartIntelPT::DoExecuteOnThreads( + Args &command, CommandReturnObject &result, + llvm::ArrayRef<lldb::tid_t> tids) { + if (Error err = m_trace.Start(tids, m_options.m_thread_buffer_size, + m_options.m_enable_tsc, m_options.m_psb_period)) + result.SetError(Status(std::move(err))); + else + result.SetStatus(eReturnStatusSuccessFinishResult); + + return result.Succeeded(); +} + +/// CommandObjectProcessTraceStartIntelPT + +#define LLDB_OPTIONS_process_trace_start_intel_pt +#include "TraceIntelPTCommandOptions.inc" + +Status CommandObjectProcessTraceStartIntelPT::CommandOptions::SetOptionValue( + uint32_t option_idx, llvm::StringRef option_arg, + ExecutionContext *execution_context) { + Status error; + const int short_option = m_getopt_table[option_idx].val; + + switch (short_option) { + case 's': { + int64_t thread_buffer_size; + if (option_arg.empty() || option_arg.getAsInteger(0, thread_buffer_size) || + thread_buffer_size < 0) + error.SetErrorStringWithFormat("invalid integer value for option '%s'", + option_arg.str().c_str()); + else + m_thread_buffer_size = thread_buffer_size; + break; + } + case 'l': { + int64_t process_buffer_size_limit; + if (option_arg.empty() || + option_arg.getAsInteger(0, process_buffer_size_limit) || + process_buffer_size_limit < 0) + error.SetErrorStringWithFormat("invalid integer value for option '%s'", + option_arg.str().c_str()); + else + m_process_buffer_size_limit = process_buffer_size_limit; + break; + } + case 't': { + m_enable_tsc = true; + break; + } + case 'p': { + int64_t psb_period; + if (option_arg.empty() || option_arg.getAsInteger(0, psb_period) || + psb_period < 0) + error.SetErrorStringWithFormat("invalid integer value for option '%s'", + option_arg.str().c_str()); + else + m_psb_period = psb_period; + break; + } + default: + llvm_unreachable("Unimplemented option"); + } + return error; +} + +void CommandObjectProcessTraceStartIntelPT::CommandOptions:: + OptionParsingStarting(ExecutionContext *execution_context) { + m_thread_buffer_size = kDefaultThreadBufferSize; + m_process_buffer_size_limit = kDefaultProcessBufferSizeLimit; + m_enable_tsc = kDefaultEnableTscValue; + m_psb_period = kDefaultPsbPeriod; +} + +llvm::ArrayRef<OptionDefinition> +CommandObjectProcessTraceStartIntelPT::CommandOptions::GetDefinitions() { + return llvm::makeArrayRef(g_process_trace_start_intel_pt_options); +} + +bool CommandObjectProcessTraceStartIntelPT::DoExecute( + Args &command, CommandReturnObject &result) { + if (Error err = m_trace.Start(m_options.m_thread_buffer_size, + m_options.m_process_buffer_size_limit, + m_options.m_enable_tsc, m_options.m_psb_period)) + result.SetError(Status(std::move(err))); + else + result.SetStatus(eReturnStatusSuccessFinishResult); + return result.Succeeded(); } diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.h index 265569c553fa..2f3d53a86406 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.h +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.h @@ -9,21 +9,21 @@ #ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_COMMANDOBJECTTRACESTARTINTELPT_H #define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_COMMANDOBJECTTRACESTARTINTELPT_H -#include "../../../../source/Commands/CommandObjectThreadUtil.h" +#include "../../../../source/Commands/CommandObjectTrace.h" +#include "TraceIntelPT.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" namespace lldb_private { namespace trace_intel_pt { -class CommandObjectTraceStartIntelPT : public CommandObjectIterateOverThreads { +class CommandObjectThreadTraceStartIntelPT + : public CommandObjectMultipleThreads { public: class CommandOptions : public Options { public: CommandOptions() : Options() { OptionParsingStarting(nullptr); } - ~CommandOptions() override = default; - Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override; @@ -31,31 +31,76 @@ public: llvm::ArrayRef<OptionDefinition> GetDefinitions() override; - size_t m_size_in_kb; - uint32_t m_custom_config; + size_t m_thread_buffer_size; + bool m_enable_tsc; + llvm::Optional<size_t> m_psb_period; }; - CommandObjectTraceStartIntelPT(CommandInterpreter &interpreter) - : CommandObjectIterateOverThreads( + CommandObjectThreadTraceStartIntelPT(TraceIntelPT &trace, + CommandInterpreter &interpreter) + : CommandObjectMultipleThreads( interpreter, "thread trace start", "Start tracing one or more threads with intel-pt. " "Defaults to the current thread. Thread indices can be " "specified as arguments.\n Use the thread-index \"all\" to trace " - "all threads.", + "all threads including future threads.", "thread trace start [<thread-index> <thread-index> ...] " "[<intel-pt-options>]", lldb::eCommandRequiresProcess | lldb::eCommandTryTargetAPILock | lldb::eCommandProcessMustBeLaunched | lldb::eCommandProcessMustBePaused), - m_options() {} + m_trace(trace), m_options() {} + + Options *GetOptions() override { return &m_options; } + +protected: + bool DoExecuteOnThreads(Args &command, CommandReturnObject &result, + llvm::ArrayRef<lldb::tid_t> tids) override; + + TraceIntelPT &m_trace; + CommandOptions m_options; +}; + +class CommandObjectProcessTraceStartIntelPT : public CommandObjectParsed { +public: + class CommandOptions : public Options { + public: + CommandOptions() : Options() { OptionParsingStarting(nullptr); } - ~CommandObjectTraceStartIntelPT() override = default; + Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, + ExecutionContext *execution_context) override; + + void OptionParsingStarting(ExecutionContext *execution_context) override; + + llvm::ArrayRef<OptionDefinition> GetDefinitions() override; + + size_t m_thread_buffer_size; + size_t m_process_buffer_size_limit; + bool m_enable_tsc; + llvm::Optional<size_t> m_psb_period; + }; + + CommandObjectProcessTraceStartIntelPT(TraceIntelPT &trace, + CommandInterpreter &interpreter) + : CommandObjectParsed( + interpreter, "process trace start", + "Start tracing this process with intel-pt, including future " + "threads. " + "This is implemented by tracing each thread independently. " + "Threads traced with the \"thread trace start\" command are left " + "unaffected ant not retraced.", + "process trace start [<intel-pt-options>]", + lldb::eCommandRequiresProcess | lldb::eCommandTryTargetAPILock | + lldb::eCommandProcessMustBeLaunched | + lldb::eCommandProcessMustBePaused), + m_trace(trace), m_options() {} Options *GetOptions() override { return &m_options; } protected: - bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override; + bool DoExecute(Args &command, CommandReturnObject &result) override; + TraceIntelPT &m_trace; CommandOptions m_options; }; diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp index 6b8b06564052..4822a786c68c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp @@ -8,8 +8,13 @@ #include "DecodedThread.h" +#include <intel-pt.h> +#include <memory> + +#include "TraceCursorIntelPT.h" #include "lldb/Utility/StreamString.h" +using namespace lldb; using namespace lldb_private; using namespace lldb_private::trace_intel_pt; using namespace llvm; @@ -30,12 +35,21 @@ void IntelPTError::log(llvm::raw_ostream &OS) const { OS << "error: " << libipt_error_message; } +IntelPTInstruction::IntelPTInstruction(llvm::Error err) { + llvm::handleAllErrors(std::move(err), + [&](std::unique_ptr<llvm::ErrorInfoBase> info) { + m_error = std::move(info); + }); + m_pt_insn.ip = LLDB_INVALID_ADDRESS; + m_pt_insn.iclass = ptic_error; +} + bool IntelPTInstruction::IsError() const { return (bool)m_error; } -Expected<lldb::addr_t> IntelPTInstruction::GetLoadAddress() const { - if (IsError()) - return ToError(); - return m_pt_insn.ip; +lldb::addr_t IntelPTInstruction::GetLoadAddress() const { return m_pt_insn.ip; } + +Optional<uint64_t> IntelPTInstruction::GetTimestampCounter() const { + return m_timestamp; } Error IntelPTInstruction::ToError() const { @@ -47,18 +61,58 @@ Error IntelPTInstruction::ToError() const { return make_error<StringError>(m_error->message(), m_error->convertToErrorCode()); } +size_t DecodedThread::GetRawTraceSize() const { return m_raw_trace_size; } + +TraceInstructionControlFlowType +IntelPTInstruction::GetControlFlowType(lldb::addr_t next_load_address) const { + if (IsError()) + return (TraceInstructionControlFlowType)0; -size_t DecodedThread::GetLastPosition() const { - return m_instructions.empty() ? 0 : m_instructions.size() - 1; + TraceInstructionControlFlowType mask = + eTraceInstructionControlFlowTypeInstruction; + + switch (m_pt_insn.iclass) { + case ptic_cond_jump: + case ptic_jump: + case ptic_far_jump: + mask |= eTraceInstructionControlFlowTypeBranch; + if (m_pt_insn.ip + m_pt_insn.size != next_load_address) + mask |= eTraceInstructionControlFlowTypeTakenBranch; + break; + case ptic_return: + case ptic_far_return: + mask |= eTraceInstructionControlFlowTypeReturn; + break; + case ptic_call: + case ptic_far_call: + mask |= eTraceInstructionControlFlowTypeCall; + break; + default: + break; + } + + return mask; } ArrayRef<IntelPTInstruction> DecodedThread::GetInstructions() const { return makeArrayRef(m_instructions); } -size_t DecodedThread::GetCursorPosition() const { return m_position; } +DecodedThread::DecodedThread(ThreadSP thread_sp, Error error) + : m_thread_sp(thread_sp) { + m_instructions.emplace_back(std::move(error)); +} + +DecodedThread::DecodedThread(ThreadSP thread_sp, + std::vector<IntelPTInstruction> &&instructions, + size_t raw_trace_size) + : m_thread_sp(thread_sp), m_instructions(std::move(instructions)), + m_raw_trace_size(raw_trace_size) { + if (m_instructions.empty()) + m_instructions.emplace_back( + createStringError(inconvertibleErrorCode(), "empty trace")); +} -size_t DecodedThread::SetCursorPosition(size_t new_position) { - m_position = std::min(new_position, GetLastPosition()); - return m_position; +lldb::TraceCursorUP DecodedThread::GetCursor() { + return std::make_unique<TraceCursorIntelPT>(m_thread_sp, shared_from_this()); } diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.h index 3c7e030414cb..592c402cd0e5 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.h +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.h @@ -15,6 +15,7 @@ #include "llvm/Support/Error.h" #include "lldb/Target/Trace.h" +#include "lldb/Utility/TraceIntelPTGDBRemotePackets.h" #include "intel-pt.h" @@ -60,17 +61,15 @@ private: /// As mentioned, any gap is represented as an error in this class. class IntelPTInstruction { public: + IntelPTInstruction(const pt_insn &pt_insn, uint64_t timestamp) + : m_pt_insn(pt_insn), m_timestamp(timestamp) {} + IntelPTInstruction(const pt_insn &pt_insn) : m_pt_insn(pt_insn) {} /// Error constructor /// /// libipt errors should use the underlying \a IntelPTError class. - IntelPTInstruction(llvm::Error err) { - llvm::handleAllErrors(std::move(err), - [&](std::unique_ptr<llvm::ErrorInfoBase> info) { - m_error = std::move(info); - }); - } + IntelPTInstruction(llvm::Error err); /// Check if this object represents an error (i.e. a gap). /// @@ -79,15 +78,34 @@ public: bool IsError() const; /// \return - /// The instruction pointer address, or an \a llvm::Error if it is an - /// error. - llvm::Expected<lldb::addr_t> GetLoadAddress() const; + /// The instruction pointer address, or \a LLDB_INVALID_ADDRESS if it is + /// an error. + lldb::addr_t GetLoadAddress() const; /// \return /// An \a llvm::Error object if this class corresponds to an Error, or an /// \a llvm::Error::success otherwise. llvm::Error ToError() const; + /// Get the timestamp associated with the current instruction. The timestamp + /// is similar to what a rdtsc instruction would return. + /// + /// \return + /// The timestamp or \b llvm::None if not available. + llvm::Optional<uint64_t> GetTimestampCounter() const; + + /// Get the \a lldb::TraceInstructionControlFlowType categories of the + /// instruction. + /// + /// \param[in] next_load_address + /// The address of the next instruction in the trace or \b + /// LLDB_INVALID_ADDRESS if not available. + /// + /// \return + /// The control flow categories, or \b 0 if the instruction is an error. + lldb::TraceInstructionControlFlowType + GetControlFlowType(lldb::addr_t next_load_address) const; + IntelPTInstruction(IntelPTInstruction &&other) = default; private: @@ -95,6 +113,7 @@ private: const IntelPTInstruction &operator=(const IntelPTInstruction &other) = delete; pt_insn m_pt_insn; + llvm::Optional<uint64_t> m_timestamp; std::unique_ptr<llvm::ErrorInfoBase> m_error; }; @@ -105,11 +124,15 @@ private: /// /// Each decoded thread contains a cursor to the current position the user is /// stopped at. See \a Trace::GetCursorPosition for more information. -class DecodedThread { +class DecodedThread : public std::enable_shared_from_this<DecodedThread> { public: - DecodedThread(std::vector<IntelPTInstruction> &&instructions) - : m_instructions(std::move(instructions)), m_position(GetLastPosition()) { - } + DecodedThread(lldb::ThreadSP thread_sp, + std::vector<IntelPTInstruction> &&instructions, + size_t raw_trace_size); + + /// Constructor with a single error signaling a complete failure of the + /// decoding process. + DecodedThread(lldb::ThreadSP thread_sp, llvm::Error error); /// Get the instructions from the decoded trace. Some of them might indicate /// errors (i.e. gaps) in the trace. @@ -118,28 +141,23 @@ public: /// The instructions of the trace. llvm::ArrayRef<IntelPTInstruction> GetInstructions() const; - /// \return - /// The current position of the cursor of this trace, or 0 if there are no - /// instructions. - size_t GetCursorPosition() const; + /// Get a new cursor for the decoded thread. + lldb::TraceCursorUP GetCursor(); - /// Change the position of the cursor of this trace. If this value is to high, - /// the new position will be set as the last instruction of the trace. + /// Get the size in bytes of the corresponding Intel PT raw trace /// /// \return - /// The effective new position. - size_t SetCursorPosition(size_t new_position); - /// \} + /// The size of the trace. + size_t GetRawTraceSize() const; private: - /// \return - /// The index of the last element of the trace, or 0 if empty. - size_t GetLastPosition() const; - + lldb::ThreadSP m_thread_sp; std::vector<IntelPTInstruction> m_instructions; - size_t m_position; + size_t m_raw_trace_size; }; +using DecodedThreadSP = std::shared_ptr<DecodedThread>; + } // namespace trace_intel_pt } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp index b6e8ae808632..3827881454c7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp @@ -1,5 +1,4 @@ -//===-- IntelPTDecoder.cpp --------------------------------------*- C++ -*-===// -// +//===-- IntelPTDecoder.cpp --======----------------------------------------===// // 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 @@ -10,10 +9,13 @@ #include "llvm/Support/MemoryBuffer.h" +#include "../common/ThreadPostMortemTrace.h" +#include "DecodedThread.h" +#include "TraceIntelPT.h" #include "lldb/Core/Module.h" #include "lldb/Core/Section.h" #include "lldb/Target/Target.h" -#include "lldb/Target/ThreadTrace.h" +#include "lldb/Utility/StringExtractor.h" using namespace lldb; using namespace lldb_private; @@ -85,7 +87,7 @@ static int ProcessPTEvents(pt_insn_decoder &decoder, int errcode) { return errcode; } return 0; -}; +} /// Decode all the instructions from a configured decoder. /// The decoding flow is based on @@ -135,7 +137,23 @@ DecodeInstructions(pt_insn_decoder &decoder) { break; } - instructions.emplace_back(insn); + uint64_t time; + int time_error = pt_insn_time(&decoder, &time, nullptr, nullptr); + if (time_error == -pte_invalid) { + // This happens if we invoke the pt_insn_time method incorrectly, + // but the instruction is good though. + instructions.emplace_back( + make_error<IntelPTError>(time_error, insn.ip)); + instructions.emplace_back(insn); + break; + } + if (time_error == -pte_no_time) { + // We simply don't have time information, i.e. None of TSC, MTC or CYC + // was enabled. + instructions.emplace_back(insn); + } else { + instructions.emplace_back(insn, time); + } } } @@ -158,39 +176,26 @@ static int ReadProcessMemory(uint8_t *buffer, size_t size, return bytes_read; } -static std::vector<IntelPTInstruction> makeInstructionListFromError(Error err) { - std::vector<IntelPTInstruction> instructions; - instructions.emplace_back(std::move(err)); - return instructions; -} - -static std::vector<IntelPTInstruction> -CreateDecoderAndDecode(Process &process, const pt_cpu &pt_cpu, - const FileSpec &trace_file) { - ErrorOr<std::unique_ptr<MemoryBuffer>> trace_or_error = - MemoryBuffer::getFile(trace_file.GetPath()); - if (std::error_code err = trace_or_error.getError()) - return makeInstructionListFromError(errorCodeToError(err)); - - MemoryBuffer &trace = **trace_or_error; +static Expected<std::vector<IntelPTInstruction>> +DecodeInMemoryTrace(Process &process, TraceIntelPT &trace_intel_pt, + MutableArrayRef<uint8_t> buffer) { + Expected<pt_cpu> cpu_info = trace_intel_pt.GetCPUInfo(); + if (!cpu_info) + return cpu_info.takeError(); pt_config config; pt_config_init(&config); - config.cpu = pt_cpu; + config.cpu = *cpu_info; if (int errcode = pt_cpu_errata(&config.errata, &config.cpu)) - return makeInstructionListFromError(make_error<IntelPTError>(errcode)); + return make_error<IntelPTError>(errcode); - // The libipt library does not modify the trace buffer, hence the following - // cast is safe. - config.begin = - reinterpret_cast<uint8_t *>(const_cast<char *>(trace.getBufferStart())); - config.end = - reinterpret_cast<uint8_t *>(const_cast<char *>(trace.getBufferEnd())); + config.begin = buffer.data(); + config.end = buffer.data() + buffer.size(); pt_insn_decoder *decoder = pt_insn_alloc_decoder(&config); if (!decoder) - return makeInstructionListFromError(make_error<IntelPTError>(-pte_nomem)); + return make_error<IntelPTError>(-pte_nomem); pt_image *image = pt_insn_get_image(decoder); @@ -204,12 +209,71 @@ CreateDecoderAndDecode(Process &process, const pt_cpu &pt_cpu, return instructions; } -const DecodedThread &ThreadTraceDecoder::Decode() { - if (!m_decoded_thread.hasValue()) { - m_decoded_thread = DecodedThread( - CreateDecoderAndDecode(*m_trace_thread->GetProcess(), m_pt_cpu, - m_trace_thread->GetTraceFile())); - } +static Expected<std::vector<IntelPTInstruction>> +DecodeTraceFile(Process &process, TraceIntelPT &trace_intel_pt, + const FileSpec &trace_file, size_t &raw_trace_size) { + ErrorOr<std::unique_ptr<MemoryBuffer>> trace_or_error = + MemoryBuffer::getFile(trace_file.GetPath()); + if (std::error_code err = trace_or_error.getError()) + return errorCodeToError(err); + + MemoryBuffer &trace = **trace_or_error; + MutableArrayRef<uint8_t> trace_data( + // The libipt library does not modify the trace buffer, hence the + // following cast is safe. + reinterpret_cast<uint8_t *>(const_cast<char *>(trace.getBufferStart())), + trace.getBufferSize()); + raw_trace_size = trace_data.size(); + return DecodeInMemoryTrace(process, trace_intel_pt, trace_data); +} + +static Expected<std::vector<IntelPTInstruction>> +DecodeLiveThread(Thread &thread, TraceIntelPT &trace, size_t &raw_trace_size) { + Expected<std::vector<uint8_t>> buffer = + trace.GetLiveThreadBuffer(thread.GetID()); + if (!buffer) + return buffer.takeError(); + raw_trace_size = buffer->size(); + if (Expected<pt_cpu> cpu_info = trace.GetCPUInfo()) + return DecodeInMemoryTrace(*thread.GetProcess(), trace, + MutableArrayRef<uint8_t>(*buffer)); + else + return cpu_info.takeError(); +} +DecodedThreadSP ThreadDecoder::Decode() { + if (!m_decoded_thread.hasValue()) + m_decoded_thread = DoDecode(); return *m_decoded_thread; } + +PostMortemThreadDecoder::PostMortemThreadDecoder( + const lldb::ThreadPostMortemTraceSP &trace_thread, TraceIntelPT &trace) + : m_trace_thread(trace_thread), m_trace(trace) {} + +DecodedThreadSP PostMortemThreadDecoder::DoDecode() { + size_t raw_trace_size = 0; + if (Expected<std::vector<IntelPTInstruction>> instructions = + DecodeTraceFile(*m_trace_thread->GetProcess(), m_trace, + m_trace_thread->GetTraceFile(), raw_trace_size)) + return std::make_shared<DecodedThread>(m_trace_thread->shared_from_this(), + std::move(*instructions), + raw_trace_size); + else + return std::make_shared<DecodedThread>(m_trace_thread->shared_from_this(), + instructions.takeError()); +} + +LiveThreadDecoder::LiveThreadDecoder(Thread &thread, TraceIntelPT &trace) + : m_thread_sp(thread.shared_from_this()), m_trace(trace) {} + +DecodedThreadSP LiveThreadDecoder::DoDecode() { + size_t raw_trace_size = 0; + if (Expected<std::vector<IntelPTInstruction>> instructions = + DecodeLiveThread(*m_thread_sp, m_trace, raw_trace_size)) + return std::make_shared<DecodedThread>( + m_thread_sp, std::move(*instructions), raw_trace_size); + else + return std::make_shared<DecodedThread>(m_thread_sp, + instructions.takeError()); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.h index 2e67f9bf6da7..e969db579e52 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.h +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.h @@ -12,38 +12,73 @@ #include "intel-pt.h" #include "DecodedThread.h" +#include "forward-declarations.h" #include "lldb/Target/Process.h" #include "lldb/Utility/FileSpec.h" namespace lldb_private { namespace trace_intel_pt { -/// \a lldb_private::ThreadTrace decoder that stores the output from decoding, -/// avoiding recomputations, as decoding is expensive. -class ThreadTraceDecoder { +/// Base class that handles the decoding of a thread and caches the result. +class ThreadDecoder { public: - /// \param[in] trace_thread - /// The thread whose trace file will be decoded. + virtual ~ThreadDecoder() = default; + + ThreadDecoder() = default; + + /// Decode the thread and store the result internally, to avoid + /// recomputations. /// - /// \param[in] pt_cpu - /// The libipt cpu used when recording the trace. - ThreadTraceDecoder(const std::shared_ptr<ThreadTrace> &trace_thread, - const pt_cpu &pt_cpu) - : m_trace_thread(trace_thread), m_pt_cpu(pt_cpu), m_decoded_thread() {} + /// \return + /// A \a DecodedThread instance. + DecodedThreadSP Decode(); - /// Decode the thread and store the result internally. + ThreadDecoder(const ThreadDecoder &other) = delete; + ThreadDecoder &operator=(const ThreadDecoder &other) = delete; + +protected: + /// Decode the thread. /// /// \return /// A \a DecodedThread instance. - const DecodedThread &Decode(); + virtual DecodedThreadSP DoDecode() = 0; + + llvm::Optional<DecodedThreadSP> m_decoded_thread; +}; + +/// Decoder implementation for \a lldb_private::ThreadPostMortemTrace, which are +/// non-live processes that come trace session files. +class PostMortemThreadDecoder : public ThreadDecoder { +public: + /// \param[in] trace_thread + /// The thread whose trace file will be decoded. + /// + /// \param[in] trace + /// The main Trace object who owns this decoder and its data. + PostMortemThreadDecoder(const lldb::ThreadPostMortemTraceSP &trace_thread, + TraceIntelPT &trace); + +private: + DecodedThreadSP DoDecode() override; + + lldb::ThreadPostMortemTraceSP m_trace_thread; + TraceIntelPT &m_trace; +}; + +class LiveThreadDecoder : public ThreadDecoder { +public: + /// \param[in] thread + /// The thread whose traces will be decoded. + /// + /// \param[in] trace + /// The main Trace object who owns this decoder and its data. + LiveThreadDecoder(Thread &thread, TraceIntelPT &trace); private: - ThreadTraceDecoder(const ThreadTraceDecoder &other) = delete; - ThreadTraceDecoder &operator=(const ThreadTraceDecoder &other) = delete; + DecodedThreadSP DoDecode() override; - std::shared_ptr<ThreadTrace> m_trace_thread; - pt_cpu m_pt_cpu; - llvm::Optional<DecodedThread> m_decoded_thread; + lldb::ThreadSP m_thread_sp; + TraceIntelPT &m_trace; }; } // namespace trace_intel_pt diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.cpp new file mode 100644 index 000000000000..edefdd0d3486 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.cpp @@ -0,0 +1,100 @@ +//===-- TraceCursorIntelPT.cpp --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "TraceCursorIntelPT.h" +#include "DecodedThread.h" +#include "TraceIntelPT.h" + +#include <cstdlib> + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::trace_intel_pt; +using namespace llvm; + +TraceCursorIntelPT::TraceCursorIntelPT(ThreadSP thread_sp, + DecodedThreadSP decoded_thread_sp) + : TraceCursor(thread_sp), m_decoded_thread_sp(decoded_thread_sp) { + assert(!m_decoded_thread_sp->GetInstructions().empty() && + "a trace should have at least one instruction or error"); + m_pos = m_decoded_thread_sp->GetInstructions().size() - 1; +} + +size_t TraceCursorIntelPT::GetInternalInstructionSize() { + return m_decoded_thread_sp->GetInstructions().size(); +} + +bool TraceCursorIntelPT::Next() { + auto canMoveOne = [&]() { + if (IsForwards()) + return m_pos + 1 < GetInternalInstructionSize(); + return m_pos > 0; + }; + + size_t initial_pos = m_pos; + + while (canMoveOne()) { + m_pos += IsForwards() ? 1 : -1; + if (!m_ignore_errors && IsError()) + return true; + if (GetInstructionControlFlowType() & m_granularity) + return true; + } + + // Didn't find any matching instructions + m_pos = initial_pos; + return false; +} + +size_t TraceCursorIntelPT::Seek(int64_t offset, SeekType origin) { + int64_t last_index = GetInternalInstructionSize() - 1; + + auto fitPosToBounds = [&](int64_t raw_pos) -> int64_t { + return std::min(std::max((int64_t)0, raw_pos), last_index); + }; + + switch (origin) { + case TraceCursor::SeekType::Set: + m_pos = fitPosToBounds(offset); + return m_pos; + case TraceCursor::SeekType::End: + m_pos = fitPosToBounds(offset + last_index); + return last_index - m_pos; + case TraceCursor::SeekType::Current: + int64_t new_pos = fitPosToBounds(offset + m_pos); + int64_t dist = m_pos - new_pos; + m_pos = new_pos; + return std::abs(dist); + } +} + +bool TraceCursorIntelPT::IsError() { + return m_decoded_thread_sp->GetInstructions()[m_pos].IsError(); +} + +Error TraceCursorIntelPT::GetError() { + return m_decoded_thread_sp->GetInstructions()[m_pos].ToError(); +} + +lldb::addr_t TraceCursorIntelPT::GetLoadAddress() { + return m_decoded_thread_sp->GetInstructions()[m_pos].GetLoadAddress(); +} + +Optional<uint64_t> TraceCursorIntelPT::GetTimestampCounter() { + return m_decoded_thread_sp->GetInstructions()[m_pos].GetTimestampCounter(); +} + +TraceInstructionControlFlowType +TraceCursorIntelPT::GetInstructionControlFlowType() { + lldb::addr_t next_load_address = + m_pos + 1 < GetInternalInstructionSize() + ? m_decoded_thread_sp->GetInstructions()[m_pos + 1].GetLoadAddress() + : LLDB_INVALID_ADDRESS; + return m_decoded_thread_sp->GetInstructions()[m_pos].GetControlFlowType( + next_load_address); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.h new file mode 100644 index 000000000000..29d3792bb489 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.h @@ -0,0 +1,50 @@ +//===-- TraceCursorIntelPT.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_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACECURSORINTELPT_H +#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACECURSORINTELPT_H + +#include "IntelPTDecoder.h" +#include "TraceIntelPTSessionFileParser.h" + +namespace lldb_private { +namespace trace_intel_pt { + +class TraceCursorIntelPT : public TraceCursor { +public: + TraceCursorIntelPT(lldb::ThreadSP thread_sp, + DecodedThreadSP decoded_thread_sp); + + size_t Seek(int64_t offset, SeekType origin) override; + + virtual bool Next() override; + + llvm::Error GetError() override; + + lldb::addr_t GetLoadAddress() override; + + llvm::Optional<uint64_t> GetTimestampCounter() override; + + lldb::TraceInstructionControlFlowType + GetInstructionControlFlowType() override; + + bool IsError() override; + +private: + size_t GetInternalInstructionSize(); + + /// Storage of the actual instructions + DecodedThreadSP m_decoded_thread_sp; + /// Internal instruction index currently pointing at. + size_t m_pos; +}; + +} // namespace trace_intel_pt +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACECURSORINTELPT_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp index 63a8b2dff4a7..c12bcd3523e3 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp @@ -8,12 +8,14 @@ #include "TraceIntelPT.h" +#include "../common/ThreadPostMortemTrace.h" #include "CommandObjectTraceStartIntelPT.h" +#include "DecodedThread.h" +#include "TraceIntelPTConstants.h" #include "TraceIntelPTSessionFileParser.h" #include "lldb/Core/PluginManager.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" -#include "lldb/Target/ThreadTrace.h" using namespace lldb; using namespace lldb_private; @@ -22,18 +24,27 @@ using namespace llvm; LLDB_PLUGIN_DEFINE(TraceIntelPT) -CommandObjectSP GetStartCommand(CommandInterpreter &interpreter) { - return CommandObjectSP(new CommandObjectTraceStartIntelPT(interpreter)); +lldb::CommandObjectSP +TraceIntelPT::GetProcessTraceStartCommand(CommandInterpreter &interpreter) { + return CommandObjectSP( + new CommandObjectProcessTraceStartIntelPT(*this, interpreter)); +} + +lldb::CommandObjectSP +TraceIntelPT::GetThreadTraceStartCommand(CommandInterpreter &interpreter) { + return CommandObjectSP( + new CommandObjectThreadTraceStartIntelPT(*this, interpreter)); } void TraceIntelPT::Initialize() { - PluginManager::RegisterPlugin( - GetPluginNameStatic(), "Intel Processor Trace", CreateInstance, - TraceIntelPTSessionFileParser::GetSchema(), GetStartCommand); + PluginManager::RegisterPlugin(GetPluginNameStatic(), "Intel Processor Trace", + CreateInstanceForSessionFile, + CreateInstanceForLiveProcess, + TraceIntelPTSessionFileParser::GetSchema()); } void TraceIntelPT::Terminate() { - PluginManager::UnregisterPlugin(CreateInstance); + PluginManager::UnregisterPlugin(CreateInstanceForSessionFile); } ConstString TraceIntelPT::GetPluginNameStatic() { @@ -55,60 +66,278 @@ uint32_t TraceIntelPT::GetPluginVersion() { return 1; } void TraceIntelPT::Dump(Stream *s) const {} -Expected<TraceSP> -TraceIntelPT::CreateInstance(const json::Value &trace_session_file, - StringRef session_file_dir, Debugger &debugger) { +Expected<TraceSP> TraceIntelPT::CreateInstanceForSessionFile( + const json::Value &trace_session_file, StringRef session_file_dir, + Debugger &debugger) { return TraceIntelPTSessionFileParser(debugger, trace_session_file, session_file_dir) .Parse(); } +Expected<TraceSP> TraceIntelPT::CreateInstanceForLiveProcess(Process &process) { + TraceSP instance(new TraceIntelPT(process)); + process.GetTarget().SetTrace(instance); + return instance; +} + TraceIntelPT::TraceIntelPT( - const pt_cpu &pt_cpu, - const std::vector<std::shared_ptr<ThreadTrace>> &traced_threads) - : m_pt_cpu(pt_cpu) { - for (const std::shared_ptr<ThreadTrace> &thread : traced_threads) - m_trace_threads.emplace( - std::piecewise_construct, - std::forward_as_tuple(thread->GetProcess()->GetID(), thread->GetID()), - std::forward_as_tuple(thread, pt_cpu)); -} - -const DecodedThread *TraceIntelPT::Decode(const Thread &thread) { - auto it = m_trace_threads.find( - std::make_pair(thread.GetProcess()->GetID(), thread.GetID())); - if (it == m_trace_threads.end()) - return nullptr; - return &it->second.Decode(); -} - -size_t TraceIntelPT::GetCursorPosition(const Thread &thread) { - const DecodedThread *decoded_thread = Decode(thread); - if (!decoded_thread) - return 0; - return decoded_thread->GetCursorPosition(); -} - -void TraceIntelPT::TraverseInstructions( - const Thread &thread, size_t position, TraceDirection direction, - std::function<bool(size_t index, Expected<lldb::addr_t> load_addr)> - callback) { - const DecodedThread *decoded_thread = Decode(thread); - if (!decoded_thread) - return; + const pt_cpu &cpu_info, + const std::vector<ThreadPostMortemTraceSP> &traced_threads) + : m_cpu_info(cpu_info) { + for (const ThreadPostMortemTraceSP &thread : traced_threads) + m_thread_decoders.emplace( + thread.get(), std::make_unique<PostMortemThreadDecoder>(thread, *this)); +} + +DecodedThreadSP TraceIntelPT::Decode(Thread &thread) { + RefreshLiveProcessState(); + if (m_live_refresh_error.hasValue()) + return std::make_shared<DecodedThread>( + thread.shared_from_this(), + createStringError(inconvertibleErrorCode(), *m_live_refresh_error)); + + auto it = m_thread_decoders.find(&thread); + if (it == m_thread_decoders.end()) + return std::make_shared<DecodedThread>( + thread.shared_from_this(), + createStringError(inconvertibleErrorCode(), "thread not traced")); + return it->second->Decode(); +} - ArrayRef<IntelPTInstruction> instructions = decoded_thread->GetInstructions(); +lldb::TraceCursorUP TraceIntelPT::GetCursor(Thread &thread) { + return Decode(thread)->GetCursor(); +} - ssize_t delta = direction == TraceDirection::Forwards ? 1 : -1; - for (ssize_t i = position; i < (ssize_t)instructions.size() && i >= 0; - i += delta) - if (!callback(i, instructions[i].GetLoadAddress())) - break; +void TraceIntelPT::DumpTraceInfo(Thread &thread, Stream &s, bool verbose) { + Optional<size_t> raw_size = GetRawTraceSize(thread); + s.Printf("\nthread #%u: tid = %" PRIu64, thread.GetIndexID(), thread.GetID()); + if (!raw_size) { + s.Printf(", not traced\n"); + return; + } + s.Printf("\n Raw trace size: %zu bytes\n", *raw_size); + return; } -size_t TraceIntelPT::GetInstructionCount(const Thread &thread) { - if (const DecodedThread *decoded_thread = Decode(thread)) - return decoded_thread->GetInstructions().size(); +Optional<size_t> TraceIntelPT::GetRawTraceSize(Thread &thread) { + if (IsTraced(thread)) + return Decode(thread)->GetRawTraceSize(); else - return 0; + return None; +} + +Expected<pt_cpu> TraceIntelPT::GetCPUInfoForLiveProcess() { + Expected<std::vector<uint8_t>> cpu_info = GetLiveProcessBinaryData("cpuInfo"); + if (!cpu_info) + return cpu_info.takeError(); + + int64_t cpu_family = -1; + int64_t model = -1; + int64_t stepping = -1; + std::string vendor_id; + + StringRef rest(reinterpret_cast<const char *>(cpu_info->data()), + cpu_info->size()); + while (!rest.empty()) { + StringRef line; + std::tie(line, rest) = rest.split('\n'); + + SmallVector<StringRef, 2> columns; + line.split(columns, StringRef(":"), -1, false); + + if (columns.size() < 2) + continue; // continue searching + + columns[1] = columns[1].trim(" "); + if (columns[0].contains("cpu family") && + columns[1].getAsInteger(10, cpu_family)) + continue; + + else if (columns[0].contains("model") && columns[1].getAsInteger(10, model)) + continue; + + else if (columns[0].contains("stepping") && + columns[1].getAsInteger(10, stepping)) + continue; + + else if (columns[0].contains("vendor_id")) { + vendor_id = columns[1].str(); + if (!vendor_id.empty()) + continue; + } + + if ((cpu_family != -1) && (model != -1) && (stepping != -1) && + (!vendor_id.empty())) { + return pt_cpu{vendor_id == "GenuineIntel" ? pcv_intel : pcv_unknown, + static_cast<uint16_t>(cpu_family), + static_cast<uint8_t>(model), + static_cast<uint8_t>(stepping)}; + } + } + return createStringError(inconvertibleErrorCode(), + "Failed parsing the target's /proc/cpuinfo file"); +} + +Expected<pt_cpu> TraceIntelPT::GetCPUInfo() { + if (!m_cpu_info) { + if (llvm::Expected<pt_cpu> cpu_info = GetCPUInfoForLiveProcess()) + m_cpu_info = *cpu_info; + else + return cpu_info.takeError(); + } + return *m_cpu_info; +} + +void TraceIntelPT::DoRefreshLiveProcessState( + Expected<TraceGetStateResponse> state) { + m_thread_decoders.clear(); + + if (!state) { + m_live_refresh_error = toString(state.takeError()); + return; + } + + for (const TraceThreadState &thread_state : state->tracedThreads) { + Thread &thread = + *m_live_process->GetThreadList().FindThreadByID(thread_state.tid); + m_thread_decoders.emplace( + &thread, std::make_unique<LiveThreadDecoder>(thread, *this)); + } +} + +bool TraceIntelPT::IsTraced(const Thread &thread) { + RefreshLiveProcessState(); + return m_thread_decoders.count(&thread); +} + +// The information here should match the description of the intel-pt section +// of the jLLDBTraceStart packet in the lldb/docs/lldb-gdb-remote.txt +// documentation file. Similarly, it should match the CLI help messages of the +// TraceIntelPTOptions.td file. +const char *TraceIntelPT::GetStartConfigurationHelp() { + return R"(Parameters: + + Note: If a parameter is not specified, a default value will be used. + + - int threadBufferSize (defaults to 4096 bytes): + [process and thread tracing] + Trace size in bytes per thread. It must be a power of 2 greater + than or equal to 4096 (2^12). The trace is circular keeping the + the most recent data. + + - boolean enableTsc (default to false): + [process and thread tracing] + Whether to use enable TSC timestamps or not. This is supported on + all devices that support intel-pt. + + - psbPeriod (defaults to null): + [process and thread tracing] + This value defines the period in which PSB packets will be generated. + A PSB packet is a synchronization packet that contains a TSC + timestamp and the current absolute instruction pointer. + + This parameter can only be used if + + /sys/bus/event_source/devices/intel_pt/caps/psb_cyc + + is 1. Otherwise, the PSB period will be defined by the processor. + + If supported, valid values for this period can be found in + + /sys/bus/event_source/devices/intel_pt/caps/psb_periods + + which contains a hexadecimal number, whose bits represent + valid values e.g. if bit 2 is set, then value 2 is valid. + + The psb_period value is converted to the approximate number of + raw trace bytes between PSB packets as: + + 2 ^ (value + 11) + + e.g. value 3 means 16KiB between PSB packets. Defaults to 0 if + supported. + + - int processBufferSizeLimit (defaults to 500 MB): + [process tracing only] + Maximum total trace size per process in bytes. This limit applies + to the sum of the sizes of all thread traces of this process, + excluding the ones created explicitly with "thread tracing". + Whenever a thread is attempted to be traced due to this command + and the limit would be reached, the process is stopped with a + "processor trace" reason, so that the user can retrace the process + if needed.)"; +} + +Error TraceIntelPT::Start(size_t thread_buffer_size, + size_t total_buffer_size_limit, bool enable_tsc, + Optional<size_t> psb_period) { + TraceIntelPTStartRequest request; + request.threadBufferSize = thread_buffer_size; + request.processBufferSizeLimit = total_buffer_size_limit; + request.enableTsc = enable_tsc; + request.psbPeriod = psb_period.map([](size_t val) { return (int64_t)val; }); + request.type = GetPluginName().AsCString(); + return Trace::Start(toJSON(request)); +} + +Error TraceIntelPT::Start(StructuredData::ObjectSP configuration) { + size_t thread_buffer_size = kDefaultThreadBufferSize; + size_t process_buffer_size_limit = kDefaultProcessBufferSizeLimit; + bool enable_tsc = kDefaultEnableTscValue; + Optional<size_t> psb_period = kDefaultPsbPeriod; + + if (configuration) { + if (StructuredData::Dictionary *dict = configuration->GetAsDictionary()) { + dict->GetValueForKeyAsInteger("threadBufferSize", thread_buffer_size); + dict->GetValueForKeyAsInteger("processBufferSizeLimit", + process_buffer_size_limit); + dict->GetValueForKeyAsBoolean("enableTsc", enable_tsc); + dict->GetValueForKeyAsInteger("psbPeriod", psb_period); + } else { + return createStringError(inconvertibleErrorCode(), + "configuration object is not a dictionary"); + } + } + + return Start(thread_buffer_size, process_buffer_size_limit, enable_tsc, + psb_period); +} + +llvm::Error TraceIntelPT::Start(llvm::ArrayRef<lldb::tid_t> tids, + size_t thread_buffer_size, bool enable_tsc, + Optional<size_t> psb_period) { + TraceIntelPTStartRequest request; + request.threadBufferSize = thread_buffer_size; + request.enableTsc = enable_tsc; + request.psbPeriod = psb_period.map([](size_t val) { return (int64_t)val; }); + request.type = GetPluginName().AsCString(); + request.tids.emplace(); + for (lldb::tid_t tid : tids) + request.tids->push_back(tid); + return Trace::Start(toJSON(request)); +} + +Error TraceIntelPT::Start(llvm::ArrayRef<lldb::tid_t> tids, + StructuredData::ObjectSP configuration) { + size_t thread_buffer_size = kDefaultThreadBufferSize; + bool enable_tsc = kDefaultEnableTscValue; + Optional<size_t> psb_period = kDefaultPsbPeriod; + + if (configuration) { + if (StructuredData::Dictionary *dict = configuration->GetAsDictionary()) { + dict->GetValueForKeyAsInteger("threadBufferSize", thread_buffer_size); + dict->GetValueForKeyAsBoolean("enableTsc", enable_tsc); + dict->GetValueForKeyAsInteger("psbPeriod", psb_period); + } else { + return createStringError(inconvertibleErrorCode(), + "configuration object is not a dictionary"); + } + } + + return Start(tids, thread_buffer_size, enable_tsc, psb_period); +} + +Expected<std::vector<uint8_t>> +TraceIntelPT::GetLiveThreadBuffer(lldb::tid_t tid) { + return Trace::GetLiveThreadBinaryData(tid, "threadTraceBuffer"); } diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h index 5058e6fd32f2..e3b247112ae1 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h @@ -45,49 +45,134 @@ public: /// \return /// A trace instance or an error in case of failures. static llvm::Expected<lldb::TraceSP> - CreateInstance(const llvm::json::Value &trace_session_file, - llvm::StringRef session_file_dir, Debugger &debugger); + CreateInstanceForSessionFile(const llvm::json::Value &trace_session_file, + llvm::StringRef session_file_dir, + Debugger &debugger); + + static llvm::Expected<lldb::TraceSP> + CreateInstanceForLiveProcess(Process &process); static ConstString GetPluginNameStatic(); uint32_t GetPluginVersion() override; /// \} + lldb::CommandObjectSP + GetProcessTraceStartCommand(CommandInterpreter &interpreter) override; + + lldb::CommandObjectSP + GetThreadTraceStartCommand(CommandInterpreter &interpreter) override; + llvm::StringRef GetSchema() override; - void TraverseInstructions( - const Thread &thread, size_t position, TraceDirection direction, - std::function<bool(size_t index, llvm::Expected<lldb::addr_t> load_addr)> - callback) override; + lldb::TraceCursorUP GetCursor(Thread &thread) override; + + void DumpTraceInfo(Thread &thread, Stream &s, bool verbose) override; + + llvm::Optional<size_t> GetRawTraceSize(Thread &thread); + + void DoRefreshLiveProcessState( + llvm::Expected<TraceGetStateResponse> state) override; + + bool IsTraced(const Thread &thread) override; + + const char *GetStartConfigurationHelp() override; + + /// Start tracing a live process. + /// + /// \param[in] thread_buffer_size + /// Trace size per thread in bytes. + /// + /// \param[in] total_buffer_size_limit + /// Maximum total trace size per process in bytes. + /// More information in TraceIntelPT::GetStartConfigurationHelp(). + /// + /// \param[in] enable_tsc + /// Whether to use enable TSC timestamps or not. + /// More information in TraceIntelPT::GetStartConfigurationHelp(). + /// + /// \param[in] psb_period + /// + /// This value defines the period in which PSB packets will be generated. + /// More information in TraceIntelPT::GetStartConfigurationHelp(); + /// + /// \return + /// \a llvm::Error::success if the operation was successful, or + /// \a llvm::Error otherwise. + llvm::Error Start(size_t thread_buffer_size, size_t total_buffer_size_limit, + bool enable_tsc, llvm::Optional<size_t> psb_period); + + /// \copydoc Trace::Start + llvm::Error Start(StructuredData::ObjectSP configuration = + StructuredData::ObjectSP()) override; - size_t GetInstructionCount(const Thread &thread) override; + /// Start tracing live threads. + /// + /// \param[in] tids + /// Threads to trace. + /// + /// \param[in] thread_buffer_size + /// Trace size per thread in bytes. + /// + /// \param[in] enable_tsc + /// Whether to use enable TSC timestamps or not. + /// More information in TraceIntelPT::GetStartConfigurationHelp(). + /// + /// \param[in] psb_period + /// + /// This value defines the period in which PSB packets will be generated. + /// More information in TraceIntelPT::GetStartConfigurationHelp(). + /// + /// \return + /// \a llvm::Error::success if the operation was successful, or + /// \a llvm::Error otherwise. + llvm::Error Start(llvm::ArrayRef<lldb::tid_t> tids, size_t thread_buffer_size, + bool enable_tsc, llvm::Optional<size_t> psb_period); + + /// \copydoc Trace::Start + llvm::Error Start(llvm::ArrayRef<lldb::tid_t> tids, + StructuredData::ObjectSP configuration = + StructuredData::ObjectSP()) override; + + /// Get the thread buffer content for a live thread + llvm::Expected<std::vector<uint8_t>> GetLiveThreadBuffer(lldb::tid_t tid); - size_t GetCursorPosition(const Thread &thread) override; + llvm::Expected<pt_cpu> GetCPUInfo(); private: friend class TraceIntelPTSessionFileParser; + llvm::Expected<pt_cpu> GetCPUInfoForLiveProcess(); + /// \param[in] trace_threads /// ThreadTrace instances, which are not live-processes and whose trace /// files are fixed. - TraceIntelPT(const pt_cpu &pt_cpu, - const std::vector<std::shared_ptr<ThreadTrace>> &traced_threads); + TraceIntelPT( + const pt_cpu &cpu_info, + const std::vector<lldb::ThreadPostMortemTraceSP> &traced_threads); + + /// Constructor for live processes + TraceIntelPT(Process &live_process) + : Trace(live_process), m_thread_decoders(){}; /// Decode the trace of the given thread that, i.e. recontruct the traced - /// instructions. That trace must be managed by this class. + /// instructions. /// /// \param[in] thread /// If \a thread is a \a ThreadTrace, then its internal trace file will be /// decoded. Live threads are not currently supported. /// /// \return - /// A \a DecodedThread instance if decoding was successful, or a \b - /// nullptr if the thread's trace is not managed by this class. - const DecodedThread *Decode(const Thread &thread); - - pt_cpu m_pt_cpu; - std::map<std::pair<lldb::pid_t, lldb::tid_t>, ThreadTraceDecoder> - m_trace_threads; + /// A \a DecodedThread shared pointer with the decoded instructions. Any + /// errors are embedded in the instruction list. + DecodedThreadSP Decode(Thread &thread); + + /// It is provided by either a session file or a live process' "cpuInfo" + /// binary data. + llvm::Optional<pt_cpu> m_cpu_info; + std::map<const Thread *, std::unique_ptr<ThreadDecoder>> m_thread_decoders; + /// Error gotten after a failed live process update, if any. + llvm::Optional<std::string> m_live_refresh_error; }; } // namespace trace_intel_pt diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTConstants.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTConstants.h new file mode 100644 index 000000000000..c2bc1b57b2bd --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTConstants.h @@ -0,0 +1,27 @@ +//===-- TraceIntelPTConstants.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_SOURCE_PLUGINS_TRACE_INTEL_PT_CONSTANTS_H +#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_CONSTANTS_H + +#include <cstddef> + +#include <llvm/ADT/Optional.h> + +namespace lldb_private { +namespace trace_intel_pt { + +const size_t kDefaultThreadBufferSize = 4 * 1024; // 4KB +const size_t kDefaultProcessBufferSizeLimit = 5 * 1024 * 1024; // 500MB +const bool kDefaultEnableTscValue = false; +const llvm::Optional<size_t> kDefaultPsbPeriod = llvm::None; + +} // namespace trace_intel_pt +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_CONSTANTS_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td index 6ffe949dbe7b..9e8cab1ee5c4 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td @@ -1,16 +1,74 @@ include "../../../../source/Commands/OptionsBase.td" +// The information of the start commands here should match the description of +// the intel-pt section of the jLLDBTraceStart packet in the +// lldb/docs/lldb-gdb-remote.txt documentation file. Similarly, it should match +// the API help message of TraceIntelPT::GetStartConfigurationHelp(). + let Command = "thread trace start intel pt" in { def thread_trace_start_intel_pt_size: Option<"size", "s">, Group<1>, Arg<"Value">, - Desc<"The size of the trace in KB. The kernel rounds it down to the nearest" - " multiple of 4. Defaults to 4.">; - def thread_trace_start_intel_pt_custom_config: Option<"custom-config", "c">, + Desc<"Trace size in bytes per thread. It must be a power of 2 greater " + "than or equal to 4096 (2^12). The trace is circular keeping " + "the most recent data. Defaults to 4096 bytes.">; + def thread_trace_start_intel_pt_tsc: Option<"tsc", "t">, + Group<1>, + Desc<"Enable the use of TSC timestamps. This is supported on all devices " + "that support intel-pt.">; + def thread_trace_start_intel_pt_psb_period: Option<"psb-period", "p">, + Group<1>, + Arg<"Value">, + Desc<"This value defines the period in which PSB packets will be " + "generated. A PSB packet is a synchronization packet that contains a " + "TSC timestamp and the current absolute instruction pointer. " + "This parameter can only be used if " + "/sys/bus/event_source/devices/intel_pt/caps/psb_cyc is 1. Otherwise, " + "the PSB period will be defined by the processor. If supported, valid " + "values for this period can be found in " + "/sys/bus/event_source/devices/intel_pt/caps/psb_periods which " + "contains a hexadecimal number, whose bits represent valid values " + "e.g. if bit 2 is set, then value 2 is valid. The psb_period value is " + "converted to the approximate number of raw trace bytes between PSB " + "packets as: 2 ^ (value + 11), e.g. value 3 means 16KiB between PSB " + "packets. Defaults to 0 if supported.">; +} + +let Command = "process trace start intel pt" in { + def process_trace_start_intel_pt_thread_size: Option<"thread-size", "s">, + Group<1>, + Arg<"Value">, + Desc<"Trace size in bytes per thread. It must be a power of 2 greater " + "than or equal to 4096 (2^12). The trace is circular keeping " + "the most recent data. Defaults to 4096 bytes.">; + def process_trace_start_intel_pt_process_size_limit: Option<"total-size-limit", "l">, + Group<1>, + Arg<"Value">, + Desc<"Maximum total trace size per process in bytes. This limit applies to " + "the sum of the sizes of all thread traces of this process, excluding " + "the ones created with the \"thread trace start\" command. " + "Whenever a thread is attempted to be traced due to this command and " + "the limit would be reached, the process is stopped with a " + "\"processor trace\" reason, so that the user can retrace the process " + "if needed. Defaults to 500MB.">; + def process_trace_start_intel_pt_tsc: Option<"tsc", "t">, + Group<1>, + Desc<"Enable the use of TSC timestamps. This is supported on all devices " + "that support intel-pt.">; + def process_trace_start_intel_pt_psb_period: Option<"psb-period", "p">, Group<1>, Arg<"Value">, - Desc<"Low level bitmask configuration for the kernel based on the values " - "in `grep -H /sys/bus/event_source/devices/intel_pt/format/*`. " - "See https://github.com/torvalds/linux/blob/master/tools/perf/Documentation/perf-intel-pt.txt" - " for more information. Defaults to 0.">; + Desc<"This value defines the period in which PSB packets will be " + "generated. A PSB packet is a synchronization packet that contains a " + "TSC timestamp and the current absolute instruction pointer. " + "This parameter can only be used if " + "/sys/bus/event_source/devices/intel_pt/caps/psb_cyc is 1. Otherwise, " + "the PSB period will be defined by the processor. If supported, valid " + "values for this period can be found in " + "/sys/bus/event_source/devices/intel_pt/caps/psb_periods which " + "contains a hexadecimal number, whose bits represent valid values " + "e.g. if bit 2 is set, then value 2 is valid. The psb_period value is " + "converted to the approximate number of raw trace bytes between PSB " + "packets as: 2 ^ (value + 11), e.g. value 3 means 16KiB between PSB " + "packets. Defaults to 0 if supported.">; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp index beef5c3968ea..5af7c269d0cb 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp @@ -8,11 +8,11 @@ #include "TraceIntelPTSessionFileParser.h" +#include "../common/ThreadPostMortemTrace.h" #include "lldb/Core/Debugger.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/ThreadList.h" -#include "lldb/Target/ThreadTrace.h" using namespace lldb; using namespace lldb_private; @@ -24,7 +24,7 @@ StringRef TraceIntelPTSessionFileParser::GetSchema() { if (schema.empty()) { schema = TraceSessionFileParser::BuildSchema(R"({ "type": "intel-pt", - "pt_cpu": { + "cpuInfo": { "vendor": "intel" | "unknown", "family": integer, "model": integer, @@ -35,21 +35,22 @@ StringRef TraceIntelPTSessionFileParser::GetSchema() { return schema; } -pt_cpu TraceIntelPTSessionFileParser::ParsePTCPU(const JSONPTCPU &pt_cpu) { - return {pt_cpu.vendor.compare("intel") == 0 ? pcv_intel : pcv_unknown, - static_cast<uint16_t>(pt_cpu.family), - static_cast<uint8_t>(pt_cpu.model), - static_cast<uint8_t>(pt_cpu.stepping)}; +pt_cpu TraceIntelPTSessionFileParser::ParsePTCPU( + const JSONTraceIntelPTCPUInfo &cpu_info) { + return {cpu_info.vendor.compare("intel") == 0 ? pcv_intel : pcv_unknown, + static_cast<uint16_t>(cpu_info.family), + static_cast<uint8_t>(cpu_info.model), + static_cast<uint8_t>(cpu_info.stepping)}; } TraceSP TraceIntelPTSessionFileParser::CreateTraceIntelPTInstance( - const pt_cpu &pt_cpu, std::vector<ParsedProcess> &parsed_processes) { - std::vector<ThreadTraceSP> threads; + const pt_cpu &cpu_info, std::vector<ParsedProcess> &parsed_processes) { + std::vector<ThreadPostMortemTraceSP> threads; for (const ParsedProcess &parsed_process : parsed_processes) threads.insert(threads.end(), parsed_process.threads.begin(), parsed_process.threads.end()); - TraceSP trace_instance(new TraceIntelPT(pt_cpu, threads)); + TraceSP trace_instance(new TraceIntelPT(cpu_info, threads)); for (const ParsedProcess &parsed_process : parsed_processes) parsed_process.target_sp->SetTrace(trace_instance); @@ -64,7 +65,7 @@ Expected<TraceSP> TraceIntelPTSessionFileParser::Parse() { if (Expected<std::vector<ParsedProcess>> parsed_processes = ParseCommonSessionFile(session)) - return CreateTraceIntelPTInstance(ParsePTCPU(session.trace.pt_cpu), + return CreateTraceIntelPTInstance(ParsePTCPU(session.trace.cpuInfo), *parsed_processes); else return parsed_processes.takeError(); @@ -73,25 +74,34 @@ Expected<TraceSP> TraceIntelPTSessionFileParser::Parse() { namespace llvm { namespace json { -bool fromJSON(const Value &value, - TraceIntelPTSessionFileParser::JSONPTCPU &pt_cpu, Path path) { - ObjectMapper o(value, path); - return o && o.map("vendor", pt_cpu.vendor) && - o.map("family", pt_cpu.family) && o.map("model", pt_cpu.model) && - o.map("stepping", pt_cpu.stepping); -} - bool fromJSON( const Value &value, TraceIntelPTSessionFileParser::JSONTraceIntelPTSettings &plugin_settings, Path path) { ObjectMapper o(value, path); - return o && o.map("pt_cpu", plugin_settings.pt_cpu) && + return o && o.map("cpuInfo", plugin_settings.cpuInfo) && fromJSON( value, (TraceSessionFileParser::JSONTracePluginSettings &)plugin_settings, path); } +bool fromJSON(const json::Value &value, + TraceIntelPTSessionFileParser::JSONTraceIntelPTCPUInfo &cpu_info, + Path path) { + ObjectMapper o(value, path); + return o && o.map("vendor", cpu_info.vendor) && + o.map("family", cpu_info.family) && o.map("model", cpu_info.model) && + o.map("stepping", cpu_info.stepping); +} + +Value toJSON( + const TraceIntelPTSessionFileParser::JSONTraceIntelPTCPUInfo &cpu_info) { + return Value(Object{{"family", cpu_info.family}, + {"model", cpu_info.model}, + {"stepping", cpu_info.stepping}, + {"vendor", cpu_info.vendor}}); +} + } // namespace json } // namespace llvm diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h index 6a896de09d00..b2667a882222 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h @@ -10,7 +10,8 @@ #define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONFILEPARSER_H #include "TraceIntelPT.h" -#include "lldb/Target/TraceSessionFileParser.h" + +#include "../common/TraceSessionFileParser.h" namespace lldb_private { namespace trace_intel_pt { @@ -19,16 +20,16 @@ class TraceIntelPT; class TraceIntelPTSessionFileParser : public TraceSessionFileParser { public: - struct JSONPTCPU { - std::string vendor; + struct JSONTraceIntelPTCPUInfo { int64_t family; int64_t model; int64_t stepping; + std::string vendor; }; struct JSONTraceIntelPTSettings : TraceSessionFileParser::JSONTracePluginSettings { - JSONPTCPU pt_cpu; + JSONTraceIntelPTCPUInfo cpuInfo; }; /// See \a TraceSessionFileParser::TraceSessionFileParser for the description @@ -52,11 +53,11 @@ public: llvm::Expected<lldb::TraceSP> Parse(); lldb::TraceSP - CreateTraceIntelPTInstance(const pt_cpu &pt_cpu, + CreateTraceIntelPTInstance(const pt_cpu &cpu_info, std::vector<ParsedProcess> &parsed_processes); private: - pt_cpu ParsePTCPU(const JSONPTCPU &pt_cpu); + static pt_cpu ParsePTCPU(const JSONTraceIntelPTCPUInfo &cpu_info); const llvm::json::Value &m_trace_session_file; }; @@ -67,17 +68,20 @@ private: namespace llvm { namespace json { -bool fromJSON( - const Value &value, - lldb_private::trace_intel_pt::TraceIntelPTSessionFileParser::JSONPTCPU - &pt_cpu, - Path path); - bool fromJSON(const Value &value, lldb_private::trace_intel_pt::TraceIntelPTSessionFileParser:: JSONTraceIntelPTSettings &plugin_settings, Path path); +bool fromJSON(const llvm::json::Value &value, + lldb_private::trace_intel_pt::TraceIntelPTSessionFileParser:: + JSONTraceIntelPTCPUInfo &packet, + llvm::json::Path path); + +llvm::json::Value +toJSON(const lldb_private::trace_intel_pt::TraceIntelPTSessionFileParser:: + JSONTraceIntelPTCPUInfo &packet); + } // namespace json } // namespace llvm diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/forward-declarations.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/forward-declarations.h new file mode 100644 index 000000000000..3c5f811acc10 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/forward-declarations.h @@ -0,0 +1,20 @@ +//===-- forward-declarations.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_SOURCE_PLUGINS_TRACE_INTEL_PT_FORWARD_DECLARATIONS_H +#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_FORWARD_DECLARATIONS_H + +namespace lldb_private { +namespace trace_intel_pt { + +class TraceIntelPT; +class ThreadDecoder; + +} // namespace trace_intel_pt +} // namespace lldb_private +#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_FORWARD_DECLARATIONS_H diff --git a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp new file mode 100644 index 000000000000..3dd4c89e2777 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp @@ -0,0 +1,66 @@ +//===-- CommandObjectThreadTraceExportCTF.cpp -----------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "CommandObjectThreadTraceExportCTF.h" + +#include "lldb/Host/OptionParser.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::ctf; +using namespace llvm; + +// CommandObjectThreadTraceExportCTF + +#define LLDB_OPTIONS_thread_trace_export_ctf +#include "TraceExporterCTFCommandOptions.inc" + +Status CommandObjectThreadTraceExportCTF::CommandOptions::SetOptionValue( + uint32_t option_idx, llvm::StringRef option_arg, + ExecutionContext *execution_context) { + Status error; + const int short_option = m_getopt_table[option_idx].val; + + switch (short_option) { + case 't': { + int64_t thread_index; + if (option_arg.empty() || option_arg.getAsInteger(0, thread_index) || + thread_index < 0) + error.SetErrorStringWithFormat("invalid integer value for option '%s'", + option_arg.str().c_str()); + else + m_thread_index = thread_index; + break; + } + default: + llvm_unreachable("Unimplemented option"); + } + return error; +} + +void CommandObjectThreadTraceExportCTF::CommandOptions::OptionParsingStarting( + ExecutionContext *execution_context) { + m_thread_index = None; +} + +llvm::ArrayRef<OptionDefinition> +CommandObjectThreadTraceExportCTF::CommandOptions::GetDefinitions() { + return llvm::makeArrayRef(g_thread_trace_export_ctf_options); +} + +bool CommandObjectThreadTraceExportCTF::DoExecute(Args &command, + CommandReturnObject &result) { + Stream &s = result.GetOutputStream(); + // TODO: create an actual instance of the exporter and invoke it + if (m_options.m_thread_index) + s.Printf("got thread index %d\n", (int)m_options.m_thread_index.getValue()); + else + s.Printf("didn't get a thread index\n"); + + return result.Succeeded(); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.h b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.h new file mode 100644 index 000000000000..26b068a8f8c5 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.h @@ -0,0 +1,56 @@ +//===-- CommandObjectThreadTraceExportCTF.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_SOURCE_PLUGINS_TRACE_INTEL_PT_COMMANDOBJECTTHREADTRACEEXPORTCTF_H +#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_COMMANDOBJECTTHREADTRACEEXPORTCTF_H + +#include "TraceExporterCTF.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/CommandReturnObject.h" + +namespace lldb_private { +namespace ctf { + +class CommandObjectThreadTraceExportCTF : public CommandObjectParsed { +public: + class CommandOptions : public Options { + public: + CommandOptions() : Options() { OptionParsingStarting(nullptr); } + + Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, + ExecutionContext *execution_context) override; + + void OptionParsingStarting(ExecutionContext *execution_context) override; + + llvm::ArrayRef<OptionDefinition> GetDefinitions() override; + + llvm::Optional<size_t> m_thread_index; + }; + + CommandObjectThreadTraceExportCTF(CommandInterpreter &interpreter) + : CommandObjectParsed( + interpreter, "thread trace export ctf", + "Export a given thread's trace to Chrome Trace Format", + "thread trace export ctf [<ctf-options>]", + lldb::eCommandRequiresProcess | lldb::eCommandTryTargetAPILock | + lldb::eCommandProcessMustBeLaunched | + lldb::eCommandProcessMustBePaused), + m_options() {} + + Options *GetOptions() override { return &m_options; } + +protected: + bool DoExecute(Args &command, CommandReturnObject &result) override; + + CommandOptions m_options; +}; + +} // namespace ctf +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_COMMANDOBJECTTHREADTRACEEXPORTCTF_H diff --git a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.cpp b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.cpp new file mode 100644 index 000000000000..08bc03d78303 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.cpp @@ -0,0 +1,53 @@ +//===-- TraceExporterCTF.cpp ----------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "TraceExporterCTF.h" + +#include <memory> + +#include "CommandObjectThreadTraceExportCTF.h" +#include "lldb/Core/PluginManager.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::ctf; +using namespace llvm; + +LLDB_PLUGIN_DEFINE(TraceExporterCTF) + +//------------------------------------------------------------------ +// PluginInterface protocol +//------------------------------------------------------------------ + +static CommandObjectSP +GetThreadTraceExportCommand(CommandInterpreter &interpreter) { + return std::make_shared<CommandObjectThreadTraceExportCTF>(interpreter); +} + +void TraceExporterCTF::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + "Chrome Trace Format Exporter", CreateInstance, + GetThreadTraceExportCommand); +} + +void TraceExporterCTF::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +ConstString TraceExporterCTF::GetPluginNameStatic() { + static ConstString g_name("ctf"); + return g_name; +} + +ConstString TraceExporterCTF::GetPluginName() { return GetPluginNameStatic(); } + +uint32_t TraceExporterCTF::GetPluginVersion() { return 1; } + +Expected<TraceExporterUP> TraceExporterCTF::CreateInstance() { + return std::make_unique<TraceExporterCTF>(); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.h b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.h new file mode 100644 index 000000000000..8f9e354ab0dd --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.h @@ -0,0 +1,42 @@ +//===-- TraceExporterCTF.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_SOURCE_PLUGINS_TRACE_EXPORTER_CTF_H +#define LLDB_SOURCE_PLUGINS_TRACE_EXPORTER_CTF_H + +#include "lldb/Target/TraceExporter.h" + +namespace lldb_private { +namespace ctf { + +/// Trace Exporter Plugin that can produce traces in Chrome Trace Format. +/// Still in development. +class TraceExporterCTF : public TraceExporter { +public: + ~TraceExporterCTF() override = default; + + /// PluginInterface protocol + /// \{ + static llvm::Expected<lldb::TraceExporterUP> CreateInstance(); + + ConstString GetPluginName() override; + + static void Initialize(); + + static void Terminate(); + + static ConstString GetPluginNameStatic(); + + uint32_t GetPluginVersion() override; + /// \} +}; + +} // namespace ctf +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_TRACE_EXPORTER_CTF_H diff --git a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTFOptions.td b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTFOptions.td new file mode 100644 index 000000000000..ce751f148d9f --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTFOptions.td @@ -0,0 +1,9 @@ +include "../../../../source/Commands/OptionsBase.td" + +let Command = "thread trace export ctf" in { + def thread_trace_export_ctf: Option<"tid", "t">, + Group<1>, + Arg<"ThreadIndex">, + Desc<"Export the trace for the specified thread index. Otherwise, the " + "currently selected thread will be used.">; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index 0218606b8937..d4260a966857 100644 --- a/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -75,7 +75,7 @@ #include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h" #include "Plugins/SymbolFile/PDB/PDBASTParser.h" -#include <stdio.h> +#include <cstdio> #include <mutex> @@ -163,7 +163,6 @@ void addOverridesForMethod(clang::CXXMethodDecl *decl) { if (name.getNameKind() == clang::DeclarationName::CXXDestructorName) if (auto *baseDtorDecl = base_record->getDestructor()) { if (baseDtorDecl->isVirtual()) { - path.Decls = baseDtorDecl; decls.push_back(baseDtorDecl); return true; } else @@ -171,12 +170,11 @@ void addOverridesForMethod(clang::CXXMethodDecl *decl) { } // Otherwise, search for name in the base class. - for (path.Decls = base_record->lookup(name); !path.Decls.empty(); - path.Decls = path.Decls.slice(1)) { + for (path.Decls = base_record->lookup(name).begin(); + path.Decls != path.Decls.end(); ++path.Decls) { if (auto *method_decl = - llvm::dyn_cast<clang::CXXMethodDecl>(path.Decls.front())) + llvm::dyn_cast<clang::CXXMethodDecl>(*path.Decls)) if (method_decl->isVirtual() && !isOverload(decl, method_decl)) { - path.Decls = method_decl; decls.push_back(method_decl); return true; } @@ -479,6 +477,9 @@ static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) { case clang::Language::OpenCL: LangStd = LangStandard::lang_opencl10; break; + case clang::Language::OpenCLCXX: + LangStd = LangStandard::lang_openclcpp; + break; case clang::Language::CUDA: LangStd = LangStandard::lang_cuda; break; @@ -686,8 +687,8 @@ void TypeSystemClang::SetTargetTriple(llvm::StringRef target_triple) { void TypeSystemClang::SetExternalSource( llvm::IntrusiveRefCntPtr<ExternalASTSource> &ast_source_up) { ASTContext &ast = getASTContext(); - ast.setExternalSource(ast_source_up); ast.getTranslationUnitDecl()->setHasExternalLexicalStorage(true); + ast.setExternalSource(ast_source_up); } ASTContext &TypeSystemClang::getASTContext() { @@ -745,7 +746,7 @@ void TypeSystemClang::CreateASTContext() { *m_diagnostics_engine_up, *m_file_manager_up); m_ast_up = std::make_unique<ASTContext>( *m_language_options_up, *m_source_manager_up, *m_identifier_table_up, - *m_selector_table_up, *m_builtins_up); + *m_selector_table_up, *m_builtins_up, TU_Complete); m_diagnostic_consumer_up = std::make_unique<NullDiagnosticConsumer>(); m_ast_up->getDiagnostics().setClient(m_diagnostic_consumer_up.get(), false); @@ -1356,9 +1357,11 @@ CompilerType TypeSystemClang::CreateRecordType( } namespace { - bool IsValueParam(const clang::TemplateArgument &argument) { - return argument.getKind() == TemplateArgument::Integral; - } +/// Returns true iff the given TemplateArgument should be represented as an +/// NonTypeTemplateParmDecl in the AST. +bool IsValueParam(const clang::TemplateArgument &argument) { + return argument.getKind() == TemplateArgument::Integral; +} } static TemplateParameterList *CreateTemplateParameterList( @@ -1462,6 +1465,99 @@ void TypeSystemClang::CreateFunctionTemplateSpecializationInfo( template_args_ptr, nullptr); } +/// Returns true if the given template parameter can represent the given value. +/// For example, `typename T` can represent `int` but not integral values such +/// as `int I = 3`. +static bool TemplateParameterAllowsValue(NamedDecl *param, + const TemplateArgument &value) { + if (auto *type_param = llvm::dyn_cast<TemplateTypeParmDecl>(param)) { + // Compare the argument kind, i.e. ensure that <typename> != <int>. + if (value.getKind() != TemplateArgument::Type) + return false; + } else if (auto *type_param = + llvm::dyn_cast<NonTypeTemplateParmDecl>(param)) { + // Compare the argument kind, i.e. ensure that <typename> != <int>. + if (!IsValueParam(value)) + return false; + // Compare the integral type, i.e. ensure that <int> != <char>. + if (type_param->getType() != value.getIntegralType()) + return false; + } else { + // There is no way to create other parameter decls at the moment, so we + // can't reach this case during normal LLDB usage. Log that this happened + // and assert. + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + LLDB_LOG(log, + "Don't know how to compare template parameter to passed" + " value. Decl kind of parameter is: {0}", + param->getDeclKindName()); + lldbassert(false && "Can't compare this TemplateParmDecl subclass"); + // In release builds just fall back to marking the parameter as not + // accepting the value so that we don't try to fit an instantiation to a + // template that doesn't fit. E.g., avoid that `S<1>` is being connected to + // `template<typename T> struct S;`. + return false; + } + return true; +} + +/// Returns true if the given class template declaration could produce an +/// instantiation with the specified values. +/// For example, `<typename T>` allows the arguments `float`, but not for +/// example `bool, float` or `3` (as an integer parameter value). +static bool ClassTemplateAllowsToInstantiationArgs( + ClassTemplateDecl *class_template_decl, + const TypeSystemClang::TemplateParameterInfos &instantiation_values) { + + TemplateParameterList ¶ms = *class_template_decl->getTemplateParameters(); + + // Save some work by iterating only once over the found parameters and + // calculate the information related to parameter packs. + + // Contains the first pack parameter (or non if there are none). + llvm::Optional<NamedDecl *> pack_parameter; + // Contains the number of non-pack parameters. + size_t non_pack_params = params.size(); + for (size_t i = 0; i < params.size(); ++i) { + NamedDecl *param = params.getParam(i); + if (param->isParameterPack()) { + pack_parameter = param; + non_pack_params = i; + break; + } + } + + // The found template needs to have compatible non-pack template arguments. + // E.g., ensure that <typename, typename> != <typename>. + // The pack parameters are compared later. + if (non_pack_params != instantiation_values.args.size()) + return false; + + // Ensure that <typename...> != <typename>. + if (pack_parameter.hasValue() != instantiation_values.hasParameterPack()) + return false; + + // Compare the first pack parameter that was found with the first pack + // parameter value. The special case of having an empty parameter pack value + // always fits to a pack parameter. + // E.g., ensure that <int...> != <typename...>. + if (pack_parameter && !instantiation_values.packed_args->args.empty() && + !TemplateParameterAllowsValue( + *pack_parameter, instantiation_values.packed_args->args.front())) + return false; + + // Compare all the non-pack parameters now. + // E.g., ensure that <int> != <long>. + for (const auto pair : llvm::zip_first(instantiation_values.args, params)) { + const TemplateArgument &passed_arg = std::get<0>(pair); + NamedDecl *found_param = std::get<1>(pair); + if (!TemplateParameterAllowsValue(found_param, passed_arg)) + return false; + } + + return class_template_decl; +} + ClassTemplateDecl *TypeSystemClang::CreateClassTemplateDecl( DeclContext *decl_ctx, OptionalClangModuleID owning_module, lldb::AccessType access_type, const char *class_name, int kind, @@ -1475,12 +1571,22 @@ ClassTemplateDecl *TypeSystemClang::CreateClassTemplateDecl( IdentifierInfo &identifier_info = ast.Idents.get(class_name); DeclarationName decl_name(&identifier_info); + // Search the AST for an existing ClassTemplateDecl that could be reused. clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name); - for (NamedDecl *decl : result) { class_template_decl = dyn_cast<clang::ClassTemplateDecl>(decl); - if (class_template_decl) - return class_template_decl; + if (!class_template_decl) + continue; + // The class template has to be able to represents the instantiation + // values we received. Without this we might end up putting an instantiation + // with arguments such as <int, int> to a template such as: + // template<typename T> struct S; + // Connecting the instantiation to an incompatible template could cause + // problems later on. + if (!ClassTemplateAllowsToInstantiationArgs(class_template_decl, + template_param_infos)) + continue; + return class_template_decl; } llvm::SmallVector<NamedDecl *, 8> template_param_decls; @@ -1866,8 +1972,8 @@ TypeSystemClang::CreateUsingDeclaration(clang::DeclContext *current_decl_ctx, clang::NestedNameSpecifierLoc(), clang::DeclarationNameInfo(), false); SetOwningModule(using_decl, owning_module); clang::UsingShadowDecl *shadow_decl = clang::UsingShadowDecl::Create( - getASTContext(), current_decl_ctx, clang::SourceLocation(), using_decl, - target); + getASTContext(), current_decl_ctx, clang::SourceLocation(), + target->getDeclName(), using_decl, target); SetOwningModule(shadow_decl, owning_module); using_decl->addShadowDecl(shadow_decl); current_decl_ctx->addDecl(using_decl); @@ -2114,11 +2220,10 @@ ParmVarDecl *TypeSystemClang::CreateParameterDeclaration( return decl; } -void TypeSystemClang::SetFunctionParameters(FunctionDecl *function_decl, - ParmVarDecl **params, - unsigned num_params) { +void TypeSystemClang::SetFunctionParameters( + FunctionDecl *function_decl, llvm::ArrayRef<ParmVarDecl *> params) { if (function_decl) - function_decl->setParams(ArrayRef<ParmVarDecl *>(params, num_params)); + function_decl->setParams(params); } CompilerType @@ -2470,42 +2575,6 @@ ClangASTMetadata *TypeSystemClang::GetMetadata(const clang::Type *object) { return nullptr; } -bool TypeSystemClang::SetTagTypeKind(clang::QualType tag_qual_type, - int kind) const { - const clang::Type *clang_type = tag_qual_type.getTypePtr(); - if (clang_type) { - const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(clang_type); - if (tag_type) { - clang::TagDecl *tag_decl = - llvm::dyn_cast<clang::TagDecl>(tag_type->getDecl()); - if (tag_decl) { - tag_decl->setTagKind((clang::TagDecl::TagKind)kind); - return true; - } - } - } - return false; -} - -bool TypeSystemClang::SetDefaultAccessForRecordFields( - clang::RecordDecl *record_decl, int default_accessibility, - int *assigned_accessibilities, size_t num_assigned_accessibilities) { - if (record_decl) { - uint32_t field_idx; - clang::RecordDecl::field_iterator field, field_end; - for (field = record_decl->field_begin(), - field_end = record_decl->field_end(), field_idx = 0; - field != field_end; ++field, ++field_idx) { - // If no accessibility was assigned, assign the correct one - if (field_idx < num_assigned_accessibilities && - assigned_accessibilities[field_idx] == clang::AS_none) - field->setAccess((clang::AccessSpecifier)default_accessibility); - } - return true; - } - return false; -} - clang::DeclContext * TypeSystemClang::GetDeclContextForType(const CompilerType &type) { return GetDeclContextForType(ClangUtil::GetQualType(type)); @@ -4697,7 +4766,6 @@ lldb::Encoding TypeSystemClang::GetEncoding(lldb::opaque_compiler_type_t type, case clang::BuiltinType::Void: break; - case clang::BuiltinType::Bool: case clang::BuiltinType::Char_S: case clang::BuiltinType::SChar: case clang::BuiltinType::WChar_S: @@ -4708,6 +4776,7 @@ lldb::Encoding TypeSystemClang::GetEncoding(lldb::opaque_compiler_type_t type, case clang::BuiltinType::Int128: return lldb::eEncodingSint; + case clang::BuiltinType::Bool: case clang::BuiltinType::Char_U: case clang::BuiltinType::UChar: case clang::BuiltinType::WChar_U: @@ -4889,6 +4958,75 @@ lldb::Encoding TypeSystemClang::GetEncoding(lldb::opaque_compiler_type_t type, case clang::BuiltinType::SveFloat64x4: break; + // RISC-V V builtin types. + case clang::BuiltinType::RvvInt8mf8: + case clang::BuiltinType::RvvInt8mf4: + case clang::BuiltinType::RvvInt8mf2: + case clang::BuiltinType::RvvInt8m1: + case clang::BuiltinType::RvvInt8m2: + case clang::BuiltinType::RvvInt8m4: + case clang::BuiltinType::RvvInt8m8: + case clang::BuiltinType::RvvUint8mf8: + case clang::BuiltinType::RvvUint8mf4: + case clang::BuiltinType::RvvUint8mf2: + case clang::BuiltinType::RvvUint8m1: + case clang::BuiltinType::RvvUint8m2: + case clang::BuiltinType::RvvUint8m4: + case clang::BuiltinType::RvvUint8m8: + case clang::BuiltinType::RvvInt16mf4: + case clang::BuiltinType::RvvInt16mf2: + case clang::BuiltinType::RvvInt16m1: + case clang::BuiltinType::RvvInt16m2: + case clang::BuiltinType::RvvInt16m4: + case clang::BuiltinType::RvvInt16m8: + case clang::BuiltinType::RvvUint16mf4: + case clang::BuiltinType::RvvUint16mf2: + case clang::BuiltinType::RvvUint16m1: + case clang::BuiltinType::RvvUint16m2: + case clang::BuiltinType::RvvUint16m4: + case clang::BuiltinType::RvvUint16m8: + case clang::BuiltinType::RvvInt32mf2: + case clang::BuiltinType::RvvInt32m1: + case clang::BuiltinType::RvvInt32m2: + case clang::BuiltinType::RvvInt32m4: + case clang::BuiltinType::RvvInt32m8: + case clang::BuiltinType::RvvUint32mf2: + case clang::BuiltinType::RvvUint32m1: + case clang::BuiltinType::RvvUint32m2: + case clang::BuiltinType::RvvUint32m4: + case clang::BuiltinType::RvvUint32m8: + case clang::BuiltinType::RvvInt64m1: + case clang::BuiltinType::RvvInt64m2: + case clang::BuiltinType::RvvInt64m4: + case clang::BuiltinType::RvvInt64m8: + case clang::BuiltinType::RvvUint64m1: + case clang::BuiltinType::RvvUint64m2: + case clang::BuiltinType::RvvUint64m4: + case clang::BuiltinType::RvvUint64m8: + case clang::BuiltinType::RvvFloat16mf4: + case clang::BuiltinType::RvvFloat16mf2: + case clang::BuiltinType::RvvFloat16m1: + case clang::BuiltinType::RvvFloat16m2: + case clang::BuiltinType::RvvFloat16m4: + case clang::BuiltinType::RvvFloat16m8: + case clang::BuiltinType::RvvFloat32mf2: + case clang::BuiltinType::RvvFloat32m1: + case clang::BuiltinType::RvvFloat32m2: + case clang::BuiltinType::RvvFloat32m4: + case clang::BuiltinType::RvvFloat32m8: + case clang::BuiltinType::RvvFloat64m1: + case clang::BuiltinType::RvvFloat64m2: + case clang::BuiltinType::RvvFloat64m4: + case clang::BuiltinType::RvvFloat64m8: + case clang::BuiltinType::RvvBool1: + case clang::BuiltinType::RvvBool2: + case clang::BuiltinType::RvvBool4: + case clang::BuiltinType::RvvBool8: + case clang::BuiltinType::RvvBool16: + case clang::BuiltinType::RvvBool32: + case clang::BuiltinType::RvvBool64: + break; + case clang::BuiltinType::IncompleteMatrixIdx: break; } @@ -6365,7 +6503,7 @@ CompilerType TypeSystemClang::GetChildCompilerTypeAtIndex( case clang::Type::RValueReference: if (idx_is_valid) { const clang::ReferenceType *reference_type = - llvm::cast<clang::ReferenceType>(parent_qual_type.getTypePtr()); + llvm::cast<clang::ReferenceType>(GetQualType(type).getTypePtr()); CompilerType pointee_clang_type = GetType(reference_type->getPointeeType()); if (transparent_pointers && pointee_clang_type.IsAggregateType()) { @@ -6536,10 +6674,11 @@ size_t TypeSystemClang::GetIndexOfChildMemberWithName( if (cxx_record_decl->lookupInBases( [decl_name](const clang::CXXBaseSpecifier *specifier, clang::CXXBasePath &path) { - path.Decls = - specifier->getType()->getAsCXXRecordDecl()->lookup( - decl_name); - return !path.Decls.empty(); + CXXRecordDecl *record = + specifier->getType()->getAsCXXRecordDecl(); + auto r = record->lookup(decl_name); + path.Decls = r.begin(); + return !r.empty(); }, paths)) { clang::CXXBasePaths::const_paths_iterator path, @@ -6562,9 +6701,10 @@ size_t TypeSystemClang::GetIndexOfChildMemberWithName( ->getDecl()); } } - for (clang::NamedDecl *path_decl : path->Decls) { + for (clang::DeclContext::lookup_iterator I = path->Decls, E; + I != E; ++I) { child_idx = GetIndexForRecordChild( - parent_record_decl, path_decl, omit_empty_base_classes); + parent_record_decl, *I, omit_empty_base_classes); if (child_idx == UINT32_MAX) { child_indexes.clear(); return 0; @@ -9238,11 +9378,11 @@ CompilerType TypeSystemClang::DeclGetFunctionArgumentType(void *opaque_decl, std::vector<CompilerDecl> TypeSystemClang::DeclContextFindDeclByName( void *opaque_decl_ctx, ConstString name, const bool ignore_using_decls) { std::vector<CompilerDecl> found_decls; - if (opaque_decl_ctx) { + SymbolFile *symbol_file = GetSymbolFile(); + if (opaque_decl_ctx && symbol_file) { DeclContext *root_decl_ctx = (DeclContext *)opaque_decl_ctx; std::set<DeclContext *> searched; std::multimap<DeclContext *, DeclContext *> search_queue; - SymbolFile *symbol_file = GetSymbolFile(); for (clang::DeclContext *decl_context = root_decl_ctx; decl_context != nullptr && found_decls.empty(); @@ -9336,10 +9476,10 @@ uint32_t TypeSystemClang::CountDeclLevels(clang::DeclContext *frame_decl_ctx, clang::DeclContext *child_decl_ctx, ConstString *child_name, CompilerType *child_type) { - if (frame_decl_ctx) { + SymbolFile *symbol_file = GetSymbolFile(); + if (frame_decl_ctx && symbol_file) { std::set<DeclContext *> searched; std::multimap<DeclContext *, DeclContext *> search_queue; - SymbolFile *symbol_file = GetSymbolFile(); // Get the lookup scope for the decl we're trying to find. clang::DeclContext *parent_decl_ctx = child_decl_ctx->getParent(); @@ -9585,7 +9725,8 @@ ScratchTypeSystemClang::ScratchTypeSystemClang(Target &target, llvm::Triple triple) : TypeSystemClang("scratch ASTContext", triple), m_triple(triple), m_target_wp(target.shared_from_this()), - m_persistent_variables(new ClangPersistentVariables) { + m_persistent_variables( + new ClangPersistentVariables(target.shared_from_this())) { m_scratch_ast_source_up = CreateASTSource(); m_scratch_ast_source_up->InstallASTContext(*this); llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source( @@ -9653,7 +9794,8 @@ ScratchTypeSystemClang::CreateUtilityFunction(std::string text, return {}; return std::make_unique<ClangUtilityFunction>( - *target_sp.get(), std::move(text), std::move(name)); + *target_sp.get(), std::move(text), std::move(name), + target_sp->GetDebugUtilityExpression()); } PersistentExpressionState * diff --git a/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h index d1d876d05a6b..4a6891795bd8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h +++ b/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h @@ -9,7 +9,7 @@ #ifndef LLDB_SOURCE_PLUGINS_TYPESYSTEM_CLANG_TYPESYSTEMCLANG_H #define LLDB_SOURCE_PLUGINS_TYPESYSTEM_CLANG_TYPESYSTEMCLANG_H -#include <stdint.h> +#include <cstdint> #include <functional> #include <initializer_list> @@ -265,7 +265,7 @@ public: clang::DeclContext::lookup_result result = decl_context->lookup(myName); if (!result.empty()) { - clang::NamedDecl *named_decl = result[0]; + clang::NamedDecl *named_decl = *result.begin(); if (const RecordDeclType *record_decl = llvm::dyn_cast<RecordDeclType>(named_decl)) compiler_type.SetCompilerType( @@ -328,6 +328,8 @@ public: (!packed_args || !packed_args->packed_args); } + bool hasParameterPack() const { return static_cast<bool>(packed_args); } + llvm::SmallVector<const char *, 2> names; llvm::SmallVector<clang::TemplateArgument, 2> args; @@ -378,13 +380,6 @@ public: bool isForwardDecl, bool isInternal, ClangASTMetadata *metadata = nullptr); - bool SetTagTypeKind(clang::QualType type, int kind) const; - - bool SetDefaultAccessForRecordFields(clang::RecordDecl *record_decl, - int default_accessibility, - int *assigned_accessibilities, - size_t num_assigned_accessibilities); - // Returns a mask containing bits from the TypeSystemClang::eTypeXXX // enumerations @@ -421,7 +416,7 @@ public: int storage, bool add_decl = false); void SetFunctionParameters(clang::FunctionDecl *function_decl, - clang::ParmVarDecl **params, unsigned num_params); + llvm::ArrayRef<clang::ParmVarDecl *> params); CompilerType CreateBlockPointerType(const CompilerType &function_type); diff --git a/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp b/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp index 1bc071c2b161..65947c5f833b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp @@ -38,10 +38,10 @@ bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly( ProcessSP process_sp(thread.GetProcess()); if (process_sp) { Status error; - const bool prefer_file_cache = true; + const bool force_live_memory = true; if (process_sp->GetTarget().ReadMemory( - range.GetBaseAddress(), prefer_file_cache, function_text.data(), - range.GetByteSize(), error) != range.GetByteSize()) { + range.GetBaseAddress(), function_text.data(), range.GetByteSize(), + error, force_live_memory) != range.GetByteSize()) { return false; } } diff --git a/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp b/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp index fe1275d5b0cf..402a70cd025f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp @@ -51,12 +51,11 @@ bool UnwindAssembly_x86::GetNonCallSiteUnwindPlanFromAssembly( ProcessSP process_sp(thread.GetProcess()); if (process_sp.get() == nullptr) return false; - const bool prefer_file_cache = true; std::vector<uint8_t> function_text(func.GetByteSize()); Status error; if (process_sp->GetTarget().ReadMemory( - func.GetBaseAddress(), prefer_file_cache, function_text.data(), - func.GetByteSize(), error) == func.GetByteSize()) { + func.GetBaseAddress(), function_text.data(), func.GetByteSize(), + error) == func.GetByteSize()) { RegisterContextSP reg_ctx(thread.GetRegisterContext()); m_assembly_inspection_engine->Initialize(reg_ctx); return m_assembly_inspection_engine->GetNonCallSiteUnwindPlanFromAssembly( @@ -153,12 +152,11 @@ bool UnwindAssembly_x86::AugmentUnwindPlanFromCallSite( return false; if (m_assembly_inspection_engine == nullptr) return false; - const bool prefer_file_cache = true; std::vector<uint8_t> function_text(func.GetByteSize()); Status error; if (process_sp->GetTarget().ReadMemory( - func.GetBaseAddress(), prefer_file_cache, function_text.data(), - func.GetByteSize(), error) == func.GetByteSize()) { + func.GetBaseAddress(), function_text.data(), func.GetByteSize(), + error) == func.GetByteSize()) { RegisterContextSP reg_ctx(thread.GetRegisterContext()); m_assembly_inspection_engine->Initialize(reg_ctx); return m_assembly_inspection_engine->AugmentUnwindPlanFromCallSite( @@ -185,10 +183,9 @@ bool UnwindAssembly_x86::GetFastUnwindPlan(AddressRange &func, Thread &thread, ProcessSP process_sp = thread.GetProcess(); if (process_sp) { Target &target(process_sp->GetTarget()); - const bool prefer_file_cache = true; Status error; - if (target.ReadMemory(func.GetBaseAddress(), prefer_file_cache, - opcode_data.data(), 4, error) == 4) { + if (target.ReadMemory(func.GetBaseAddress(), opcode_data.data(), 4, + error) == 4) { uint8_t i386_push_mov[] = {0x55, 0x89, 0xe5}; uint8_t x86_64_push_mov[] = {0x55, 0x48, 0x89, 0xe5}; @@ -220,12 +217,10 @@ bool UnwindAssembly_x86::FirstNonPrologueInsn( if (m_assembly_inspection_engine == nullptr) return false; - const bool prefer_file_cache = true; std::vector<uint8_t> function_text(func.GetByteSize()); Status error; - if (target->ReadMemory(func.GetBaseAddress(), prefer_file_cache, - function_text.data(), func.GetByteSize(), - error) == func.GetByteSize()) { + if (target->ReadMemory(func.GetBaseAddress(), function_text.data(), + func.GetByteSize(), error) == func.GetByteSize()) { size_t offset; if (m_assembly_inspection_engine->FindFirstNonPrologueInstruction( function_text.data(), func.GetByteSize(), offset)) { diff --git a/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h b/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h index f39dce1afaa6..487748812968 100644 --- a/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h +++ b/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h @@ -45,9 +45,9 @@ public: /// are called. This one takes a vector of register name and lldb /// register numbers. struct lldb_reg_info { - const char *name; - uint32_t lldb_regnum; - lldb_reg_info() : name(nullptr), lldb_regnum(LLDB_INVALID_REGNUM) {} + const char *name = nullptr; + uint32_t lldb_regnum = LLDB_INVALID_REGNUM; + lldb_reg_info() = default; }; void Initialize(std::vector<lldb_reg_info> ®_info); diff --git a/contrib/llvm-project/lldb/source/Symbol/ArmUnwindInfo.cpp b/contrib/llvm-project/lldb/source/Symbol/ArmUnwindInfo.cpp index f2887035e5cf..07852485f44e 100644 --- a/contrib/llvm-project/lldb/source/Symbol/ArmUnwindInfo.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/ArmUnwindInfo.cpp @@ -68,7 +68,7 @@ ArmUnwindInfo::ArmUnwindInfo(ObjectFile &objfile, SectionSP &arm_exidx, llvm::sort(m_exidx_entries.begin(), m_exidx_entries.end()); } -ArmUnwindInfo::~ArmUnwindInfo() {} +ArmUnwindInfo::~ArmUnwindInfo() = default; // Read a byte from the unwind instruction stream with the given offset. Custom // function is required because have to red in order of significance within diff --git a/contrib/llvm-project/lldb/source/Symbol/Block.cpp b/contrib/llvm-project/lldb/source/Symbol/Block.cpp index afcdf3e21e19..fc246ac8575d 100644 --- a/contrib/llvm-project/lldb/source/Symbol/Block.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/Block.cpp @@ -25,7 +25,7 @@ Block::Block(lldb::user_id_t uid) m_inlineInfoSP(), m_variable_list_sp(), m_parsed_block_info(false), m_parsed_block_variables(false), m_parsed_child_blocks(false) {} -Block::~Block() {} +Block::~Block() = default; void Block::GetDescription(Stream *s, Function *function, lldb::DescriptionLevel level, Target *target) const { diff --git a/contrib/llvm-project/lldb/source/Symbol/CompactUnwindInfo.cpp b/contrib/llvm-project/lldb/source/Symbol/CompactUnwindInfo.cpp index 1bb7cd1fc05b..830fe5546c1c 100644 --- a/contrib/llvm-project/lldb/source/Symbol/CompactUnwindInfo.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/CompactUnwindInfo.cpp @@ -167,7 +167,7 @@ CompactUnwindInfo::CompactUnwindInfo(ObjectFile &objfile, SectionSP §ion_sp) // destructor -CompactUnwindInfo::~CompactUnwindInfo() {} +CompactUnwindInfo::~CompactUnwindInfo() = default; bool CompactUnwindInfo::GetUnwindPlan(Target &target, Address addr, UnwindPlan &unwind_plan) { diff --git a/contrib/llvm-project/lldb/source/Symbol/CompileUnit.cpp b/contrib/llvm-project/lldb/source/Symbol/CompileUnit.cpp index 822f0df4da37..588ed4976d65 100644 --- a/contrib/llvm-project/lldb/source/Symbol/CompileUnit.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/CompileUnit.cpp @@ -224,18 +224,24 @@ uint32_t CompileUnit::FindLineEntry(uint32_t start_idx, uint32_t line, if (file_indexes.empty()) return UINT32_MAX; + // TODO: Handle SourceLocationSpec column information + SourceLocationSpec location_spec(*file_spec_ptr, line, /*column=*/llvm::None, + /*check_inlines=*/false, exact); + LineTable *line_table = GetLineTable(); if (line_table) return line_table->FindLineEntryIndexByFileIndex( - start_idx, file_indexes, line, exact, line_entry_ptr); + start_idx, file_indexes, location_spec, line_entry_ptr); return UINT32_MAX; } -void CompileUnit::ResolveSymbolContext(const FileSpec &file_spec, - uint32_t line, bool check_inlines, - bool exact, - SymbolContextItem resolve_scope, - SymbolContextList &sc_list) { +void CompileUnit::ResolveSymbolContext( + const SourceLocationSpec &src_location_spec, + SymbolContextItem resolve_scope, SymbolContextList &sc_list) { + const FileSpec file_spec = src_location_spec.GetFileSpec(); + const uint32_t line = src_location_spec.GetLine().getValueOr(0); + const bool check_inlines = src_location_spec.GetCheckInlines(); + // First find all of the file indexes that match our "file_spec". If // "file_spec" has an empty directory, then only compare the basenames when // finding file indexes @@ -248,6 +254,18 @@ void CompileUnit::ResolveSymbolContext(const FileSpec &file_spec, if (!file_spec_matches_cu_file_spec && !check_inlines) return; + SymbolContext sc(GetModule()); + sc.comp_unit = this; + + if (line == 0) { + if (file_spec_matches_cu_file_spec && !check_inlines) { + // only append the context if we aren't looking for inline call sites by + // file and line and if the file spec matches that of the compile unit + sc_list.Append(sc); + } + return; + } + uint32_t file_idx = GetSupportFiles().FindFileIndex(0, file_spec, true); while (file_idx != UINT32_MAX) { @@ -259,23 +277,15 @@ void CompileUnit::ResolveSymbolContext(const FileSpec &file_spec, if (num_file_indexes == 0) return; - SymbolContext sc(GetModule()); - sc.comp_unit = this; + LineTable *line_table = sc.comp_unit->GetLineTable(); - if (line == 0) { + if (line_table == nullptr) { if (file_spec_matches_cu_file_spec && !check_inlines) { - // only append the context if we aren't looking for inline call sites by - // file and line and if the file spec matches that of the compile unit sc_list.Append(sc); } return; } - LineTable *line_table = sc.comp_unit->GetLineTable(); - - if (line_table == nullptr) - return; - uint32_t line_idx; LineEntry line_entry; @@ -284,21 +294,24 @@ void CompileUnit::ResolveSymbolContext(const FileSpec &file_spec, // table function that searches for a line entries that match a single // support file index line_idx = line_table->FindLineEntryIndexByFileIndex( - 0, file_indexes.front(), line, exact, &line_entry); + 0, file_indexes.front(), src_location_spec, &line_entry); } else { // We found multiple support files that match "file_spec" so use the // line table function that searches for a line entries that match a // multiple support file indexes. - line_idx = line_table->FindLineEntryIndexByFileIndex(0, file_indexes, line, - exact, &line_entry); + line_idx = line_table->FindLineEntryIndexByFileIndex( + 0, file_indexes, src_location_spec, &line_entry); } // If "exact == true", then "found_line" will be the same as "line". If // "exact == false", the "found_line" will be the closest line entry // with a line number greater than "line" and we will use this for our // subsequent line exact matches below. - uint32_t found_line = line_entry.line; - + const bool inlines = false; + const bool exact = true; + SourceLocationSpec found_entry(line_entry.file, line_entry.line, + line_entry.column, inlines, exact); + while (line_idx != UINT32_MAX) { // If they only asked for the line entry, then we're done, we can // just copy that over. But if they wanted more than just the line @@ -313,10 +326,10 @@ void CompileUnit::ResolveSymbolContext(const FileSpec &file_spec, sc_list.Append(sc); if (num_file_indexes == 1) line_idx = line_table->FindLineEntryIndexByFileIndex( - line_idx + 1, file_indexes.front(), found_line, true, &line_entry); + line_idx + 1, file_indexes.front(), found_entry, &line_entry); else line_idx = line_table->FindLineEntryIndexByFileIndex( - line_idx + 1, file_indexes, found_line, true, &line_entry); + line_idx + 1, file_indexes, found_entry, &line_entry); } } diff --git a/contrib/llvm-project/lldb/source/Symbol/CompilerType.cpp b/contrib/llvm-project/lldb/source/Symbol/CompilerType.cpp index 4f0c3b366af5..ac98352c235e 100644 --- a/contrib/llvm-project/lldb/source/Symbol/CompilerType.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/CompilerType.cpp @@ -248,7 +248,7 @@ bool CompilerType::IsPointerToScalarType() const { bool CompilerType::IsArrayOfScalarType() const { CompilerType element_type; - if (IsArrayType(&element_type, nullptr, nullptr)) + if (IsArrayType(&element_type)) return element_type.IsScalarType(); return false; } diff --git a/contrib/llvm-project/lldb/source/Symbol/FuncUnwinders.cpp b/contrib/llvm-project/lldb/source/Symbol/FuncUnwinders.cpp index 9a2671a08e86..d67c0a828eb3 100644 --- a/contrib/llvm-project/lldb/source/Symbol/FuncUnwinders.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/FuncUnwinders.cpp @@ -55,7 +55,7 @@ FuncUnwinders::FuncUnwinders(UnwindTable &unwind_table, AddressRange range) /// destructor -FuncUnwinders::~FuncUnwinders() {} +FuncUnwinders::~FuncUnwinders() = default; UnwindPlanSP FuncUnwinders::GetUnwindPlanAtCallSite(Target &target, Thread &thread) { diff --git a/contrib/llvm-project/lldb/source/Symbol/Function.cpp b/contrib/llvm-project/lldb/source/Symbol/Function.cpp index 67013f6dd8b1..37479651fb45 100644 --- a/contrib/llvm-project/lldb/source/Symbol/Function.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/Function.cpp @@ -32,7 +32,7 @@ FunctionInfo::FunctionInfo(const char *name, const Declaration *decl_ptr) FunctionInfo::FunctionInfo(ConstString name, const Declaration *decl_ptr) : m_name(name), m_declaration(decl_ptr) {} -FunctionInfo::~FunctionInfo() {} +FunctionInfo::~FunctionInfo() = default; void FunctionInfo::Dump(Stream *s, bool show_fullpaths) const { if (m_name) @@ -74,7 +74,7 @@ InlineFunctionInfo::InlineFunctionInfo(ConstString name, : FunctionInfo(name, decl_ptr), m_mangled(mangled), m_call_decl(call_decl_ptr) {} -InlineFunctionInfo::~InlineFunctionInfo() {} +InlineFunctionInfo::~InlineFunctionInfo() = default; void InlineFunctionInfo::Dump(Stream *s, bool show_fullpaths) const { FunctionInfo::Dump(s, show_fullpaths); @@ -238,7 +238,7 @@ Function::Function(CompileUnit *comp_unit, lldb::user_id_t func_uid, assert(comp_unit != nullptr); } -Function::~Function() {} +Function::~Function() = default; void Function::GetStartLineSourceInfo(FileSpec &source_file, uint32_t &line_no) { @@ -426,17 +426,16 @@ lldb::DisassemblerSP Function::GetInstructions(const ExecutionContext &exe_ctx, bool prefer_file_cache) { ModuleSP module_sp(GetAddressRange().GetBaseAddress().GetModule()); if (module_sp && exe_ctx.HasTargetScope()) { - const bool prefer_file_cache = false; return Disassembler::DisassembleRange(module_sp->GetArchitecture(), nullptr, flavor, exe_ctx.GetTargetRef(), - GetAddressRange(), prefer_file_cache); + GetAddressRange(), !prefer_file_cache); } return lldb::DisassemblerSP(); } bool Function::GetDisassembly(const ExecutionContext &exe_ctx, - const char *flavor, bool prefer_file_cache, - Stream &strm) { + const char *flavor, Stream &strm, + bool prefer_file_cache) { lldb::DisassemblerSP disassembler_sp = GetInstructions(exe_ctx, flavor, prefer_file_cache); if (disassembler_sp) { diff --git a/contrib/llvm-project/lldb/source/Symbol/LineEntry.cpp b/contrib/llvm-project/lldb/source/Symbol/LineEntry.cpp index a3907f4dd9c0..1b2801cd0368 100644 --- a/contrib/llvm-project/lldb/source/Symbol/LineEntry.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/LineEntry.cpp @@ -14,9 +14,8 @@ using namespace lldb_private; LineEntry::LineEntry() - : range(), file(), line(LLDB_INVALID_LINE_NUMBER), column(0), - is_start_of_statement(0), is_start_of_basic_block(0), is_prologue_end(0), - is_epilogue_begin(0), is_terminal_entry(0) {} + : range(), file(), is_start_of_statement(0), is_start_of_basic_block(0), + is_prologue_end(0), is_epilogue_begin(0), is_terminal_entry(0) {} LineEntry::LineEntry(const lldb::SectionSP §ion_sp, lldb::addr_t section_offset, lldb::addr_t byte_size, @@ -253,9 +252,9 @@ AddressRange LineEntry::GetSameLineContiguousAddressRange( void LineEntry::ApplyFileMappings(lldb::TargetSP target_sp) { if (target_sp) { - // Apply any file remappings to our file - FileSpec new_file_spec; - if (target_sp->GetSourcePathMap().FindFile(original_file, new_file_spec)) - file = new_file_spec; + // Apply any file remappings to our file. + if (auto new_file_spec = + target_sp->GetSourcePathMap().FindFile(original_file)) + file = *new_file_spec; } } diff --git a/contrib/llvm-project/lldb/source/Symbol/LineTable.cpp b/contrib/llvm-project/lldb/source/Symbol/LineTable.cpp index 1d4a405ad47d..cd8d520ada78 100644 --- a/contrib/llvm-project/lldb/source/Symbol/LineTable.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/LineTable.cpp @@ -34,7 +34,7 @@ LineTable::LineTable(CompileUnit *comp_unit, } // Destructor -LineTable::~LineTable() {} +LineTable::~LineTable() = default; void LineTable::InsertLineEntry(lldb::addr_t file_addr, uint32_t line, uint16_t column, uint16_t file_idx, @@ -58,7 +58,7 @@ void LineTable::InsertLineEntry(lldb::addr_t file_addr, uint32_t line, // Dump (&s, Address::DumpStyleFileAddress); } -LineSequence::LineSequence() {} +LineSequence::LineSequence() = default; void LineTable::LineSequenceImpl::Clear() { m_entries.clear(); } @@ -303,91 +303,26 @@ bool LineTable::ConvertEntryAtIndexToLineEntry(uint32_t idx, } uint32_t LineTable::FindLineEntryIndexByFileIndex( - uint32_t start_idx, const std::vector<uint32_t> &file_indexes, - uint32_t line, bool exact, LineEntry *line_entry_ptr) { - - const size_t count = m_entries.size(); - size_t best_match = UINT32_MAX; - - for (size_t idx = start_idx; idx < count; ++idx) { - // Skip line table rows that terminate the previous row (is_terminal_entry - // is non-zero) - if (m_entries[idx].is_terminal_entry) - continue; - - if (!llvm::is_contained(file_indexes, m_entries[idx].file_idx)) - continue; - - // Exact match always wins. Otherwise try to find the closest line > the - // desired line. - // FIXME: Maybe want to find the line closest before and the line closest - // after and - // if they're not in the same function, don't return a match. - - if (m_entries[idx].line < line) { - continue; - } else if (m_entries[idx].line == line) { - if (line_entry_ptr) - ConvertEntryAtIndexToLineEntry(idx, *line_entry_ptr); - return idx; - } else if (!exact) { - if (best_match == UINT32_MAX) - best_match = idx; - else if (m_entries[idx].line < m_entries[best_match].line) - best_match = idx; - } - } - - if (best_match != UINT32_MAX) { - if (line_entry_ptr) - ConvertEntryAtIndexToLineEntry(best_match, *line_entry_ptr); - return best_match; - } - return UINT32_MAX; + uint32_t start_idx, uint32_t file_idx, + const SourceLocationSpec &src_location_spec, LineEntry *line_entry_ptr) { + auto file_idx_matcher = [](uint32_t file_index, uint16_t entry_file_idx) { + return file_index == entry_file_idx; + }; + return FindLineEntryIndexByFileIndexImpl<uint32_t>( + + start_idx, file_idx, src_location_spec, line_entry_ptr, file_idx_matcher); } -uint32_t LineTable::FindLineEntryIndexByFileIndex(uint32_t start_idx, - uint32_t file_idx, - uint32_t line, bool exact, - LineEntry *line_entry_ptr) { - const size_t count = m_entries.size(); - size_t best_match = UINT32_MAX; - - for (size_t idx = start_idx; idx < count; ++idx) { - // Skip line table rows that terminate the previous row (is_terminal_entry - // is non-zero) - if (m_entries[idx].is_terminal_entry) - continue; - - if (m_entries[idx].file_idx != file_idx) - continue; - - // Exact match always wins. Otherwise try to find the closest line > the - // desired line. - // FIXME: Maybe want to find the line closest before and the line closest - // after and - // if they're not in the same function, don't return a match. - - if (m_entries[idx].line < line) { - continue; - } else if (m_entries[idx].line == line) { - if (line_entry_ptr) - ConvertEntryAtIndexToLineEntry(idx, *line_entry_ptr); - return idx; - } else if (!exact) { - if (best_match == UINT32_MAX) - best_match = idx; - else if (m_entries[idx].line < m_entries[best_match].line) - best_match = idx; - } - } - - if (best_match != UINT32_MAX) { - if (line_entry_ptr) - ConvertEntryAtIndexToLineEntry(best_match, *line_entry_ptr); - return best_match; - } - return UINT32_MAX; +uint32_t LineTable::FindLineEntryIndexByFileIndex( + uint32_t start_idx, const std::vector<uint32_t> &file_idx, + const SourceLocationSpec &src_location_spec, LineEntry *line_entry_ptr) { + auto file_idx_matcher = [](const std::vector<uint32_t> &file_indexes, + uint16_t entry_file_idx) { + return llvm::is_contained(file_indexes, entry_file_idx); + }; + + return FindLineEntryIndexByFileIndexImpl<std::vector<uint32_t>>( + start_idx, file_idx, src_location_spec, line_entry_ptr, file_idx_matcher); } size_t LineTable::FineLineEntriesForFileIndex(uint32_t file_idx, bool append, diff --git a/contrib/llvm-project/lldb/source/Symbol/ObjectFile.cpp b/contrib/llvm-project/lldb/source/Symbol/ObjectFile.cpp index f5dcbc5467f7..101af01341a2 100644 --- a/contrib/llvm-project/lldb/source/Symbol/ObjectFile.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/ObjectFile.cpp @@ -616,14 +616,6 @@ ObjectFile::GetSymbolTypeFromName(llvm::StringRef name, return symbol_type_hint; } -ConstString ObjectFile::GetNextSyntheticSymbolName() { - StreamString ss; - ConstString file_name = GetModule()->GetFileSpec().GetFilename(); - ss.Printf("___lldb_unnamed_symbol%u$$%s", ++m_synthetic_symbol_idx, - file_name.GetCString()); - return ConstString(ss.GetString()); -} - std::vector<ObjectFile::LoadableData> ObjectFile::GetLoadableData(Target &target) { std::vector<LoadableData> loadables; diff --git a/contrib/llvm-project/lldb/source/Symbol/Symbol.cpp b/contrib/llvm-project/lldb/source/Symbol/Symbol.cpp index 8d099e0cc7e1..251f9104ad54 100644 --- a/contrib/llvm-project/lldb/source/Symbol/Symbol.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/Symbol.cpp @@ -23,13 +23,12 @@ using namespace lldb; using namespace lldb_private; Symbol::Symbol() - : SymbolContextScope(), m_uid(UINT32_MAX), m_type_data(0), - m_type_data_resolved(false), m_is_synthetic(false), m_is_debug(false), - m_is_external(false), m_size_is_sibling(false), + : SymbolContextScope(), m_type_data_resolved(false), m_is_synthetic(false), + m_is_debug(false), m_is_external(false), m_size_is_sibling(false), m_size_is_synthesized(false), m_size_is_valid(false), m_demangled_is_synthesized(false), m_contains_linker_annotations(false), - m_is_weak(false), m_type(eSymbolTypeInvalid), m_mangled(), m_addr_range(), - m_flags() {} + m_is_weak(false), m_type(eSymbolTypeInvalid), m_mangled(), + m_addr_range() {} Symbol::Symbol(uint32_t symID, llvm::StringRef name, SymbolType type, bool external, bool is_debug, bool is_trampoline, bool is_artificial, @@ -57,8 +56,8 @@ Symbol::Symbol(uint32_t symID, const Mangled &mangled, SymbolType type, m_size_is_synthesized(false), m_size_is_valid(size_is_valid || range.GetByteSize() > 0), m_demangled_is_synthesized(false), - m_contains_linker_annotations(contains_linker_annotations), - m_is_weak(false), m_type(type), m_mangled(mangled), m_addr_range(range), + m_contains_linker_annotations(contains_linker_annotations), + m_is_weak(false), m_type(type), m_mangled(mangled), m_addr_range(range), m_flags(flags) {} Symbol::Symbol(const Symbol &rhs) @@ -120,7 +119,7 @@ bool Symbol::ValueIsAddress() const { } ConstString Symbol::GetDisplayName() const { - return m_mangled.GetDisplayDemangledName(); + return GetMangled().GetDisplayDemangledName(); } ConstString Symbol::GetReExportedSymbolName() const { @@ -203,7 +202,7 @@ void Symbol::GetDescription(Stream *s, lldb::DescriptionLevel level, s->Printf(", value = 0x%16.16" PRIx64, m_addr_range.GetBaseAddress().GetOffset()); } - ConstString demangled = m_mangled.GetDemangledName(); + ConstString demangled = GetMangled().GetDemangledName(); if (demangled) s->Printf(", name=\"%s\"", demangled.AsCString()); if (m_mangled.GetMangledName()) @@ -219,7 +218,7 @@ void Symbol::Dump(Stream *s, Target *target, uint32_t index, // Make sure the size of the symbol is up to date before dumping GetByteSize(); - ConstString name = m_mangled.GetName(name_preference); + ConstString name = GetMangled().GetName(name_preference); if (ValueIsAddress()) { if (!m_addr_range.GetBaseAddress().Dump(s, nullptr, Address::DumpStyleFileAddress)) @@ -331,9 +330,11 @@ uint32_t Symbol::GetPrologueByteSize() { } bool Symbol::Compare(ConstString name, SymbolType type) const { - if (type == eSymbolTypeAny || m_type == type) - return m_mangled.GetMangledName() == name || - m_mangled.GetDemangledName() == name; + if (type == eSymbolTypeAny || m_type == type) { + const Mangled &mangled = GetMangled(); + return mangled.GetMangledName() == name || + mangled.GetDemangledName() == name; + } return false; } @@ -496,10 +497,10 @@ lldb::addr_t Symbol::GetLoadAddress(Target *target) const { return LLDB_INVALID_ADDRESS; } -ConstString Symbol::GetName() const { return m_mangled.GetName(); } +ConstString Symbol::GetName() const { return GetMangled().GetName(); } ConstString Symbol::GetNameNoArguments() const { - return m_mangled.GetName(Mangled::ePreferDemangledWithoutArguments); + return GetMangled().GetName(Mangled::ePreferDemangledWithoutArguments); } lldb::addr_t Symbol::ResolveCallableAddress(Target &target) const { @@ -542,10 +543,9 @@ lldb::DisassemblerSP Symbol::GetInstructions(const ExecutionContext &exe_ctx, bool prefer_file_cache) { ModuleSP module_sp(m_addr_range.GetBaseAddress().GetModule()); if (module_sp && exe_ctx.HasTargetScope()) { - const bool prefer_file_cache = false; return Disassembler::DisassembleRange(module_sp->GetArchitecture(), nullptr, flavor, exe_ctx.GetTargetRef(), - m_addr_range, prefer_file_cache); + m_addr_range, !prefer_file_cache); } return lldb::DisassemblerSP(); } @@ -567,3 +567,30 @@ bool Symbol::GetDisassembly(const ExecutionContext &exe_ctx, const char *flavor, bool Symbol::ContainsFileAddress(lldb::addr_t file_addr) const { return m_addr_range.ContainsFileAddress(file_addr); } + +bool Symbol::IsSyntheticWithAutoGeneratedName() const { + if (!IsSynthetic()) + return false; + if (!m_mangled) + return true; + ConstString demangled = m_mangled.GetDemangledName(); + return demangled.GetStringRef().startswith(GetSyntheticSymbolPrefix()); +} + +void Symbol::SynthesizeNameIfNeeded() const { + if (m_is_synthetic && !m_mangled) { + // Synthetic symbol names don't mean anything, but they do uniquely + // identify individual symbols so we give them a unique name. The name + // starts with the synthetic symbol prefix, followed by a unique number. + // Typically the UserID of a real symbol is the symbol table index of the + // symbol in the object file's symbol table(s), so it will be the same + // every time you read in the object file. We want the same persistence for + // synthetic symbols so that users can identify them across multiple debug + // sessions, to understand crashes in those symbols and to reliably set + // breakpoints on them. + llvm::SmallString<256> name; + llvm::raw_svector_ostream os(name); + os << GetSyntheticSymbolPrefix() << GetID(); + m_mangled.SetDemangledName(ConstString(os.str())); + } +} diff --git a/contrib/llvm-project/lldb/source/Symbol/SymbolContext.cpp b/contrib/llvm-project/lldb/source/Symbol/SymbolContext.cpp index 8cfea35180fa..2e8fe1cec30e 100644 --- a/contrib/llvm-project/lldb/source/Symbol/SymbolContext.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/SymbolContext.cpp @@ -26,9 +26,7 @@ using namespace lldb; using namespace lldb_private; -SymbolContext::SymbolContext() - : target_sp(), module_sp(), comp_unit(nullptr), function(nullptr), - block(nullptr), line_entry(), symbol(nullptr), variable(nullptr) {} +SymbolContext::SymbolContext() : target_sp(), module_sp(), line_entry() {} SymbolContext::SymbolContext(const ModuleSP &m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) @@ -53,7 +51,7 @@ SymbolContext::SymbolContext(SymbolContextScope *sc_scope) sc_scope->CalculateSymbolContext(this); } -SymbolContext::~SymbolContext() {} +SymbolContext::~SymbolContext() = default; void SymbolContext::Clear(bool clear_target) { if (clear_target) @@ -71,8 +69,7 @@ bool SymbolContext::DumpStopContext(Stream *s, ExecutionContextScope *exe_scope, const Address &addr, bool show_fullpaths, bool show_module, bool show_inlined_frames, bool show_function_arguments, - bool show_function_name, - bool show_inline_callsite_line_info) const { + bool show_function_name) const { bool dumped_something = false; if (show_module && module_sp) { if (show_fullpaths) @@ -128,13 +125,14 @@ bool SymbolContext::DumpStopContext(Stream *s, ExecutionContextScope *exe_scope, s->Printf(" + %" PRIu64, inlined_function_offset); } } - if (show_inline_callsite_line_info) { - const Declaration &call_site = inlined_block_info->GetCallSite(); - if (call_site.IsValid()) { - s->PutCString(" at "); - call_site.DumpStopContext(s, show_fullpaths); - } - } else if (line_entry.IsValid()) { + // "line_entry" will always be valid as GetParentOfInlinedScope(...) will + // fill it in correctly with the calling file and line. Previous code + // was extracting the calling file and line from inlined_block_info and + // using it right away which is not correct. On the first call to this + // function "line_entry" will contain the actual line table entry. On + // susequent calls "line_entry" will contain the calling file and line + // from the previous inline info. + if (line_entry.IsValid()) { s->PutCString(" at "); line_entry.DumpStopContext(s, show_fullpaths); } @@ -928,7 +926,7 @@ SymbolContextSpecifier::SymbolContextSpecifier(const TargetSP &target_sp) m_start_line(0), m_end_line(0), m_function_spec(), m_class_name(), m_address_range_up(), m_type(eNothingSpecified) {} -SymbolContextSpecifier::~SymbolContextSpecifier() {} +SymbolContextSpecifier::~SymbolContextSpecifier() = default; bool SymbolContextSpecifier::AddLineSpecification(uint32_t line_no, SpecificationType type) { @@ -1188,7 +1186,7 @@ void SymbolContextSpecifier::GetDescription( SymbolContextList::SymbolContextList() : m_symbol_contexts() {} -SymbolContextList::~SymbolContextList() {} +SymbolContextList::~SymbolContextList() = default; void SymbolContextList::Append(const SymbolContext &sc) { m_symbol_contexts.push_back(sc); diff --git a/contrib/llvm-project/lldb/source/Symbol/SymbolFile.cpp b/contrib/llvm-project/lldb/source/Symbol/SymbolFile.cpp index 3f9cdefc8d41..152bbe8de6cb 100644 --- a/contrib/llvm-project/lldb/source/Symbol/SymbolFile.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/SymbolFile.cpp @@ -97,10 +97,10 @@ SymbolFile::GetTypeSystemForLanguage(lldb::LanguageType language) { return type_system_or_err; } -uint32_t SymbolFile::ResolveSymbolContext(const FileSpec &file_spec, - uint32_t line, bool check_inlines, - lldb::SymbolContextItem resolve_scope, - SymbolContextList &sc_list) { +uint32_t +SymbolFile::ResolveSymbolContext(const SourceLocationSpec &src_location_spec, + lldb::SymbolContextItem resolve_scope, + SymbolContextList &sc_list) { return 0; } diff --git a/contrib/llvm-project/lldb/source/Symbol/Symtab.cpp b/contrib/llvm-project/lldb/source/Symbol/Symtab.cpp index 7f8424334708..313b451601ae 100644 --- a/contrib/llvm-project/lldb/source/Symbol/Symtab.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/Symtab.cpp @@ -9,8 +9,6 @@ #include <map> #include <set> -#include "Plugins/Language/ObjC/ObjCLanguage.h" - #include "lldb/Core/Module.h" #include "lldb/Core/RichManglingContext.h" #include "lldb/Core/Section.h" @@ -18,6 +16,7 @@ #include "lldb/Symbol/Symbol.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/Symtab.h" +#include "lldb/Target/Language.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/Timer.h" @@ -29,10 +28,19 @@ using namespace lldb_private; Symtab::Symtab(ObjectFile *objfile) : m_objfile(objfile), m_symbols(), m_file_addr_to_index(*this), - m_name_to_index(), m_mutex(), m_file_addr_to_index_computed(false), - m_name_indexes_computed(false) {} + m_name_to_symbol_indices(), m_mutex(), + m_file_addr_to_index_computed(false), m_name_indexes_computed(false) { + m_name_to_symbol_indices.emplace(std::make_pair( + lldb::eFunctionNameTypeNone, UniqueCStringMap<uint32_t>())); + m_name_to_symbol_indices.emplace(std::make_pair( + lldb::eFunctionNameTypeBase, UniqueCStringMap<uint32_t>())); + m_name_to_symbol_indices.emplace(std::make_pair( + lldb::eFunctionNameTypeMethod, UniqueCStringMap<uint32_t>())); + m_name_to_symbol_indices.emplace(std::make_pair( + lldb::eFunctionNameTypeSelector, UniqueCStringMap<uint32_t>())); +} -Symtab::~Symtab() {} +Symtab::~Symtab() = default; void Symtab::Reserve(size_t count) { // Clients should grab the mutex from this symbol table and lock it manually @@ -51,7 +59,8 @@ uint32_t Symtab::AddSymbol(const Symbol &symbol) { // Clients should grab the mutex from this symbol table and lock it manually // when calling this function to avoid performance issues. uint32_t symbol_idx = m_symbols.size(); - m_name_to_index.Clear(); + auto &name_to_index = GetNameToSymbolIndexMap(lldb::eFunctionNameTypeNone); + name_to_index.Clear(); m_file_addr_to_index.Clear(); m_symbols.push_back(symbol); m_file_addr_to_index_computed = false; @@ -65,7 +74,8 @@ size_t Symtab::GetNumSymbols() const { } void Symtab::SectionFileAddressesChanged() { - m_name_to_index.Clear(); + auto &name_to_index = GetNameToSymbolIndexMap(lldb::eFunctionNameTypeNone); + name_to_index.Clear(); m_file_addr_to_index_computed = false; } @@ -240,6 +250,10 @@ static bool lldb_skip_name(llvm::StringRef mangled, case Mangled::eManglingSchemeMSVC: return false; + // No filters for this scheme yet. Include all names in indexing. + case Mangled::eManglingSchemeRustV0: + return false; + // Don't try and demangle things we can't categorize. case Mangled::eManglingSchemeNone: return true; @@ -252,9 +266,24 @@ void Symtab::InitNameIndexes() { if (!m_name_indexes_computed) { m_name_indexes_computed = true; LLDB_SCOPED_TIMER(); + + // Collect all loaded language plugins. + std::vector<Language *> languages; + Language::ForEach([&languages](Language *l) { + languages.push_back(l); + return true; + }); + + auto &name_to_index = GetNameToSymbolIndexMap(lldb::eFunctionNameTypeNone); + auto &basename_to_index = + GetNameToSymbolIndexMap(lldb::eFunctionNameTypeBase); + auto &method_to_index = + GetNameToSymbolIndexMap(lldb::eFunctionNameTypeMethod); + auto &selector_to_index = + GetNameToSymbolIndexMap(lldb::eFunctionNameTypeSelector); // Create the name index vector to be able to quickly search by name const size_t num_symbols = m_symbols.size(); - m_name_to_index.Reserve(num_symbols); + name_to_index.Reserve(num_symbols); // The "const char *" in "class_contexts" and backlog::value_type::second // must come from a ConstString::GetCString() @@ -271,22 +300,24 @@ void Symtab::InitNameIndexes() { // Don't let trampolines get into the lookup by name map If we ever need // the trampoline symbols to be searchable by name we can remove this and // then possibly add a new bool to any of the Symtab functions that - // lookup symbols by name to indicate if they want trampolines. - if (symbol->IsTrampoline()) + // lookup symbols by name to indicate if they want trampolines. We also + // don't want any synthetic symbols with auto generated names in the + // name lookups. + if (symbol->IsTrampoline() || symbol->IsSyntheticWithAutoGeneratedName()) continue; // If the symbol's name string matched a Mangled::ManglingScheme, it is // stored in the mangled field. Mangled &mangled = symbol->GetMangled(); if (ConstString name = mangled.GetMangledName()) { - m_name_to_index.Append(name, value); + name_to_index.Append(name, value); if (symbol->ContainsLinkerAnnotations()) { // If the symbol has linker annotations, also add the version without // the annotations. ConstString stripped = ConstString( m_objfile->StripLinkerSymbolAnnotations(name.GetStringRef())); - m_name_to_index.Append(stripped, value); + name_to_index.Append(stripped, value); } const SymbolType type = symbol->GetType(); @@ -299,25 +330,29 @@ void Symtab::InitNameIndexes() { // Symbol name strings that didn't match a Mangled::ManglingScheme, are // stored in the demangled field. if (ConstString name = mangled.GetDemangledName()) { - m_name_to_index.Append(name, value); + name_to_index.Append(name, value); if (symbol->ContainsLinkerAnnotations()) { // If the symbol has linker annotations, also add the version without // the annotations. name = ConstString( m_objfile->StripLinkerSymbolAnnotations(name.GetStringRef())); - m_name_to_index.Append(name, value); + name_to_index.Append(name, value); } // If the demangled name turns out to be an ObjC name, and is a category // name, add the version without categories to the index too. - ObjCLanguage::MethodName objc_method(name.GetStringRef(), true); - if (objc_method.IsValid(true)) { - m_selector_to_index.Append(objc_method.GetSelector(), value); - - if (ConstString objc_method_no_category = - objc_method.GetFullNameWithoutCategory(true)) - m_name_to_index.Append(objc_method_no_category, value); + for (Language *lang : languages) { + for (auto variant : lang->GetMethodNameVariants(name)) { + if (variant.GetType() & lldb::eFunctionNameTypeSelector) + selector_to_index.Append(variant.GetName(), value); + else if (variant.GetType() & lldb::eFunctionNameTypeFull) + name_to_index.Append(variant.GetName(), value); + else if (variant.GetType() & lldb::eFunctionNameTypeMethod) + method_to_index.Append(variant.GetName(), value); + else if (variant.GetType() & lldb::eFunctionNameTypeBase) + basename_to_index.Append(variant.GetName(), value); + } } } } @@ -326,14 +361,14 @@ void Symtab::InitNameIndexes() { RegisterBacklogEntry(record.first, record.second, class_contexts); } - m_name_to_index.Sort(); - m_name_to_index.SizeToFit(); - m_selector_to_index.Sort(); - m_selector_to_index.SizeToFit(); - m_basename_to_index.Sort(); - m_basename_to_index.SizeToFit(); - m_method_to_index.Sort(); - m_method_to_index.SizeToFit(); + name_to_index.Sort(); + name_to_index.SizeToFit(); + selector_to_index.Sort(); + selector_to_index.SizeToFit(); + basename_to_index.Sort(); + basename_to_index.SizeToFit(); + method_to_index.Sort(); + method_to_index.SizeToFit(); } } @@ -356,10 +391,13 @@ void Symtab::RegisterMangledNameEntry( // Register functions with no context. if (decl_context.empty()) { // This has to be a basename - m_basename_to_index.Append(entry); + auto &basename_to_index = + GetNameToSymbolIndexMap(lldb::eFunctionNameTypeBase); + basename_to_index.Append(entry); // If there is no context (no namespaces or class scopes that come before // the function name) then this also could be a fullname. - m_name_to_index.Append(entry); + auto &name_to_index = GetNameToSymbolIndexMap(lldb::eFunctionNameTypeNone); + name_to_index.Append(entry); return; } @@ -368,10 +406,12 @@ void Symtab::RegisterMangledNameEntry( const char *decl_context_ccstr = ConstString(decl_context).GetCString(); auto it = class_contexts.find(decl_context_ccstr); + auto &method_to_index = + GetNameToSymbolIndexMap(lldb::eFunctionNameTypeMethod); // Register constructors and destructors. They are methods and create // declaration contexts. if (rmc.IsCtorOrDtor()) { - m_method_to_index.Append(entry); + method_to_index.Append(entry); if (it == class_contexts.end()) class_contexts.insert(it, decl_context_ccstr); return; @@ -379,7 +419,7 @@ void Symtab::RegisterMangledNameEntry( // Register regular methods with a known declaration context. if (it != class_contexts.end()) { - m_method_to_index.Append(entry); + method_to_index.Append(entry); return; } @@ -391,14 +431,18 @@ void Symtab::RegisterMangledNameEntry( void Symtab::RegisterBacklogEntry( const NameToIndexMap::Entry &entry, const char *decl_context, const std::set<const char *> &class_contexts) { + auto &method_to_index = + GetNameToSymbolIndexMap(lldb::eFunctionNameTypeMethod); auto it = class_contexts.find(decl_context); if (it != class_contexts.end()) { - m_method_to_index.Append(entry); + method_to_index.Append(entry); } else { // If we got here, we have something that had a context (was inside // a namespace or class) yet we don't know the entry - m_method_to_index.Append(entry); - m_basename_to_index.Append(entry); + method_to_index.Append(entry); + auto &basename_to_index = + GetNameToSymbolIndexMap(lldb::eFunctionNameTypeBase); + basename_to_index.Append(entry); } } @@ -586,6 +630,36 @@ void Symtab::SortSymbolIndexesByValue(std::vector<uint32_t> &indexes, } } +uint32_t Symtab::GetNameIndexes(ConstString symbol_name, + std::vector<uint32_t> &indexes) { + auto &name_to_index = GetNameToSymbolIndexMap(lldb::eFunctionNameTypeNone); + const uint32_t count = name_to_index.GetValues(symbol_name, indexes); + if (count) + return count; + // Synthetic symbol names are not added to the name indexes, but they start + // with a prefix and end with a the symbol UserID. This allows users to find + // these symbols without having to add them to the name indexes. These + // queries will not happen very often since the names don't mean anything, so + // performance is not paramount in this case. + llvm::StringRef name = symbol_name.GetStringRef(); + // String the synthetic prefix if the name starts with it. + if (!name.consume_front(Symbol::GetSyntheticSymbolPrefix())) + return 0; // Not a synthetic symbol name + + // Extract the user ID from the symbol name + unsigned long long uid = 0; + if (getAsUnsignedInteger(name, /*Radix=*/10, uid)) + return 0; // Failed to extract the user ID as an integer + Symbol *symbol = FindSymbolByID(uid); + if (symbol == nullptr) + return 0; + const uint32_t symbol_idx = GetIndexForSymbol(symbol); + if (symbol_idx == UINT32_MAX) + return 0; + indexes.push_back(symbol_idx); + return 1; +} + uint32_t Symtab::AppendSymbolIndexesWithName(ConstString symbol_name, std::vector<uint32_t> &indexes) { std::lock_guard<std::recursive_mutex> guard(m_mutex); @@ -595,7 +669,7 @@ uint32_t Symtab::AppendSymbolIndexesWithName(ConstString symbol_name, if (!m_name_indexes_computed) InitNameIndexes(); - return m_name_to_index.GetValues(symbol_name, indexes); + return GetNameIndexes(symbol_name, indexes); } return 0; } @@ -614,7 +688,7 @@ uint32_t Symtab::AppendSymbolIndexesWithName(ConstString symbol_name, std::vector<uint32_t> all_name_indexes; const size_t name_match_count = - m_name_to_index.GetValues(symbol_name, all_name_indexes); + GetNameIndexes(symbol_name, all_name_indexes); for (size_t i = 0; i < name_match_count; ++i) { if (CheckSymbolAtIndex(all_name_indexes[i], symbol_debug_type, symbol_visibility)) @@ -1035,45 +1109,18 @@ void Symtab::FindFunctionSymbols(ConstString name, uint32_t name_type_mask, } } - if (name_type_mask & eFunctionNameTypeBase) { - // From mangled names we can't tell what is a basename and what is a method - // name, so we just treat them the same - if (!m_name_indexes_computed) - InitNameIndexes(); - - if (!m_basename_to_index.IsEmpty()) { - const UniqueCStringMap<uint32_t>::Entry *match; - for (match = m_basename_to_index.FindFirstValueForName(name); - match != nullptr; - match = m_basename_to_index.FindNextValueForName(match)) { - symbol_indexes.push_back(match->value); - } - } - } - - if (name_type_mask & eFunctionNameTypeMethod) { - if (!m_name_indexes_computed) - InitNameIndexes(); - - if (!m_method_to_index.IsEmpty()) { - const UniqueCStringMap<uint32_t>::Entry *match; - for (match = m_method_to_index.FindFirstValueForName(name); - match != nullptr; - match = m_method_to_index.FindNextValueForName(match)) { - symbol_indexes.push_back(match->value); - } - } - } + if (!m_name_indexes_computed) + InitNameIndexes(); - if (name_type_mask & eFunctionNameTypeSelector) { - if (!m_name_indexes_computed) - InitNameIndexes(); + for (lldb::FunctionNameType type : + {lldb::eFunctionNameTypeBase, lldb::eFunctionNameTypeMethod, + lldb::eFunctionNameTypeSelector}) { + if (name_type_mask & type) { + auto map = GetNameToSymbolIndexMap(type); - if (!m_selector_to_index.IsEmpty()) { const UniqueCStringMap<uint32_t>::Entry *match; - for (match = m_selector_to_index.FindFirstValueForName(name); - match != nullptr; - match = m_selector_to_index.FindNextValueForName(match)) { + for (match = map.FindFirstValueForName(name); match != nullptr; + match = map.FindNextValueForName(match)) { symbol_indexes.push_back(match->value); } } diff --git a/contrib/llvm-project/lldb/source/Symbol/Type.cpp b/contrib/llvm-project/lldb/source/Symbol/Type.cpp index df5dab19dbf3..5b4169d256d2 100644 --- a/contrib/llvm-project/lldb/source/Symbol/Type.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/Type.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include <stdio.h> +#include <cstdio> #include "lldb/Core/Module.h" #include "lldb/Utility/DataBufferHeap.h" @@ -161,10 +161,8 @@ Type::Type(lldb::user_id_t uid, SymbolFile *symbol_file, ConstString name, } Type::Type() - : std::enable_shared_from_this<Type>(), UserID(0), m_name("<INVALID TYPE>"), - m_symbol_file(nullptr), m_context(nullptr), m_encoding_type(nullptr), - m_encoding_uid(LLDB_INVALID_UID), m_encoding_uid_type(eEncodingInvalid), - m_compiler_type_resolve_state(ResolveState::Unresolved) { + : std::enable_shared_from_this<Type>(), UserID(0), + m_name("<INVALID TYPE>") { m_byte_size = 0; m_byte_size_has_value = false; } @@ -730,7 +728,8 @@ ModuleSP Type::GetModule() { ModuleSP Type::GetExeModule() { if (m_compiler_type) { SymbolFile *symbol_file = m_compiler_type.GetTypeSystem()->GetSymbolFile(); - return symbol_file->GetObjectFile()->GetModule(); + if (symbol_file) + return symbol_file->GetObjectFile()->GetModule(); } return ModuleSP(); } diff --git a/contrib/llvm-project/lldb/source/Symbol/TypeList.cpp b/contrib/llvm-project/lldb/source/Symbol/TypeList.cpp index f0506c7c5bfc..ace715d933ea 100644 --- a/contrib/llvm-project/lldb/source/Symbol/TypeList.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/TypeList.cpp @@ -22,7 +22,7 @@ using namespace lldb_private; TypeList::TypeList() : m_types() {} // Destructor -TypeList::~TypeList() {} +TypeList::~TypeList() = default; void TypeList::Insert(const TypeSP &type_sp) { // Just push each type on the back for now. We will worry about uniquing diff --git a/contrib/llvm-project/lldb/source/Symbol/TypeMap.cpp b/contrib/llvm-project/lldb/source/Symbol/TypeMap.cpp index e810d3020073..2cda9b6c27d1 100644 --- a/contrib/llvm-project/lldb/source/Symbol/TypeMap.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/TypeMap.cpp @@ -22,7 +22,7 @@ using namespace lldb_private; TypeMap::TypeMap() : m_types() {} // Destructor -TypeMap::~TypeMap() {} +TypeMap::~TypeMap() = default; void TypeMap::Insert(const TypeSP &type_sp) { // Just push each type on the back for now. We will worry about uniquing diff --git a/contrib/llvm-project/lldb/source/Symbol/TypeSystem.cpp b/contrib/llvm-project/lldb/source/Symbol/TypeSystem.cpp index 83161f32444c..0b3f7e4f3bd4 100644 --- a/contrib/llvm-project/lldb/source/Symbol/TypeSystem.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/TypeSystem.cpp @@ -35,7 +35,7 @@ size_t LanguageSet::Size() const { return bitvector.count(); } bool LanguageSet::Empty() const { return bitvector.none(); } bool LanguageSet::operator[](unsigned i) const { return bitvector[i]; } -TypeSystem::~TypeSystem() {} +TypeSystem::~TypeSystem() = default; static lldb::TypeSystemSP CreateInstanceHelper(lldb::LanguageType language, Module *module, Target *target) { @@ -178,10 +178,9 @@ TypeSystem::CreateUtilityFunction(std::string text, std::string name) { #pragma mark TypeSystemMap -TypeSystemMap::TypeSystemMap() - : m_mutex(), m_map(), m_clear_in_progress(false) {} +TypeSystemMap::TypeSystemMap() : m_mutex(), m_map() {} -TypeSystemMap::~TypeSystemMap() {} +TypeSystemMap::~TypeSystemMap() = default; void TypeSystemMap::Clear() { collection map; diff --git a/contrib/llvm-project/lldb/source/Symbol/UnwindPlan.cpp b/contrib/llvm-project/lldb/source/Symbol/UnwindPlan.cpp index d24cabed14ce..41bd8cd46ad8 100644 --- a/contrib/llvm-project/lldb/source/Symbol/UnwindPlan.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/UnwindPlan.cpp @@ -217,6 +217,7 @@ void UnwindPlan::Row::Clear() { m_cfa_value.SetUnspecified(); m_afa_value.SetUnspecified(); m_offset = 0; + m_unspecified_registers_are_undefined = false; m_register_locations.clear(); } @@ -242,11 +243,9 @@ void UnwindPlan::Row::Dump(Stream &s, const UnwindPlan *unwind_plan, idx->second.Dump(s, unwind_plan, this, thread, verbose); s.PutChar(' '); } - s.EOL(); } -UnwindPlan::Row::Row() - : m_offset(0), m_cfa_value(), m_afa_value(), m_register_locations() {} +UnwindPlan::Row::Row() : m_cfa_value(), m_afa_value(), m_register_locations() {} bool UnwindPlan::Row::GetRegisterInfo( uint32_t reg_num, @@ -256,6 +255,10 @@ bool UnwindPlan::Row::GetRegisterInfo( register_location = pos->second; return true; } + if (m_unspecified_registers_are_undefined) { + register_location.SetUndefined(); + return true; + } return false; } @@ -348,10 +351,11 @@ bool UnwindPlan::Row::SetRegisterLocationToSame(uint32_t reg_num, } bool UnwindPlan::Row::operator==(const UnwindPlan::Row &rhs) const { - return m_offset == rhs.m_offset && - m_cfa_value == rhs.m_cfa_value && - m_afa_value == rhs.m_afa_value && - m_register_locations == rhs.m_register_locations; + return m_offset == rhs.m_offset && m_cfa_value == rhs.m_cfa_value && + m_afa_value == rhs.m_afa_value && + m_unspecified_registers_are_undefined == + rhs.m_unspecified_registers_are_undefined && + m_register_locations == rhs.m_register_locations; } void UnwindPlan::AppendRow(const UnwindPlan::RowSP &row_sp) { @@ -552,6 +556,7 @@ void UnwindPlan::Dump(Stream &s, Thread *thread, lldb::addr_t base_addr) const { for (pos = begin; pos != end; ++pos) { s.Printf("row[%u]: ", (uint32_t)std::distance(begin, pos)); (*pos)->Dump(s, this, thread, base_addr); + s.Printf("\n"); } } diff --git a/contrib/llvm-project/lldb/source/Symbol/UnwindTable.cpp b/contrib/llvm-project/lldb/source/Symbol/UnwindTable.cpp index 3faa528a339f..fe69e41b3638 100644 --- a/contrib/llvm-project/lldb/source/Symbol/UnwindTable.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/UnwindTable.cpp @@ -8,7 +8,7 @@ #include "lldb/Symbol/UnwindTable.h" -#include <stdio.h> +#include <cstdio> #include "lldb/Core/Module.h" #include "lldb/Core/Section.h" @@ -83,7 +83,7 @@ void UnwindTable::Initialize() { } } -UnwindTable::~UnwindTable() {} +UnwindTable::~UnwindTable() = default; llvm::Optional<AddressRange> UnwindTable::GetAddressRange(const Address &addr, SymbolContext &sc) { diff --git a/contrib/llvm-project/lldb/source/Symbol/Variable.cpp b/contrib/llvm-project/lldb/source/Symbol/Variable.cpp index 62b16011fe66..89682fc39141 100644 --- a/contrib/llvm-project/lldb/source/Symbol/Variable.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/Variable.cpp @@ -49,7 +49,7 @@ Variable::Variable(lldb::user_id_t uid, const char *name, const char *mangled, m_artificial(artificial), m_loc_is_const_data(location_is_constant_data), m_static_member(static_member) {} -Variable::~Variable() {} +Variable::~Variable() = default; lldb::LanguageType Variable::GetLanguage() const { lldb::LanguageType lang = m_mangled.GuessLanguage(); diff --git a/contrib/llvm-project/lldb/source/Symbol/VariableList.cpp b/contrib/llvm-project/lldb/source/Symbol/VariableList.cpp index f7a441472bc0..b7a396edd701 100644 --- a/contrib/llvm-project/lldb/source/Symbol/VariableList.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/VariableList.cpp @@ -20,7 +20,7 @@ using namespace lldb_private; VariableList::VariableList() : m_variables() {} // Destructor -VariableList::~VariableList() {} +VariableList::~VariableList() = default; void VariableList::AddVariable(const VariableSP &var_sp) { m_variables.push_back(var_sp); diff --git a/contrib/llvm-project/lldb/source/Target/ABI.cpp b/contrib/llvm-project/lldb/source/Target/ABI.cpp index f6a531136dcb..c3342caf8742 100644 --- a/contrib/llvm-project/lldb/source/Target/ABI.cpp +++ b/contrib/llvm-project/lldb/source/Target/ABI.cpp @@ -120,11 +120,13 @@ ValueObjectSP ABI::GetReturnValueObject(Thread &thread, CompilerType &ast_type, const Value &result_value = live_valobj_sp->GetValue(); switch (result_value.GetValueType()) { - case Value::eValueTypeHostAddress: - case Value::eValueTypeFileAddress: - // we don't do anything with these for now + case Value::ValueType::Invalid: + return {}; + case Value::ValueType::HostAddress: + case Value::ValueType::FileAddress: + // we odon't do anything with these for now break; - case Value::eValueTypeScalar: + case Value::ValueType::Scalar: expr_variable_sp->m_flags |= ExpressionVariable::EVIsFreezeDried; expr_variable_sp->m_flags |= @@ -132,7 +134,7 @@ ValueObjectSP ABI::GetReturnValueObject(Thread &thread, CompilerType &ast_type, expr_variable_sp->m_flags |= ExpressionVariable::EVNeedsAllocation; break; - case Value::eValueTypeLoadAddress: + case Value::ValueType::LoadAddress: expr_variable_sp->m_live_sp = live_valobj_sp; expr_variable_sp->m_flags |= ExpressionVariable::EVIsProgramReference; diff --git a/contrib/llvm-project/lldb/source/Target/AssertFrameRecognizer.cpp b/contrib/llvm-project/lldb/source/Target/AssertFrameRecognizer.cpp index cb671040d14f..a2315b6d63c6 100644 --- a/contrib/llvm-project/lldb/source/Target/AssertFrameRecognizer.cpp +++ b/contrib/llvm-project/lldb/source/Target/AssertFrameRecognizer.cpp @@ -22,6 +22,10 @@ namespace lldb_private { struct SymbolLocation { FileSpec module_spec; std::vector<ConstString> symbols; + + // The symbols are regular expressions. In such case all symbols are matched + // with their trailing @VER symbol version stripped. + bool symbols_are_regex = false; }; /// Fetches the abort frame location depending on the current platform. @@ -45,6 +49,8 @@ bool GetAbortLocation(llvm::Triple::OSType os, SymbolLocation &location) { location.symbols.push_back(ConstString("raise")); location.symbols.push_back(ConstString("__GI_raise")); location.symbols.push_back(ConstString("gsignal")); + location.symbols.push_back(ConstString("pthread_kill")); + location.symbols_are_regex = true; break; default: Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); @@ -93,9 +99,33 @@ void RegisterAssertFrameRecognizer(Process *process) { if (!GetAbortLocation(os, location)) return; + if (!location.symbols_are_regex) { + target.GetFrameRecognizerManager().AddRecognizer( + std::make_shared<AssertFrameRecognizer>(), + location.module_spec.GetFilename(), location.symbols, + /*first_instruction_only*/ false); + return; + } + std::string module_re = "^"; + for (char c : location.module_spec.GetFilename().GetStringRef()) { + if (c == '.') + module_re += '\\'; + module_re += c; + } + module_re += '$'; + std::string symbol_re = "^("; + for (auto it = location.symbols.cbegin(); it != location.symbols.cend(); + ++it) { + if (it != location.symbols.cbegin()) + symbol_re += '|'; + symbol_re += it->GetStringRef(); + } + // Strip the trailing @VER symbol version. + symbol_re += ")(@.*)?$"; target.GetFrameRecognizerManager().AddRecognizer( - StackFrameRecognizerSP(new AssertFrameRecognizer()), - location.module_spec.GetFilename(), location.symbols, + std::make_shared<AssertFrameRecognizer>(), + std::make_shared<RegularExpression>(std::move(module_re)), + std::make_shared<RegularExpression>(std::move(symbol_re)), /*first_instruction_only*/ false); } @@ -112,7 +142,7 @@ AssertFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame_sp) { if (!GetAssertLocation(os, location)) return RecognizedStackFrameSP(); - const uint32_t frames_to_fetch = 5; + const uint32_t frames_to_fetch = 6; const uint32_t last_frame_index = frames_to_fetch - 1; StackFrameSP prev_frame_sp = nullptr; diff --git a/contrib/llvm-project/lldb/source/Target/ExecutionContext.cpp b/contrib/llvm-project/lldb/source/Target/ExecutionContext.cpp index 20932ee63dce..b5cf13582af1 100644 --- a/contrib/llvm-project/lldb/source/Target/ExecutionContext.cpp +++ b/contrib/llvm-project/lldb/source/Target/ExecutionContext.cpp @@ -395,8 +395,7 @@ bool ExecutionContext::HasFrameScope() const { } ExecutionContextRef::ExecutionContextRef() - : m_target_wp(), m_process_wp(), m_thread_wp(), - m_tid(LLDB_INVALID_THREAD_ID), m_stack_id() {} + : m_target_wp(), m_process_wp(), m_thread_wp(), m_stack_id() {} ExecutionContextRef::ExecutionContextRef(const ExecutionContext *exe_ctx) : m_target_wp(), m_process_wp(), m_thread_wp(), diff --git a/contrib/llvm-project/lldb/source/Target/JITLoaderList.cpp b/contrib/llvm-project/lldb/source/Target/JITLoaderList.cpp index f5a90d58d588..92e841b5c94d 100644 --- a/contrib/llvm-project/lldb/source/Target/JITLoaderList.cpp +++ b/contrib/llvm-project/lldb/source/Target/JITLoaderList.cpp @@ -15,7 +15,7 @@ using namespace lldb_private; JITLoaderList::JITLoaderList() : m_jit_loaders_vec(), m_jit_loaders_mutex() {} -JITLoaderList::~JITLoaderList() {} +JITLoaderList::~JITLoaderList() = default; void JITLoaderList::Append(const JITLoaderSP &jit_loader_sp) { std::lock_guard<std::recursive_mutex> guard(m_jit_loaders_mutex); diff --git a/contrib/llvm-project/lldb/source/Target/Language.cpp b/contrib/llvm-project/lldb/source/Target/Language.cpp index b1a8a9517f3f..7b35da5028ac 100644 --- a/contrib/llvm-project/lldb/source/Target/Language.cpp +++ b/contrib/llvm-project/lldb/source/Target/Language.cpp @@ -184,7 +184,7 @@ struct language_name_pair language_names[] = { {"fortran03", eLanguageTypeFortran03}, {"fortran08", eLanguageTypeFortran08}, // Vendor Extensions - {"mipsassem", eLanguageTypeMipsAssembler}, + {"assembler", eLanguageTypeMipsAssembler}, {"renderscript", eLanguageTypeExtRenderScript}, // Now synonyms, in arbitrary order {"objc", eLanguageTypeObjC}, @@ -196,7 +196,7 @@ static uint32_t num_languages = LanguageType Language::GetLanguageTypeFromString(llvm::StringRef string) { for (const auto &L : language_names) { - if (string.equals_lower(L.name)) + if (string.equals_insensitive(L.name)) return static_cast<LanguageType>(L.type); } @@ -448,7 +448,7 @@ void Language::GetDefaultExceptionResolverDescription(bool catch_on, catch_on ? "on" : "off", throw_on ? "on" : "off"); } // Constructor -Language::Language() {} +Language::Language() = default; // Destructor -Language::~Language() {} +Language::~Language() = default; diff --git a/contrib/llvm-project/lldb/source/Target/LanguageRuntime.cpp b/contrib/llvm-project/lldb/source/Target/LanguageRuntime.cpp index f2e2febf8b88..be878d69fa00 100644 --- a/contrib/llvm-project/lldb/source/Target/LanguageRuntime.cpp +++ b/contrib/llvm-project/lldb/source/Target/LanguageRuntime.cpp @@ -259,6 +259,25 @@ BreakpointSP LanguageRuntime::CreateExceptionBreakpoint( return exc_breakpt_sp; } +UnwindPlanSP +LanguageRuntime::GetRuntimeUnwindPlan(Thread &thread, RegisterContext *regctx, + bool &behaves_like_zeroth_frame) { + ProcessSP process_sp = thread.GetProcess(); + if (!process_sp.get()) + return UnwindPlanSP(); + if (process_sp->GetDisableLangRuntimeUnwindPlans() == true) + return UnwindPlanSP(); + for (const lldb::LanguageType lang_type : Language::GetSupportedLanguages()) { + if (LanguageRuntime *runtime = process_sp->GetLanguageRuntime(lang_type)) { + UnwindPlanSP plan_sp = runtime->GetRuntimeUnwindPlan( + process_sp, regctx, behaves_like_zeroth_frame); + if (plan_sp.get()) + return plan_sp; + } + } + return UnwindPlanSP(); +} + void LanguageRuntime::InitializeCommands(CommandObject *parent) { if (!parent) return; diff --git a/contrib/llvm-project/lldb/source/Target/Memory.cpp b/contrib/llvm-project/lldb/source/Target/Memory.cpp index a7ed1a3d97b7..806e92aa4ed5 100644 --- a/contrib/llvm-project/lldb/source/Target/Memory.cpp +++ b/contrib/llvm-project/lldb/source/Target/Memory.cpp @@ -26,7 +26,7 @@ MemoryCache::MemoryCache(Process &process) m_L2_cache_line_byte_size(process.GetMemoryCacheLineSize()) {} // Destructor -MemoryCache::~MemoryCache() {} +MemoryCache::~MemoryCache() = default; void MemoryCache::Clear(bool clear_invalid_ranges) { std::lock_guard<std::recursive_mutex> guard(m_mutex); @@ -259,7 +259,7 @@ AllocatedBlock::AllocatedBlock(lldb::addr_t addr, uint32_t byte_size, assert(byte_size > chunk_size); } -AllocatedBlock::~AllocatedBlock() {} +AllocatedBlock::~AllocatedBlock() = default; lldb::addr_t AllocatedBlock::ReserveBlock(uint32_t size) { // We must return something valid for zero bytes. @@ -329,7 +329,7 @@ bool AllocatedBlock::FreeBlock(addr_t addr) { AllocatedMemoryCache::AllocatedMemoryCache(Process &process) : m_process(process), m_mutex(), m_memory_map() {} -AllocatedMemoryCache::~AllocatedMemoryCache() {} +AllocatedMemoryCache::~AllocatedMemoryCache() = default; void AllocatedMemoryCache::Clear() { std::lock_guard<std::recursive_mutex> guard(m_mutex); diff --git a/contrib/llvm-project/lldb/source/Target/ModuleCache.cpp b/contrib/llvm-project/lldb/source/Target/ModuleCache.cpp index 20661a7b7a25..dcdc0772b31a 100644 --- a/contrib/llvm-project/lldb/source/Target/ModuleCache.cpp +++ b/contrib/llvm-project/lldb/source/Target/ModuleCache.cpp @@ -17,7 +17,7 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/FileUtilities.h" -#include <assert.h> +#include <cassert> #include <cstdio> diff --git a/contrib/llvm-project/lldb/source/Target/PathMappingList.cpp b/contrib/llvm-project/lldb/source/Target/PathMappingList.cpp index b22673f55471..b660c310ef31 100644 --- a/contrib/llvm-project/lldb/source/Target/PathMappingList.cpp +++ b/contrib/llvm-project/lldb/source/Target/PathMappingList.cpp @@ -37,8 +37,7 @@ namespace { } } // PathMappingList constructor -PathMappingList::PathMappingList() - : m_pairs(), m_callback(nullptr), m_callback_baton(nullptr), m_mod_id(0) {} +PathMappingList::PathMappingList() : m_pairs() {} PathMappingList::PathMappingList(ChangedCallback callback, void *callback_baton) : m_pairs(), m_callback(callback), m_callback_baton(callback_baton), @@ -146,21 +145,37 @@ void PathMappingList::Clear(bool notify) { bool PathMappingList::RemapPath(ConstString path, ConstString &new_path) const { - std::string remapped; - if (RemapPath(path.GetStringRef(), remapped)) { - new_path.SetString(remapped); + if (llvm::Optional<FileSpec> remapped = RemapPath(path.GetStringRef())) { + new_path.SetString(remapped->GetPath()); return true; } return false; } -bool PathMappingList::RemapPath(llvm::StringRef path, - std::string &new_path) const { - if (m_pairs.empty() || path.empty()) - return false; +/// Append components to path, applying style. +static void AppendPathComponents(FileSpec &path, llvm::StringRef components, + llvm::sys::path::Style style) { + auto component = llvm::sys::path::begin(components, style); + auto e = llvm::sys::path::end(components); + while (component != e && + llvm::sys::path::is_separator(*component->data(), style)) + ++component; + for (; component != e; ++component) + path.AppendPathComponent(*component); +} + +llvm::Optional<FileSpec> +PathMappingList::RemapPath(llvm::StringRef mapping_path, + bool only_if_exists) const { + if (m_pairs.empty() || mapping_path.empty()) + return {}; LazyBool path_is_relative = eLazyBoolCalculate; + for (const auto &it : m_pairs) { - auto prefix = it.first.GetStringRef(); + llvm::StringRef prefix = it.first.GetStringRef(); + // We create a copy of mapping_path because StringRef::consume_from + // effectively modifies the instance itself. + llvm::StringRef path = mapping_path; if (!path.consume_front(prefix)) { // Relative paths won't have a leading "./" in them unless "." is the // only thing in the relative path so we need to work around "." @@ -177,11 +192,13 @@ bool PathMappingList::RemapPath(llvm::StringRef path, continue; } FileSpec remapped(it.second.GetStringRef()); - remapped.AppendPathComponent(path); - new_path = remapped.GetPath(); - return true; + auto orig_style = FileSpec::GuessPathStyle(prefix).getValueOr( + llvm::sys::path::Style::native); + AppendPathComponents(remapped, path, orig_style); + if (!only_if_exists || FileSystem::Instance().Exists(remapped)) + return remapped; } - return false; + return {}; } bool PathMappingList::ReverseRemapPath(const FileSpec &file, FileSpec &fixed) const { @@ -190,56 +207,21 @@ bool PathMappingList::ReverseRemapPath(const FileSpec &file, FileSpec &fixed) co for (const auto &it : m_pairs) { if (!path_ref.consume_front(it.second.GetStringRef())) continue; - fixed.SetFile(it.first.GetStringRef(), FileSpec::Style::native); - fixed.AppendPathComponent(path_ref); + auto orig_file = it.first.GetStringRef(); + auto orig_style = FileSpec::GuessPathStyle(orig_file).getValueOr( + llvm::sys::path::Style::native); + fixed.SetFile(orig_file, orig_style); + AppendPathComponents(fixed, path_ref, orig_style); return true; } return false; } -bool PathMappingList::FindFile(const FileSpec &orig_spec, - FileSpec &new_spec) const { - if (m_pairs.empty()) - return false; - - std::string orig_path = orig_spec.GetPath(); - - if (orig_path.empty()) - return false; - - bool orig_is_relative = orig_spec.IsRelative(); +llvm::Optional<FileSpec> PathMappingList::FindFile(const FileSpec &orig_spec) const { + if (auto remapped = RemapPath(orig_spec.GetPath(), /*only_if_exists=*/true)) + return remapped; - for (auto entry : m_pairs) { - llvm::StringRef orig_ref(orig_path); - llvm::StringRef prefix_ref = entry.first.GetStringRef(); - if (orig_ref.size() < prefix_ref.size()) - continue; - // We consider a relative prefix or one of just "." to - // mean "only apply to relative paths". - bool prefix_is_relative = false; - - if (prefix_ref == ".") { - prefix_is_relative = true; - // Remove the "." since it will have been removed from the - // FileSpec paths already. - prefix_ref = prefix_ref.drop_front(); - } else { - FileSpec prefix_spec(prefix_ref, FileSpec::Style::native); - prefix_is_relative = prefix_spec.IsRelative(); - } - if (prefix_is_relative != orig_is_relative) - continue; - - if (orig_ref.consume_front(prefix_ref)) { - new_spec.SetFile(entry.second.GetCString(), FileSpec::Style::native); - new_spec.AppendPathComponent(orig_ref); - if (FileSystem::Instance().Exists(new_spec)) - return true; - } - } - - new_spec.Clear(); - return false; + return {}; } bool PathMappingList::Replace(ConstString path, diff --git a/contrib/llvm-project/lldb/source/Target/Process.cpp b/contrib/llvm-project/lldb/source/Target/Process.cpp index 518a6934059e..8ecc66b592ea 100644 --- a/contrib/llvm-project/lldb/source/Target/Process.cpp +++ b/contrib/llvm-project/lldb/source/Target/Process.cpp @@ -10,6 +10,7 @@ #include <memory> #include <mutex> +#include "llvm/ADT/ScopeExit.h" #include "llvm/Support/ScopedPrinter.h" #include "llvm/Support/Threading.h" @@ -68,6 +69,7 @@ #include "lldb/Utility/ProcessInfo.h" #include "lldb/Utility/SelectHelper.h" #include "lldb/Utility/State.h" +#include "lldb/Utility/Timer.h" using namespace lldb; using namespace lldb_private; @@ -83,16 +85,10 @@ using namespace std::chrono; #define DISABLE_MEM_CACHE_DEFAULT true #endif -class ProcessOptionValueProperties : public OptionValueProperties { +class ProcessOptionValueProperties + : public Cloneable<ProcessOptionValueProperties, OptionValueProperties> { public: - ProcessOptionValueProperties(ConstString name) - : OptionValueProperties(name) {} - - // This constructor is used when creating ProcessOptionValueProperties when - // it is part of a new lldb_private::Process instance. It will copy all - // current global property values as needed - ProcessOptionValueProperties(ProcessProperties *global_properties) - : OptionValueProperties(*global_properties->GetValueProperties()) {} + ProcessOptionValueProperties(ConstString name) : Cloneable(name) {} const Property *GetPropertyAtIndex(const ExecutionContext *exe_ctx, bool will_modify, @@ -131,10 +127,12 @@ enum { #include "TargetPropertiesEnum.inc" }; -class ProcessExperimentalOptionValueProperties : public OptionValueProperties { +class ProcessExperimentalOptionValueProperties + : public Cloneable<ProcessExperimentalOptionValueProperties, + OptionValueProperties> { public: ProcessExperimentalOptionValueProperties() - : OptionValueProperties( + : Cloneable( ConstString(Properties::GetExperimentalSettingsName())) {} }; @@ -157,8 +155,8 @@ ProcessProperties::ProcessProperties(lldb_private::Process *process) ConstString("thread"), ConstString("Settings specific to threads."), true, Thread::GetGlobalProperties()->GetValueProperties()); } else { - m_collection_sp = std::make_shared<ProcessOptionValueProperties>( - Process::GetGlobalProperties().get()); + m_collection_sp = + OptionValueProperties::CreateLocalCopy(*Process::GetGlobalProperties()); m_collection_sp->SetValueChangedCallback( ePropertyPythonOSPluginPath, [this] { m_process->LoadOperatingSystemPlugin(true); }); @@ -204,6 +202,16 @@ FileSpec ProcessProperties::GetPythonOSPluginPath() const { return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx); } +uint32_t ProcessProperties::GetVirtualAddressableBits() const { + const uint32_t idx = ePropertyVirtualAddressableBits; + return m_collection_sp->GetPropertyAtIndexAsUInt64( + nullptr, idx, g_process_properties[idx].default_uint_value); +} + +void ProcessProperties::SetVirtualAddressableBits(uint32_t bits) { + const uint32_t idx = ePropertyVirtualAddressableBits; + m_collection_sp->SetPropertyAtIndexAsUInt64(nullptr, idx, bits); +} void ProcessProperties::SetPythonOSPluginPath(const FileSpec &file) { const uint32_t idx = ePropertyPythonOSPluginPath; m_collection_sp->SetPropertyAtIndexAsFileSpec(nullptr, idx, file); @@ -242,6 +250,18 @@ void ProcessProperties::SetStopOnSharedLibraryEvents(bool stop) { m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, stop); } +bool ProcessProperties::GetDisableLangRuntimeUnwindPlans() const { + const uint32_t idx = ePropertyDisableLangRuntimeUnwindPlans; + return m_collection_sp->GetPropertyAtIndexAsBoolean( + nullptr, idx, g_process_properties[idx].default_uint_value != 0); +} + +void ProcessProperties::SetDisableLangRuntimeUnwindPlans(bool disable) { + const uint32_t idx = ePropertyDisableLangRuntimeUnwindPlans; + m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, disable); + m_process->Flush(); +} + bool ProcessProperties::GetDetachKeepsStopped() const { const uint32_t idx = ePropertyDetachKeepsStopped; return m_collection_sp->GetPropertyAtIndexAsBoolean( @@ -278,6 +298,13 @@ std::chrono::seconds ProcessProperties::GetUtilityExpressionTimeout() const { return std::chrono::seconds(value); } +std::chrono::seconds ProcessProperties::GetInterruptTimeout() const { + const uint32_t idx = ePropertyInterruptTimeout; + uint64_t value = m_collection_sp->GetPropertyAtIndexAsUInt64( + nullptr, idx, g_process_properties[idx].default_uint_value); + return std::chrono::seconds(value); +} + bool ProcessProperties::GetSteppingRunsAllThreads() const { const uint32_t idx = ePropertySteppingRunsAllThreads; return m_collection_sp->GetPropertyAtIndexAsBoolean( @@ -466,25 +493,9 @@ void Process::Finalize() { if (m_finalizing.exchange(true)) return; - // Destroy this process if needed - switch (GetPrivateState()) { - case eStateConnected: - case eStateAttaching: - case eStateLaunching: - case eStateStopped: - case eStateRunning: - case eStateStepping: - case eStateCrashed: - case eStateSuspended: - DestroyImpl(false); - break; - - case eStateInvalid: - case eStateUnloaded: - case eStateDetached: - case eStateExited: - break; - } + // Destroy the process. This will call the virtual function DoDestroy under + // the hood, giving our derived class a chance to do the ncessary tear down. + DestroyImpl(false); // Clear our broadcaster before we proceed with destroying Broadcaster::Clear(); @@ -766,13 +777,30 @@ bool Process::HandleProcessStateChangedEvent(const EventSP &event_sp, ThreadSP curr_thread(thread_list.GetSelectedThread()); ThreadSP thread; StopReason curr_thread_stop_reason = eStopReasonInvalid; - if (curr_thread) { + bool prefer_curr_thread = false; + if (curr_thread && curr_thread->IsValid()) { curr_thread_stop_reason = curr_thread->GetStopReason(); + switch (curr_thread_stop_reason) { + case eStopReasonNone: + case eStopReasonInvalid: + // Don't prefer the current thread if it didn't stop for a reason. + break; + case eStopReasonSignal: { + // We need to do the same computation we do for other threads + // below in case the current thread happens to be the one that + // stopped for the no-stop signal. + uint64_t signo = curr_thread->GetStopInfo()->GetValue(); + if (process_sp->GetUnixSignals()->GetShouldStop(signo)) + prefer_curr_thread = true; + } break; + default: + prefer_curr_thread = true; + break; + } curr_thread_stop_info_sp = curr_thread->GetStopInfo(); } - if (!curr_thread || !curr_thread->IsValid() || - curr_thread_stop_reason == eStopReasonInvalid || - curr_thread_stop_reason == eStopReasonNone) { + + if (!prefer_curr_thread) { // Prefer a thread that has just completed its plan over another // thread as current thread. ThreadSP plan_thread; @@ -804,8 +832,12 @@ bool Process::HandleProcessStateChangedEvent(const EventSP &event_sp, case eStopReasonWatchpoint: case eStopReasonException: case eStopReasonExec: + case eStopReasonFork: + case eStopReasonVFork: + case eStopReasonVForkDone: case eStopReasonThreadExiting: case eStopReasonInstrumentation: + case eStopReasonProcessorTrace: if (!other_thread) other_thread = thread; break; @@ -1311,8 +1343,8 @@ Status Process::ResumeSynchronous(Stream *stream) { Status error = PrivateResume(); if (error.Success()) { - StateType state = - WaitForProcessToStop(llvm::None, nullptr, true, listener_sp, stream); + StateType state = WaitForProcessToStop(llvm::None, nullptr, true, + listener_sp, stream); const bool must_be_alive = false; // eStateExited is ok, so this must be false if (!StateIsStoppedState(state, must_be_alive)) @@ -1356,8 +1388,8 @@ void Process::SetPrivateState(StateType new_state) { if (m_finalizing) return; - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STATE | - LIBLLDB_LOG_PROCESS)); + Log *log(lldb_private::GetLogIfAnyCategoriesSet( + LIBLLDB_LOG_STATE | LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_UNWIND)); bool state_changed = false; LLDB_LOGF(log, "Process::SetPrivateState (%s)", StateAsCString(new_state)); @@ -2022,6 +2054,8 @@ size_t Process::ReadCStringFromMemory(addr_t addr, char *dst, size_t Process::ReadMemoryFromInferior(addr_t addr, void *buf, size_t size, Status &error) { + LLDB_SCOPED_TIMER(); + if (buf == nullptr || size == 0) return 0; @@ -2448,6 +2482,11 @@ Status Process::Launch(ProcessLaunchInfo &launch_info) { if (error.Fail()) return error; + // Listen and queue events that are broadcasted during the process launch. + ListenerSP listener_sp(Listener::MakeListener("LaunchEventHijack")); + HijackProcessEvents(listener_sp); + auto on_exit = llvm::make_scope_exit([this]() { RestoreProcessEvents(); }); + if (PrivateStateThreadIsValid()) PausePrivateStateThread(); @@ -2856,8 +2895,10 @@ void Process::CompleteAttach() { ProcessInstanceInfo process_info; GetProcessInfo(process_info); const ArchSpec &process_arch = process_info.GetArchitecture(); + const ArchSpec &target_arch = GetTarget().GetArchitecture(); if (process_arch.IsValid() && - !GetTarget().GetArchitecture().IsExactMatch(process_arch)) { + target_arch.IsCompatibleMatch(process_arch) && + !target_arch.IsExactMatch(process_arch)) { GetTarget().SetArchitecture(process_arch); LLDB_LOGF(log, "Process::%s switching architecture to %s based on info " @@ -3050,9 +3091,10 @@ Status Process::Halt(bool clear_thread_plans, bool use_run_lock) { return Status(); } - // Wait for 10 second for the process to stop. - StateType state = WaitForProcessToStop( - seconds(10), &event_sp, true, halt_listener_sp, nullptr, use_run_lock); + // Wait for the process halt timeout seconds for the process to stop. + StateType state = + WaitForProcessToStop(GetInterruptTimeout(), &event_sp, true, + halt_listener_sp, nullptr, use_run_lock); RestoreProcessEvents(); if (state == eStateInvalid || !event_sp) { @@ -3083,8 +3125,8 @@ Status Process::StopForDestroyOrDetach(lldb::EventSP &exit_event_sp) { SendAsyncInterrupt(); // Consume the interrupt event. - StateType state = - WaitForProcessToStop(seconds(10), &exit_event_sp, true, listener_sp); + StateType state = WaitForProcessToStop(GetInterruptTimeout(), + &exit_event_sp, true, listener_sp); RestoreProcessEvents(); @@ -3203,7 +3245,7 @@ Status Process::DestroyImpl(bool force_kill) { error = StopForDestroyOrDetach(exit_event_sp); } - if (m_public_state.GetValue() != eStateRunning) { + if (m_public_state.GetValue() == eStateStopped) { // Ditch all thread plans, and remove all our breakpoints: in case we // have to restart the target to kill it, we don't want it hitting a // breakpoint... Only do this if we've stopped, however, since if we @@ -3374,14 +3416,14 @@ bool Process::ShouldBroadcastEvent(Event *event_ptr) { should_resume = !m_thread_list.ShouldStop(event_ptr); if (was_restarted || should_resume || m_resume_requested) { - Vote stop_vote = m_thread_list.ShouldReportStop(event_ptr); + Vote report_stop_vote = m_thread_list.ShouldReportStop(event_ptr); LLDB_LOGF(log, "Process::ShouldBroadcastEvent: should_resume: %i state: " - "%s was_restarted: %i stop_vote: %d.", + "%s was_restarted: %i report_stop_vote: %d.", should_resume, StateAsCString(state), was_restarted, - stop_vote); + report_stop_vote); - switch (stop_vote) { + switch (report_stop_vote) { case eVoteYes: return_value = true; break; @@ -3819,9 +3861,7 @@ thread_result_t Process::RunPrivateStateThread(bool is_secondary_thread) { // Process Event Data -Process::ProcessEventData::ProcessEventData() - : EventData(), m_process_wp(), m_state(eStateInvalid), m_restarted(false), - m_update_state(0), m_interrupted(false) {} +Process::ProcessEventData::ProcessEventData() : EventData(), m_process_wp() {} Process::ProcessEventData::ProcessEventData(const ProcessSP &process_sp, StateType state) @@ -5536,6 +5576,26 @@ void Process::Flush() { m_queue_list_stop_id = 0; } +lldb::addr_t Process::GetCodeAddressMask() { + if (m_code_address_mask == 0) { + if (uint32_t number_of_addressable_bits = GetVirtualAddressableBits()) { + lldb::addr_t address_mask = ~((1ULL << number_of_addressable_bits) - 1); + SetCodeAddressMask(address_mask); + } + } + return m_code_address_mask; +} + +lldb::addr_t Process::GetDataAddressMask() { + if (m_data_address_mask == 0) { + if (uint32_t number_of_addressable_bits = GetVirtualAddressableBits()) { + lldb::addr_t address_mask = ~((1ULL << number_of_addressable_bits) - 1); + SetDataAddressMask(address_mask); + } + } + return m_data_address_mask; +} + void Process::DidExec() { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); LLDB_LOGF(log, "Process::%s()", __FUNCTION__); @@ -5591,6 +5651,8 @@ addr_t Process::ResolveIndirectFunction(const Address *address, Status &error) { symbol ? symbol->GetName().AsCString() : "<UNKNOWN>"); function_addr = LLDB_INVALID_ADDRESS; } else { + if (ABISP abi_sp = GetABI()) + function_addr = abi_sp->FixCodeAddress(function_addr); m_resolved_indirect_addresses.insert( std::pair<addr_t, addr_t>(addr, function_addr)); } @@ -5684,12 +5746,12 @@ void Process::PrintWarningUnsupportedLanguage(const SymbolContext &sc) { LanguageType language = sc.GetLanguage(); if (language == eLanguageTypeUnknown) return; - auto type_system_or_err = sc.module_sp->GetTypeSystemForLanguage(language); - if (auto err = type_system_or_err.takeError()) { - llvm::consumeError(std::move(err)); + LanguageSet plugins = + PluginManager::GetAllTypeSystemSupportedLanguagesForTypes(); + if (!plugins[language]) { PrintWarning(Process::Warnings::eWarningsUnsupportedLanguage, sc.module_sp.get(), - "This version of LLDB has no plugin for the %s language. " + "This version of LLDB has no plugin for the language \"%s\". " "Inspection of frame variables will be limited.\n", Language::GetNameForLanguageType(language)); } @@ -5769,10 +5831,8 @@ Process::AdvanceAddressToNextBranchInstruction(Address default_stop_addr, const char *plugin_name = nullptr; const char *flavor = nullptr; - const bool prefer_file_cache = true; disassembler_sp = Disassembler::DisassembleRange( - target.GetArchitecture(), plugin_name, flavor, GetTarget(), range_bounds, - prefer_file_cache); + target.GetArchitecture(), plugin_name, flavor, GetTarget(), range_bounds); if (disassembler_sp) insn_list = &disassembler_sp->GetInstructionList(); @@ -5962,7 +6022,7 @@ UtilityFunction *Process::GetLoadImageUtilityFunction( return m_dlopen_utility_func_up.get(); } -llvm::Expected<TraceTypeInfo> Process::GetSupportedTraceType() { +llvm::Expected<TraceSupportedResponse> Process::TraceSupported() { if (!IsLiveDebugSession()) return llvm::createStringError(llvm::inconvertibleErrorCode(), "Can't trace a non-live process."); @@ -6023,3 +6083,57 @@ bool Process::CallVoidArgVoidPtrReturn(const Address *address, return false; } + +llvm::Expected<const MemoryTagManager *> Process::GetMemoryTagManager() { + Architecture *arch = GetTarget().GetArchitecturePlugin(); + const MemoryTagManager *tag_manager = + arch ? arch->GetMemoryTagManager() : nullptr; + if (!arch || !tag_manager) { + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "This architecture does not support memory tagging", + GetPluginName().GetCString()); + } + + if (!SupportsMemoryTagging()) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Process does not support memory tagging"); + } + + return tag_manager; +} + +llvm::Expected<std::vector<lldb::addr_t>> +Process::ReadMemoryTags(lldb::addr_t addr, size_t len) { + llvm::Expected<const MemoryTagManager *> tag_manager_or_err = + GetMemoryTagManager(); + if (!tag_manager_or_err) + return tag_manager_or_err.takeError(); + + const MemoryTagManager *tag_manager = *tag_manager_or_err; + llvm::Expected<std::vector<uint8_t>> tag_data = + DoReadMemoryTags(addr, len, tag_manager->GetAllocationTagType()); + if (!tag_data) + return tag_data.takeError(); + + return tag_manager->UnpackTagsData(*tag_data, + len / tag_manager->GetGranuleSize()); +} + +Status Process::WriteMemoryTags(lldb::addr_t addr, size_t len, + const std::vector<lldb::addr_t> &tags) { + llvm::Expected<const MemoryTagManager *> tag_manager_or_err = + GetMemoryTagManager(); + if (!tag_manager_or_err) + return Status(tag_manager_or_err.takeError()); + + const MemoryTagManager *tag_manager = *tag_manager_or_err; + llvm::Expected<std::vector<uint8_t>> packed_tags = + tag_manager->PackTags(tags); + if (!packed_tags) { + return Status(packed_tags.takeError()); + } + + return DoWriteMemoryTags(addr, len, tag_manager->GetAllocationTagType(), + *packed_tags); +} diff --git a/contrib/llvm-project/lldb/source/Target/ProcessTrace.cpp b/contrib/llvm-project/lldb/source/Target/ProcessTrace.cpp index 95f87745b724..c878a2ac4eb9 100644 --- a/contrib/llvm-project/lldb/source/Target/ProcessTrace.cpp +++ b/contrib/llvm-project/lldb/source/Target/ProcessTrace.cpp @@ -87,8 +87,6 @@ void ProcessTrace::RefreshStateAfterStop() {} Status ProcessTrace::DoDestroy() { return Status(); } -bool ProcessTrace::IsAlive() { return true; } - size_t ProcessTrace::ReadMemory(addr_t addr, void *buf, size_t size, Status &error) { // Don't allow the caching that lldb_private::Process::ReadMemory does since diff --git a/contrib/llvm-project/lldb/source/Target/QueueItem.cpp b/contrib/llvm-project/lldb/source/Target/QueueItem.cpp index 740b2a6771a2..7070812a10b0 100644 --- a/contrib/llvm-project/lldb/source/Target/QueueItem.cpp +++ b/contrib/llvm-project/lldb/source/Target/QueueItem.cpp @@ -27,7 +27,7 @@ QueueItem::QueueItem(QueueSP queue_sp, ProcessSP process_sp, m_process_wp = process_sp; } -QueueItem::~QueueItem() {} +QueueItem::~QueueItem() = default; QueueItemKind QueueItem::GetKind() { FetchEntireItem(); diff --git a/contrib/llvm-project/lldb/source/Target/RegisterContext.cpp b/contrib/llvm-project/lldb/source/Target/RegisterContext.cpp index cdc7653cea6d..bd50a9486ef3 100644 --- a/contrib/llvm-project/lldb/source/Target/RegisterContext.cpp +++ b/contrib/llvm-project/lldb/source/Target/RegisterContext.cpp @@ -58,8 +58,8 @@ RegisterContext::GetRegisterInfoByName(llvm::StringRef reg_name, for (uint32_t reg = start_idx; reg < num_registers; ++reg) { const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg); - if (reg_name.equals_lower(reg_info->name) || - reg_name.equals_lower(reg_info->alt_name)) + if (reg_name.equals_insensitive(reg_info->name) || + reg_name.equals_insensitive(reg_info->alt_name)) return reg_info; } return nullptr; @@ -150,6 +150,20 @@ bool RegisterContext::SetPC(uint64_t pc) { return success; } +bool RegisterContext::GetPCForSymbolication(Address &address) { + addr_t pc = GetPC(LLDB_INVALID_ADDRESS); + if (pc == LLDB_INVALID_ADDRESS) + return false; + TargetSP target_sp = m_thread.CalculateTarget(); + if (!target_sp.get()) + return false; + + if (!BehavesLikeZerothFrame() && pc != 0) + pc--; + address.SetLoadAddress(pc, target_sp.get()); + return true; +} + bool RegisterContext::SetPC(Address addr) { TargetSP target_sp = m_thread.CalculateTarget(); Target *target = target_sp.get(); diff --git a/contrib/llvm-project/lldb/source/Target/RegisterContextUnwind.cpp b/contrib/llvm-project/lldb/source/Target/RegisterContextUnwind.cpp index f33f4180be23..1ce21e6306e0 100644 --- a/contrib/llvm-project/lldb/source/Target/RegisterContextUnwind.cpp +++ b/contrib/llvm-project/lldb/source/Target/RegisterContextUnwind.cpp @@ -24,6 +24,7 @@ #include "lldb/Target/ABI.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/LanguageRuntime.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" #include "lldb/Target/SectionLoadList.h" @@ -57,10 +58,11 @@ RegisterContextUnwind::RegisterContextUnwind(Thread &thread, m_fast_unwind_plan_sp(), m_full_unwind_plan_sp(), m_fallback_unwind_plan_sp(), m_all_registers_available(false), m_frame_type(-1), m_cfa(LLDB_INVALID_ADDRESS), - m_afa(LLDB_INVALID_ADDRESS), m_start_pc(), - m_current_pc(), m_current_offset(0), m_current_offset_backed_up_one(0), - m_sym_ctx(sym_ctx), m_sym_ctx_valid(false), m_frame_number(frame_number), - m_registers(), m_parent_unwind(unwind_lldb) { + m_afa(LLDB_INVALID_ADDRESS), m_start_pc(), m_current_pc(), + m_current_offset(0), m_current_offset_backed_up_one(0), + m_behaves_like_zeroth_frame(false), m_sym_ctx(sym_ctx), + m_sym_ctx_valid(false), m_frame_number(frame_number), m_registers(), + m_parent_unwind(unwind_lldb) { m_sym_ctx.Clear(false); m_sym_ctx_valid = false; @@ -139,6 +141,12 @@ void RegisterContextUnwind::InitializeZerothFrame() { if (abi) current_pc = abi->FixCodeAddress(current_pc); + UnwindPlanSP lang_runtime_plan_sp = LanguageRuntime::GetRuntimeUnwindPlan( + m_thread, this, m_behaves_like_zeroth_frame); + if (lang_runtime_plan_sp.get()) { + UnwindLogMsg("This is an async frame"); + } + // Initialize m_current_pc, an Address object, based on current_pc, an // addr_t. m_current_pc.SetLoadAddress(current_pc, &process->GetTarget()); @@ -202,6 +210,38 @@ void RegisterContextUnwind::InitializeZerothFrame() { UnwindPlan::RowSP active_row; lldb::RegisterKind row_register_kind = eRegisterKindGeneric; + + // If we have LanguageRuntime UnwindPlan for this unwind, use those + // rules to find the caller frame instead of the function's normal + // UnwindPlans. The full unwind plan for this frame will be + // the LanguageRuntime-provided unwind plan, and there will not be a + // fast unwind plan. + if (lang_runtime_plan_sp.get()) { + active_row = + lang_runtime_plan_sp->GetRowForFunctionOffset(m_current_offset); + row_register_kind = lang_runtime_plan_sp->GetRegisterKind(); + if (!ReadFrameAddress(row_register_kind, active_row->GetCFAValue(), + m_cfa)) { + UnwindLogMsg("Cannot set cfa"); + } else { + m_full_unwind_plan_sp = lang_runtime_plan_sp; + if (log) { + StreamString active_row_strm; + active_row->Dump(active_row_strm, lang_runtime_plan_sp.get(), &m_thread, + m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr())); + UnwindLogMsg("async active row: %s", active_row_strm.GetData()); + } + UnwindLogMsg("m_cfa = 0x%" PRIx64 " m_afa = 0x%" PRIx64, m_cfa, m_afa); + UnwindLogMsg( + "initialized async frame current pc is 0x%" PRIx64 + " cfa is 0x%" PRIx64 " afa is 0x%" PRIx64, + (uint64_t)m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr()), + (uint64_t)m_cfa, (uint64_t)m_afa); + + return; + } + } + if (m_full_unwind_plan_sp && m_full_unwind_plan_sp->PlanValidAtAddress(m_current_pc)) { active_row = @@ -283,6 +323,22 @@ void RegisterContextUnwind::InitializeNonZerothFrame() { return; } + ExecutionContext exe_ctx(m_thread.shared_from_this()); + Process *process = exe_ctx.GetProcessPtr(); + + // Some languages may have a logical parent stack frame which is + // not a real stack frame, but the programmer would consider it to + // be the caller of the frame, e.g. Swift asynchronous frames. + // + // A LanguageRuntime may provide an UnwindPlan that is used in this + // stack trace base on the RegisterContext contents, intsead + // of the normal UnwindPlans we would use for the return-pc. + UnwindPlanSP lang_runtime_plan_sp = LanguageRuntime::GetRuntimeUnwindPlan( + m_thread, this, m_behaves_like_zeroth_frame); + if (lang_runtime_plan_sp.get()) { + UnwindLogMsg("This is an async frame"); + } + addr_t pc; if (!ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc)) { UnwindLogMsg("could not get pc value"); @@ -290,8 +346,6 @@ void RegisterContextUnwind::InitializeNonZerothFrame() { return; } - ExecutionContext exe_ctx(m_thread.shared_from_this()); - Process *process = exe_ctx.GetProcessPtr(); // Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs // this will strip bit zero in case we read a PC from memory or from the LR. ABI *abi = process->GetABI().get(); @@ -468,6 +522,8 @@ void RegisterContextUnwind::InitializeNonZerothFrame() { // so do not decrement and recompute if the symbol we already found is a trap // handler. decr_pc_and_recompute_addr_range = false; + } else if (m_behaves_like_zeroth_frame) { + decr_pc_and_recompute_addr_range = false; } else { // Decrement to find the function containing the call. decr_pc_and_recompute_addr_range = true; @@ -522,12 +578,43 @@ void RegisterContextUnwind::InitializeNonZerothFrame() { } } - // We've set m_frame_type and m_sym_ctx before this call. - m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame(); - UnwindPlan::RowSP active_row; RegisterKind row_register_kind = eRegisterKindGeneric; + // If we have LanguageRuntime UnwindPlan for this unwind, use those + // rules to find the caller frame instead of the function's normal + // UnwindPlans. The full unwind plan for this frame will be + // the LanguageRuntime-provided unwind plan, and there will not be a + // fast unwind plan. + if (lang_runtime_plan_sp.get()) { + active_row = + lang_runtime_plan_sp->GetRowForFunctionOffset(m_current_offset); + row_register_kind = lang_runtime_plan_sp->GetRegisterKind(); + if (!ReadFrameAddress(row_register_kind, active_row->GetCFAValue(), + m_cfa)) { + UnwindLogMsg("Cannot set cfa"); + } else { + m_full_unwind_plan_sp = lang_runtime_plan_sp; + if (log) { + StreamString active_row_strm; + active_row->Dump(active_row_strm, lang_runtime_plan_sp.get(), &m_thread, + m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr())); + UnwindLogMsg("async active row: %s", active_row_strm.GetData()); + } + UnwindLogMsg("m_cfa = 0x%" PRIx64 " m_afa = 0x%" PRIx64, m_cfa, m_afa); + UnwindLogMsg( + "initialized async frame current pc is 0x%" PRIx64 + " cfa is 0x%" PRIx64 " afa is 0x%" PRIx64, + (uint64_t)m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr()), + (uint64_t)m_cfa, (uint64_t)m_afa); + + return; + } + } + + // We've set m_frame_type and m_sym_ctx before this call. + m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame(); + // Try to get by with just the fast UnwindPlan if possible - the full // UnwindPlan may be expensive to get (e.g. if we have to parse the entire // eh_frame section of an ObjectFile for the first time.) @@ -542,6 +629,8 @@ void RegisterContextUnwind::InitializeNonZerothFrame() { StreamString active_row_strm; active_row->Dump(active_row_strm, m_fast_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr())); + UnwindLogMsg("Using fast unwind plan '%s'", + m_fast_unwind_plan_sp->GetSourceName().AsCString()); UnwindLogMsg("active row: %s", active_row_strm.GetData()); } } else { @@ -556,6 +645,8 @@ void RegisterContextUnwind::InitializeNonZerothFrame() { active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr())); + UnwindLogMsg("Using full unwind plan '%s'", + m_full_unwind_plan_sp->GetSourceName().AsCString()); UnwindLogMsg("active row: %s", active_row_strm.GetData()); } } @@ -625,6 +716,14 @@ bool RegisterContextUnwind::CheckIfLoopingStack() { bool RegisterContextUnwind::IsFrameZero() const { return m_frame_number == 0; } +bool RegisterContextUnwind::BehavesLikeZerothFrame() const { + if (m_frame_number == 0) + return true; + if (m_behaves_like_zeroth_frame) + return true; + return false; +} + // Find a fast unwind plan for this frame, if possible. // // On entry to this method, @@ -662,13 +761,6 @@ UnwindPlanSP RegisterContextUnwind::GetFastUnwindPlanForFrame() { *m_thread.CalculateTarget(), m_thread); if (unwind_plan_sp) { if (unwind_plan_sp->PlanValidAtAddress(m_current_pc)) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); - if (log && log->GetVerbose()) { - if (m_fast_unwind_plan_sp) - UnwindLogMsgVerbose("frame, and has a fast UnwindPlan"); - else - UnwindLogMsgVerbose("frame"); - } m_frame_type = eNormalFrame; return unwind_plan_sp; } else { @@ -702,10 +794,9 @@ UnwindPlanSP RegisterContextUnwind::GetFullUnwindPlanForFrame() { "unable to get architectural default UnwindPlan from ABI plugin"); } - bool behaves_like_zeroth_frame = false; if (IsFrameZero() || GetNextFrame()->m_frame_type == eTrapHandlerFrame || GetNextFrame()->m_frame_type == eDebuggerFrame) { - behaves_like_zeroth_frame = true; + m_behaves_like_zeroth_frame = true; // If this frame behaves like a 0th frame (currently executing or // interrupted asynchronously), all registers can be retrieved. m_all_registers_available = true; @@ -721,7 +812,7 @@ UnwindPlanSP RegisterContextUnwind::GetFullUnwindPlanForFrame() { if ((!m_sym_ctx_valid || (m_sym_ctx.function == nullptr && m_sym_ctx.symbol == nullptr)) && - behaves_like_zeroth_frame && m_current_pc.IsValid()) { + m_behaves_like_zeroth_frame && m_current_pc.IsValid()) { uint32_t permissions; addr_t current_pc_addr = m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr()); @@ -849,7 +940,7 @@ UnwindPlanSP RegisterContextUnwind::GetFullUnwindPlanForFrame() { // Typically the NonCallSite UnwindPlan is the unwind created by inspecting // the assembly language instructions - if (behaves_like_zeroth_frame && process) { + if (m_behaves_like_zeroth_frame && process) { unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite( process->GetTarget(), m_thread); if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc)) { @@ -1147,6 +1238,7 @@ enum UnwindLLDB::RegisterSearchResult RegisterContextUnwind::SavedLocationForRegister( uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation ®loc) { RegisterNumber regnum(m_thread, eRegisterKindLLDB, lldb_regnum); + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); // Have we already found this register location? if (!m_registers.empty()) { @@ -1179,8 +1271,17 @@ RegisterContextUnwind::SavedLocationForRegister( (int)unwindplan_registerkind); return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; } + // The architecture default unwind plan marks unknown registers as + // Undefined so that we don't forward them up the stack when a + // jitted stack frame may have overwritten them. But when the + // arch default unwind plan is used as the Fast Unwind Plan, we + // need to recognize this & switch over to the Full Unwind Plan + // to see what unwind rule that (more knoweldgeable, probably) + // UnwindPlan has. If the full UnwindPlan says the register + // location is Undefined, then it really is. if (active_row->GetRegisterInfo(regnum.GetAsKind(unwindplan_registerkind), - unwindplan_regloc)) { + unwindplan_regloc) && + !unwindplan_regloc.IsUndefined()) { UnwindLogMsg( "supplying caller's saved %s (%d)'s location using FastUnwindPlan", regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); @@ -1191,8 +1292,11 @@ RegisterContextUnwind::SavedLocationForRegister( if (!have_unwindplan_regloc) { // m_full_unwind_plan_sp being NULL means that we haven't tried to find a // full UnwindPlan yet - if (!m_full_unwind_plan_sp) + bool got_new_full_unwindplan = false; + if (!m_full_unwind_plan_sp) { m_full_unwind_plan_sp = GetFullUnwindPlanForFrame(); + got_new_full_unwindplan = true; + } if (m_full_unwind_plan_sp) { RegisterNumber pc_regnum(m_thread, eRegisterKindGeneric, @@ -1202,6 +1306,16 @@ RegisterContextUnwind::SavedLocationForRegister( m_full_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset); unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind(); + if (got_new_full_unwindplan && active_row.get() && log) { + StreamString active_row_strm; + ExecutionContext exe_ctx(m_thread.shared_from_this()); + active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), + &m_thread, + m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr())); + UnwindLogMsg("Using full unwind plan '%s'", + m_full_unwind_plan_sp->GetSourceName().AsCString()); + UnwindLogMsg("active row: %s", active_row_strm.GetData()); + } RegisterNumber return_address_reg; // If we're fetching the saved pc and this UnwindPlan defines a @@ -1521,7 +1635,7 @@ RegisterContextUnwind::SavedLocationForRegister( DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr); dwarfexpr.SetRegisterKind(unwindplan_registerkind); Value cfa_val = Scalar(m_cfa); - cfa_val.SetValueType(Value::eValueTypeLoadAddress); + cfa_val.SetValueType(Value::ValueType::LoadAddress); Value result; Status error; if (dwarfexpr.Evaluate(&exe_ctx, this, 0, &cfa_val, nullptr, result, @@ -1616,6 +1730,10 @@ bool RegisterContextUnwind::TryFallbackUnwindPlan() { RegisterValue reg_value; if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) { old_caller_pc_value = reg_value.GetAsUInt64(); + if (ProcessSP process_sp = m_thread.GetProcess()) { + if (ABISP abi = process_sp->GetABI()) + old_caller_pc_value = abi->FixCodeAddress(old_caller_pc_value); + } } } } @@ -1671,6 +1789,10 @@ bool RegisterContextUnwind::TryFallbackUnwindPlan() { if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) { new_caller_pc_value = reg_value.GetAsUInt64(); + if (ProcessSP process_sp = m_thread.GetProcess()) { + if (ABISP abi = process_sp->GetABI()) + new_caller_pc_value = abi->FixCodeAddress(new_caller_pc_value); + } } } } @@ -1824,6 +1946,8 @@ bool RegisterContextUnwind::ReadFrameAddress( reg_info, cfa_reg_contents, reg_info->byte_size, reg_value); if (error.Success()) { address = reg_value.GetAsUInt64(); + if (ABISP abi_sp = m_thread.GetProcess()->GetABI()) + address = abi_sp->FixCodeAddress(address); UnwindLogMsg( "CFA value via dereferencing reg %s (%d): reg has val 0x%" PRIx64 ", CFA value is 0x%" PRIx64, @@ -1878,6 +2002,8 @@ bool RegisterContextUnwind::ReadFrameAddress( if (dwarfexpr.Evaluate(&exe_ctx, this, 0, nullptr, nullptr, result, &error)) { address = result.GetScalar().ULongLong(); + if (ABISP abi_sp = m_thread.GetProcess()->GetABI()) + address = abi_sp->FixCodeAddress(address); UnwindLogMsg("CFA value set by DWARF expression is 0x%" PRIx64, address); @@ -2007,6 +2133,12 @@ bool RegisterContextUnwind::ReadGPRValue(lldb::RegisterKind register_kind, } if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) { value = reg_value.GetAsUInt64(); + if (pc_register) { + if (ProcessSP process_sp = m_thread.GetProcess()) { + if (ABISP abi = process_sp->GetABI()) + value = abi->FixCodeAddress(value); + } + } return true; } return false; @@ -2048,7 +2180,19 @@ bool RegisterContextUnwind::ReadRegister(const RegisterInfo *reg_info, lldb_regnum, regloc, m_frame_number - 1, is_pc_regnum)) return false; - return ReadRegisterValueFromRegisterLocation(regloc, reg_info, value); + bool result = ReadRegisterValueFromRegisterLocation(regloc, reg_info, value); + if (result) { + if (is_pc_regnum && value.GetType() == RegisterValue::eTypeUInt64) { + addr_t reg_value = value.GetAsUInt64(LLDB_INVALID_ADDRESS); + if (reg_value != LLDB_INVALID_ADDRESS) { + if(ProcessSP process_sp = m_thread.GetProcess()) { + if (ABISP abi = process_sp->GetABI()) + value = abi->FixCodeAddress(reg_value); + } + } + } + } + return result; } bool RegisterContextUnwind::WriteRegister(const RegisterInfo *reg_info, diff --git a/contrib/llvm-project/lldb/source/Target/RegisterNumber.cpp b/contrib/llvm-project/lldb/source/Target/RegisterNumber.cpp index 0ea9f212c693..e5610bf58854 100644 --- a/contrib/llvm-project/lldb/source/Target/RegisterNumber.cpp +++ b/contrib/llvm-project/lldb/source/Target/RegisterNumber.cpp @@ -26,9 +26,7 @@ RegisterNumber::RegisterNumber(lldb_private::Thread &thread, } } -RegisterNumber::RegisterNumber() - : m_reg_ctx_sp(), m_regnum(LLDB_INVALID_REGNUM), - m_kind(lldb::kNumRegisterKinds), m_kind_regnum_map(), m_name(nullptr) {} +RegisterNumber::RegisterNumber() : m_reg_ctx_sp(), m_kind_regnum_map() {} void RegisterNumber::init(lldb_private::Thread &thread, lldb::RegisterKind kind, uint32_t num) { diff --git a/contrib/llvm-project/lldb/source/Target/RemoteAwarePlatform.cpp b/contrib/llvm-project/lldb/source/Target/RemoteAwarePlatform.cpp index 3a186adca04c..b0c43ffa839e 100644 --- a/contrib/llvm-project/lldb/source/Target/RemoteAwarePlatform.cpp +++ b/contrib/llvm-project/lldb/source/Target/RemoteAwarePlatform.cpp @@ -437,3 +437,10 @@ Status RemoteAwarePlatform::KillProcess(const lldb::pid_t pid) { return m_remote_platform_sp->KillProcess(pid); return Status("the platform is not currently connected"); } + +size_t RemoteAwarePlatform::ConnectToWaitingProcesses(Debugger &debugger, + Status &error) { + if (m_remote_platform_sp) + return m_remote_platform_sp->ConnectToWaitingProcesses(debugger, error); + return Platform::ConnectToWaitingProcesses(debugger, error); +} diff --git a/contrib/llvm-project/lldb/source/Target/StackFrame.cpp b/contrib/llvm-project/lldb/source/Target/StackFrame.cpp index 131581567d73..cba51d266c5b 100644 --- a/contrib/llvm-project/lldb/source/Target/StackFrame.cpp +++ b/contrib/llvm-project/lldb/source/Target/StackFrame.cpp @@ -213,6 +213,35 @@ const Address &StackFrame::GetFrameCodeAddress() { return m_frame_code_addr; } +// This can't be rewritten into a call to +// RegisterContext::GetPCForSymbolication because this +// StackFrame may have been constructed with a special pc, +// e.g. tail-call artificial frames. +Address StackFrame::GetFrameCodeAddressForSymbolication() { + Address lookup_addr(GetFrameCodeAddress()); + if (!lookup_addr.IsValid()) + return lookup_addr; + if (m_behaves_like_zeroth_frame) + return lookup_addr; + + addr_t offset = lookup_addr.GetOffset(); + if (offset > 0) { + lookup_addr.SetOffset(offset - 1); + } else { + // lookup_addr is the start of a section. We need do the math on the + // actual load address and re-compute the section. We're working with + // a 'noreturn' function at the end of a section. + TargetSP target_sp = CalculateTarget(); + if (target_sp) { + addr_t addr_minus_one = lookup_addr.GetOpcodeLoadAddress( + target_sp.get(), AddressClass::eCode) - + 1; + lookup_addr.SetOpcodeLoadAddress(addr_minus_one, target_sp.get()); + } + } + return lookup_addr; +} + bool StackFrame::ChangePC(addr_t pc) { std::lock_guard<std::recursive_mutex> guard(m_mutex); // We can't change the pc value of a history stack frame - it is immutable. @@ -288,30 +317,7 @@ StackFrame::GetSymbolContext(SymbolContextItem resolve_scope) { // If this is not frame zero, then we need to subtract 1 from the PC value // when doing address lookups since the PC will be on the instruction // following the function call instruction... - - Address lookup_addr(GetFrameCodeAddress()); - if (!m_behaves_like_zeroth_frame && lookup_addr.IsValid()) { - addr_t offset = lookup_addr.GetOffset(); - if (offset > 0) { - lookup_addr.SetOffset(offset - 1); - - } else { - // lookup_addr is the start of a section. We need do the math on the - // actual load address and re-compute the section. We're working with - // a 'noreturn' function at the end of a section. - ThreadSP thread_sp(GetThread()); - if (thread_sp) { - TargetSP target_sp(thread_sp->CalculateTarget()); - if (target_sp) { - addr_t addr_minus_one = - lookup_addr.GetLoadAddress(target_sp.get()) - 1; - lookup_addr.SetLoadAddress(addr_minus_one, target_sp.get()); - } else { - lookup_addr.SetOffset(offset - 1); - } - } - } - } + Address lookup_addr(GetFrameCodeAddressForSymbolication()); if (m_sc.module_sp) { // We have something in our stack frame symbol context, lets check if we @@ -1160,31 +1166,6 @@ StackFrame::GetValueObjectForFrameVariable(const VariableSP &variable_sp, return valobj_sp; } -ValueObjectSP StackFrame::TrackGlobalVariable(const VariableSP &variable_sp, - DynamicValueType use_dynamic) { - std::lock_guard<std::recursive_mutex> guard(m_mutex); - if (IsHistorical()) - return ValueObjectSP(); - - // Check to make sure we aren't already tracking this variable? - ValueObjectSP valobj_sp( - GetValueObjectForFrameVariable(variable_sp, use_dynamic)); - if (!valobj_sp) { - // We aren't already tracking this global - VariableList *var_list = GetVariableList(true); - // If this frame has no variables, create a new list - if (var_list == nullptr) - m_variable_list_sp = std::make_shared<VariableList>(); - - // Add the global/static variable to this frame - m_variable_list_sp->AddVariable(variable_sp); - - // Now make a value object for it so we can track its changes - valobj_sp = GetValueObjectForFrameVariable(variable_sp, use_dynamic); - } - return valobj_sp; -} - bool StackFrame::IsInlined() { if (m_sc.block == nullptr) GetSymbolContext(eSymbolContextBlock); @@ -1313,11 +1294,11 @@ lldb::ValueObjectSP StackFrame::GuessValueForAddress(lldb::addr_t addr) { const char *plugin_name = nullptr; const char *flavor = nullptr; - const bool prefer_file_cache = false; + const bool force_live_memory = true; DisassemblerSP disassembler_sp = Disassembler::DisassembleRange(target_arch, plugin_name, flavor, - *target_sp, pc_range, prefer_file_cache); + *target_sp, pc_range, force_live_memory); if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) { return ValueObjectSP(); @@ -1693,10 +1674,10 @@ lldb::ValueObjectSP StackFrame::GuessValueForRegisterAndOffset(ConstString reg, const char *plugin_name = nullptr; const char *flavor = nullptr; - const bool prefer_file_cache = false; + const bool force_live_memory = true; DisassemblerSP disassembler_sp = Disassembler::DisassembleRange(target_arch, plugin_name, flavor, - *target_sp, pc_range, prefer_file_cache); + *target_sp, pc_range, force_live_memory); if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) { return ValueObjectSP(); diff --git a/contrib/llvm-project/lldb/source/Target/StackFrameList.cpp b/contrib/llvm-project/lldb/source/Target/StackFrameList.cpp index e4f5d3028366..061500152a49 100644 --- a/contrib/llvm-project/lldb/source/Target/StackFrameList.cpp +++ b/contrib/llvm-project/lldb/source/Target/StackFrameList.cpp @@ -131,6 +131,9 @@ void StackFrameList::ResetCurrentInlinedDepth() { case eStopReasonWatchpoint: case eStopReasonException: case eStopReasonExec: + case eStopReasonFork: + case eStopReasonVFork: + case eStopReasonVForkDone: case eStopReasonSignal: // In all these cases we want to stop in the deepest frame. m_current_inlined_pc = curr_pc; @@ -522,27 +525,10 @@ void StackFrameList::GetFramesUpTo(uint32_t end_idx) { SymbolContext unwind_sc = unwind_frame_sp->GetSymbolContext( eSymbolContextBlock | eSymbolContextFunction); Block *unwind_block = unwind_sc.block; + TargetSP target_sp = m_thread.CalculateTarget(); if (unwind_block) { - Address curr_frame_address(unwind_frame_sp->GetFrameCodeAddress()); - TargetSP target_sp = m_thread.CalculateTarget(); - // Be sure to adjust the frame address to match the address that was - // used to lookup the symbol context above. If we are in the first - // concrete frame, then we lookup using the current address, else we - // decrement the address by one to get the correct location. - if (idx > 0) { - if (curr_frame_address.GetOffset() == 0) { - // If curr_frame_address points to the first address in a section - // then after adjustment it will point to an other section. In that - // case resolve the address again to the correct section plus - // offset form. - addr_t load_addr = curr_frame_address.GetOpcodeLoadAddress( - target_sp.get(), AddressClass::eCode); - curr_frame_address.SetOpcodeLoadAddress( - load_addr - 1, target_sp.get(), AddressClass::eCode); - } else { - curr_frame_address.Slide(-1); - } - } + Address curr_frame_address( + unwind_frame_sp->GetFrameCodeAddressForSymbolication()); SymbolContext next_frame_sc; Address next_frame_address; @@ -840,105 +826,6 @@ void StackFrameList::Clear() { m_concrete_frames_fetched = 0; } -void StackFrameList::Merge(std::unique_ptr<StackFrameList> &curr_up, - lldb::StackFrameListSP &prev_sp) { - std::unique_lock<std::recursive_mutex> current_lock, previous_lock; - if (curr_up) - current_lock = std::unique_lock<std::recursive_mutex>(curr_up->m_mutex); - if (prev_sp) - previous_lock = std::unique_lock<std::recursive_mutex>(prev_sp->m_mutex); - -#if defined(DEBUG_STACK_FRAMES) - StreamFile s(stdout, false); - s.PutCString("\n\nStackFrameList::Merge():\nPrev:\n"); - if (prev_sp) - prev_sp->Dump(&s); - else - s.PutCString("NULL"); - s.PutCString("\nCurr:\n"); - if (curr_up) - curr_up->Dump(&s); - else - s.PutCString("NULL"); - s.EOL(); -#endif - - if (!curr_up || curr_up->GetNumFrames(false) == 0) { -#if defined(DEBUG_STACK_FRAMES) - s.PutCString("No current frames, leave previous frames alone...\n"); -#endif - curr_up.release(); - return; - } - - if (!prev_sp || prev_sp->GetNumFrames(false) == 0) { -#if defined(DEBUG_STACK_FRAMES) - s.PutCString("No previous frames, so use current frames...\n"); -#endif - // We either don't have any previous frames, or since we have more than one - // current frames it means we have all the frames and can safely replace - // our previous frames. - prev_sp.reset(curr_up.release()); - return; - } - - const uint32_t num_curr_frames = curr_up->GetNumFrames(false); - - if (num_curr_frames > 1) { -#if defined(DEBUG_STACK_FRAMES) - s.PutCString( - "We have more than one current frame, so use current frames...\n"); -#endif - // We have more than one current frames it means we have all the frames and - // can safely replace our previous frames. - prev_sp.reset(curr_up.release()); - -#if defined(DEBUG_STACK_FRAMES) - s.PutCString("\nMerged:\n"); - prev_sp->Dump(&s); -#endif - return; - } - - StackFrameSP prev_frame_zero_sp(prev_sp->GetFrameAtIndex(0)); - StackFrameSP curr_frame_zero_sp(curr_up->GetFrameAtIndex(0)); - StackID curr_stack_id(curr_frame_zero_sp->GetStackID()); - StackID prev_stack_id(prev_frame_zero_sp->GetStackID()); - -#if defined(DEBUG_STACK_FRAMES) - const uint32_t num_prev_frames = prev_sp->GetNumFrames(false); - s.Printf("\n%u previous frames with one current frame\n", num_prev_frames); -#endif - - // We have only a single current frame - // Our previous stack frames only had a single frame as well... - if (curr_stack_id == prev_stack_id) { -#if defined(DEBUG_STACK_FRAMES) - s.Printf("\nPrevious frame #0 is same as current frame #0, merge the " - "cached data\n"); -#endif - - curr_frame_zero_sp->UpdateCurrentFrameFromPreviousFrame( - *prev_frame_zero_sp); - // prev_frame_zero_sp->UpdatePreviousFrameFromCurrentFrame - // (*curr_frame_zero_sp); - // prev_sp->SetFrameAtIndex (0, prev_frame_zero_sp); - } else if (curr_stack_id < prev_stack_id) { -#if defined(DEBUG_STACK_FRAMES) - s.Printf("\nCurrent frame #0 has a stack ID that is less than the previous " - "frame #0, insert current frame zero in front of previous\n"); -#endif - prev_sp->m_frames.insert(prev_sp->m_frames.begin(), curr_frame_zero_sp); - } - - curr_up.release(); - -#if defined(DEBUG_STACK_FRAMES) - s.PutCString("\nMerged:\n"); - prev_sp->Dump(&s); -#endif -} - lldb::StackFrameSP StackFrameList::GetStackFrameSPForStackFramePtr(StackFrame *stack_frame_ptr) { const_iterator pos; diff --git a/contrib/llvm-project/lldb/source/Target/StopInfo.cpp b/contrib/llvm-project/lldb/source/Target/StopInfo.cpp index 7e830c6e2bed..aeb97f1919eb 100644 --- a/contrib/llvm-project/lldb/source/Target/StopInfo.cpp +++ b/contrib/llvm-project/lldb/source/Target/StopInfo.cpp @@ -125,7 +125,7 @@ public: BreakpointSiteSP bp_site_sp( process_sp->GetBreakpointSiteList().FindByID(m_value)); if (bp_site_sp) - return bp_site_sp->ValidForThisThread(&thread); + return bp_site_sp->ValidForThisThread(thread); } return false; } @@ -305,6 +305,20 @@ protected: // location said we should stop. But that's better than not running // all the callbacks. + // There's one other complication here. We may have run an async + // breakpoint callback that said we should stop. We only want to + // override that if another breakpoint action says we shouldn't + // stop. If nobody else has an opinion, then we should stop if the + // async callback says we should. An example of this is the async + // shared library load notification breakpoint and the setting + // stop-on-sharedlibrary-events. + // We'll keep the async value in async_should_stop, and track whether + // anyone said we should NOT stop in actually_said_continue. + bool async_should_stop = false; + if (m_should_stop_is_valid) + async_should_stop = m_should_stop; + bool actually_said_continue = false; + m_should_stop = false; // We don't select threads as we go through them testing breakpoint @@ -399,7 +413,7 @@ protected: // The breakpoint site may have many locations associated with it, // not all of them valid for this thread. Skip the ones that // aren't: - if (!bp_loc_sp->ValidForThisThread(thread_sp.get())) { + if (!bp_loc_sp->ValidForThisThread(*thread_sp)) { if (log) { LLDB_LOGF(log, "Breakpoint %s hit on thread 0x%llx but it was not " @@ -422,9 +436,10 @@ protected: bool precondition_result = bp_loc_sp->GetBreakpoint().EvaluatePrecondition(context); - if (!precondition_result) + if (!precondition_result) { + actually_said_continue = true; continue; - + } // Next run the condition for the breakpoint. If that says we // should stop, then we'll run the callback for the breakpoint. If // the callback says we shouldn't stop that will win. @@ -462,11 +477,21 @@ protected: // the condition fails. We've already bumped it by the time // we get here, so undo the bump: bp_loc_sp->UndoBumpHitCount(); + actually_said_continue = true; continue; } } } + // We've done all the checks whose failure means "we consider lldb + // not to have hit the breakpoint". Now we're going to check for + // conditions that might continue after hitting. Start with the + // ignore count: + if (!bp_loc_sp->IgnoreCountShouldStop()) { + actually_said_continue = true; + continue; + } + // Check the auto-continue bit on the location, do this before the // callback since it may change this, but that would be for the // NEXT hit. Note, you might think you could check auto-continue @@ -494,16 +519,22 @@ protected: // When we figure out how to nest breakpoint hits then this will // change. - Debugger &debugger = thread_sp->CalculateTarget()->GetDebugger(); - bool old_async = debugger.GetAsyncExecution(); - debugger.SetAsyncExecution(true); + // Don't run async callbacks in PerformAction. They have already + // been taken into account with async_should_stop. + if (!bp_loc_sp->IsCallbackSynchronous()) { + Debugger &debugger = thread_sp->CalculateTarget()->GetDebugger(); + bool old_async = debugger.GetAsyncExecution(); + debugger.SetAsyncExecution(true); - callback_says_stop = bp_loc_sp->InvokeCallback(&context); + callback_says_stop = bp_loc_sp->InvokeCallback(&context); - debugger.SetAsyncExecution(old_async); + debugger.SetAsyncExecution(old_async); - if (callback_says_stop && auto_continue_says_stop) - m_should_stop = true; + if (callback_says_stop && auto_continue_says_stop) + m_should_stop = true; + else + actually_said_continue = true; + } // If we are going to stop for this breakpoint, then remove the // breakpoint. @@ -517,9 +548,15 @@ protected: // here. if (HasTargetRunSinceMe()) { m_should_stop = false; + actually_said_continue = true; break; } } + // At this point if nobody actually told us to continue, we should + // give the async breakpoint callback a chance to weigh in: + if (!actually_said_continue && !m_should_stop) { + m_should_stop = async_should_stop; + } } // We've figured out what this stop wants to do, so mark it as valid so // we don't compute it again. @@ -1016,6 +1053,30 @@ public: } }; +// StopInfoProcessorTrace + +class StopInfoProcessorTrace : public StopInfo { +public: + StopInfoProcessorTrace(Thread &thread, const char *description) + : StopInfo(thread, LLDB_INVALID_UID) { + if (description) + SetDescription(description); + } + + ~StopInfoProcessorTrace() override = default; + + StopReason GetStopReason() const override { + return eStopReasonProcessorTrace; + } + + const char *GetDescription() override { + if (m_description.empty()) + return "processor trace event"; + else + return m_description.c_str(); + } +}; + // StopInfoThreadPlan class StopInfoThreadPlan : public StopInfo { @@ -1133,6 +1194,11 @@ StopInfoSP StopInfo::CreateStopReasonWithException(Thread &thread, return StopInfoSP(new StopInfoException(thread, description)); } +StopInfoSP StopInfo::CreateStopReasonProcessorTrace(Thread &thread, + const char *description) { + return StopInfoSP(new StopInfoProcessorTrace(thread, description)); +} + StopInfoSP StopInfo::CreateStopReasonWithExec(Thread &thread) { return StopInfoSP(new StopInfoExec(thread)); } diff --git a/contrib/llvm-project/lldb/source/Target/StructuredDataPlugin.cpp b/contrib/llvm-project/lldb/source/Target/StructuredDataPlugin.cpp index bd899d2f7681..20ed26a1a99a 100644 --- a/contrib/llvm-project/lldb/source/Target/StructuredDataPlugin.cpp +++ b/contrib/llvm-project/lldb/source/Target/StructuredDataPlugin.cpp @@ -23,14 +23,14 @@ public: "Parent for per-plugin structured data commands", "plugin structured-data <plugin>") {} - ~CommandStructuredData() override {} + ~CommandStructuredData() override = default; }; } StructuredDataPlugin::StructuredDataPlugin(const ProcessWP &process_wp) : PluginInterface(), m_process_wp(process_wp) {} -StructuredDataPlugin::~StructuredDataPlugin() {} +StructuredDataPlugin::~StructuredDataPlugin() = default; bool StructuredDataPlugin::GetEnabled(ConstString type_name) const { // By default, plugins are always enabled. Plugin authors should override diff --git a/contrib/llvm-project/lldb/source/Target/Target.cpp b/contrib/llvm-project/lldb/source/Target/Target.cpp index 736864e021bb..1f8e8c54fa9e 100644 --- a/contrib/llvm-project/lldb/source/Target/Target.cpp +++ b/contrib/llvm-project/lldb/source/Target/Target.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "lldb/Target/Target.h" -#include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h" #include "lldb/Breakpoint/BreakpointIDList.h" #include "lldb/Breakpoint/BreakpointPrecondition.h" #include "lldb/Breakpoint/BreakpointResolver.h" @@ -42,6 +41,7 @@ #include "lldb/Symbol/Function.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/Symbol.h" +#include "lldb/Target/ABI.h" #include "lldb/Target/Language.h" #include "lldb/Target/LanguageRuntime.h" #include "lldb/Target/Process.h" @@ -95,6 +95,7 @@ Target::Target(Debugger &debugger, const ArchSpec &target_arch, m_watchpoint_list(), m_process_sp(), m_search_filter_sp(), m_image_search_paths(ImageSearchPathsChanged, this), m_source_manager_up(), m_stop_hooks(), m_stop_hook_next_id(0), + m_latest_stop_hook_id(0), m_valid(true), m_suppress_stop_hooks(false), m_is_dummy_target(is_dummy_target), m_frame_recognizer_manager_up( @@ -181,6 +182,7 @@ void Target::CleanupProcess() { DisableAllWatchpoints(false); ClearAllWatchpointHitCounts(); ClearAllWatchpointHistoricValues(); + m_latest_stop_hook_id = 0; } void Target::DeleteCurrentProcess() { @@ -371,9 +373,14 @@ BreakpointSP Target::CreateBreakpoint(const FileSpecList *containingModules, if (move_to_nearest_code == eLazyBoolCalculate) move_to_nearest_code = GetMoveToNearestCode() ? eLazyBoolYes : eLazyBoolNo; + SourceLocationSpec location_spec(remapped_file, line_no, column, + check_inlines, + !static_cast<bool>(move_to_nearest_code)); + if (!location_spec) + return nullptr; + BreakpointResolverSP resolver_sp(new BreakpointResolverFileLine( - nullptr, remapped_file, line_no, column, offset, check_inlines, - skip_prologue, !static_cast<bool>(move_to_nearest_code))); + nullptr, offset, skip_prologue, location_spec)); return CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true); } @@ -819,6 +826,11 @@ WatchpointSP Target::CreateWatchpoint(lldb::addr_t addr, size_t size, // Grab the list mutex while doing operations. const bool notify = false; // Don't notify about all the state changes we do // on creating the watchpoint. + + // Mask off ignored bits from watchpoint address. + if (ABISP abi = m_process_sp->GetABI()) + addr = abi->FixDataAddress(addr); + std::unique_lock<std::recursive_mutex> lock; this->GetWatchpointList().GetListMutex(lock); WatchpointSP matched_sp = m_watchpoint_list.FindByAddress(addr); @@ -1149,9 +1161,7 @@ bool Target::RemoveAllWatchpoints(bool end_to_end) { if (!ProcessIsValid()) return false; - size_t num_watchpoints = m_watchpoint_list.GetSize(); - for (size_t i = 0; i < num_watchpoints; ++i) { - WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i); + for (WatchpointSP wp_sp : m_watchpoint_list.Watchpoints()) { if (!wp_sp) return false; @@ -1180,9 +1190,7 @@ bool Target::DisableAllWatchpoints(bool end_to_end) { if (!ProcessIsValid()) return false; - size_t num_watchpoints = m_watchpoint_list.GetSize(); - for (size_t i = 0; i < num_watchpoints; ++i) { - WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i); + for (WatchpointSP wp_sp : m_watchpoint_list.Watchpoints()) { if (!wp_sp) return false; @@ -1209,9 +1217,7 @@ bool Target::EnableAllWatchpoints(bool end_to_end) { if (!ProcessIsValid()) return false; - size_t num_watchpoints = m_watchpoint_list.GetSize(); - for (size_t i = 0; i < num_watchpoints; ++i) { - WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i); + for (WatchpointSP wp_sp : m_watchpoint_list.Watchpoints()) { if (!wp_sp) return false; @@ -1227,9 +1233,7 @@ bool Target::ClearAllWatchpointHitCounts() { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); LLDB_LOGF(log, "Target::%s\n", __FUNCTION__); - size_t num_watchpoints = m_watchpoint_list.GetSize(); - for (size_t i = 0; i < num_watchpoints; ++i) { - WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i); + for (WatchpointSP wp_sp : m_watchpoint_list.Watchpoints()) { if (!wp_sp) return false; @@ -1243,9 +1247,7 @@ bool Target::ClearAllWatchpointHistoricValues() { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); LLDB_LOGF(log, "Target::%s\n", __FUNCTION__); - size_t num_watchpoints = m_watchpoint_list.GetSize(); - for (size_t i = 0; i < num_watchpoints; ++i) { - WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i); + for (WatchpointSP wp_sp : m_watchpoint_list.Watchpoints()) { if (!wp_sp) return false; @@ -1263,9 +1265,7 @@ bool Target::IgnoreAllWatchpoints(uint32_t ignore_count) { if (!ProcessIsValid()) return false; - size_t num_watchpoints = m_watchpoint_list.GetSize(); - for (size_t i = 0; i < num_watchpoints; ++i) { - WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i); + for (WatchpointSP wp_sp : m_watchpoint_list.Watchpoints()) { if (!wp_sp) return false; @@ -1687,6 +1687,7 @@ bool Target::ModuleIsExcludedForUnconstrainedSearches( size_t Target::ReadMemoryFromFileCache(const Address &addr, void *dst, size_t dst_len, Status &error) { + LLDB_SCOPED_TIMER(); SectionSP section_sp(addr.GetSection()); if (section_sp) { // If the contents of this section are encrypted, the on-disk file is @@ -1717,8 +1718,8 @@ size_t Target::ReadMemoryFromFileCache(const Address &addr, void *dst, return 0; } -size_t Target::ReadMemory(const Address &addr, bool prefer_file_cache, - void *dst, size_t dst_len, Status &error, +size_t Target::ReadMemory(const Address &addr, void *dst, size_t dst_len, + Status &error, bool force_live_memory, lldb::addr_t *load_addr_ptr) { error.Clear(); @@ -1753,10 +1754,31 @@ size_t Target::ReadMemory(const Address &addr, bool prefer_file_cache, if (!resolved_addr.IsValid()) resolved_addr = addr; - if (prefer_file_cache) { - bytes_read = ReadMemoryFromFileCache(resolved_addr, dst, dst_len, error); - if (bytes_read > 0) - return bytes_read; + // If we read from the file cache but can't get as many bytes as requested, + // we keep the result around in this buffer, in case this result is the + // best we can do. + std::unique_ptr<uint8_t[]> file_cache_read_buffer; + size_t file_cache_bytes_read = 0; + + // Read from file cache if read-only section. + if (!force_live_memory && resolved_addr.IsSectionOffset()) { + SectionSP section_sp(resolved_addr.GetSection()); + if (section_sp) { + auto permissions = Flags(section_sp->GetPermissions()); + bool is_readonly = !permissions.Test(ePermissionsWritable) && + permissions.Test(ePermissionsReadable); + if (is_readonly) { + file_cache_bytes_read = + ReadMemoryFromFileCache(resolved_addr, dst, dst_len, error); + if (file_cache_bytes_read == dst_len) + return file_cache_bytes_read; + else if (file_cache_bytes_read > 0) { + file_cache_read_buffer = + std::make_unique<uint8_t[]>(file_cache_bytes_read); + std::memcpy(file_cache_read_buffer.get(), dst, file_cache_bytes_read); + } + } + } } if (ProcessIsValid()) { @@ -1791,17 +1813,17 @@ size_t Target::ReadMemory(const Address &addr, bool prefer_file_cache, *load_addr_ptr = load_addr; return bytes_read; } - // If the address is not section offset we have an address that doesn't - // resolve to any address in any currently loaded shared libraries and we - // failed to read memory so there isn't anything more we can do. If it is - // section offset, we might be able to read cached memory from the object - // file. - if (!resolved_addr.IsSectionOffset()) - return 0; } } - if (!prefer_file_cache && resolved_addr.IsSectionOffset()) { + if (file_cache_read_buffer && file_cache_bytes_read > 0) { + // Reading from the process failed. If we've previously succeeded in reading + // something from the file cache, then copy that over and return that. + std::memcpy(dst, file_cache_read_buffer.get(), file_cache_bytes_read); + return file_cache_bytes_read; + } + + if (!file_cache_read_buffer && resolved_addr.IsSectionOffset()) { // If we didn't already try and read from the object file cache, then try // it after failing to read from the process. return ReadMemoryFromFileCache(resolved_addr, dst, dst_len, error); @@ -1856,7 +1878,7 @@ size_t Target::ReadCStringFromMemory(const Address &addr, char *dst, addr_t bytes_to_read = std::min<addr_t>(bytes_left, cache_line_bytes_left); size_t bytes_read = - ReadMemory(address, false, curr_dst, bytes_to_read, error); + ReadMemory(address, curr_dst, bytes_to_read, error, true); if (bytes_read == 0) { result_error = error; @@ -1884,15 +1906,15 @@ size_t Target::ReadCStringFromMemory(const Address &addr, char *dst, return total_cstr_len; } -size_t Target::ReadScalarIntegerFromMemory(const Address &addr, - bool prefer_file_cache, - uint32_t byte_size, bool is_signed, - Scalar &scalar, Status &error) { +size_t Target::ReadScalarIntegerFromMemory(const Address &addr, uint32_t byte_size, + bool is_signed, Scalar &scalar, + Status &error, + bool force_live_memory) { uint64_t uval; if (byte_size <= sizeof(uval)) { size_t bytes_read = - ReadMemory(addr, prefer_file_cache, &uval, byte_size, error); + ReadMemory(addr, &uval, byte_size, error, force_live_memory); if (bytes_read == byte_size) { DataExtractor data(&uval, sizeof(uval), m_arch.GetSpec().GetByteOrder(), m_arch.GetSpec().GetAddressByteSize()); @@ -1914,23 +1936,22 @@ size_t Target::ReadScalarIntegerFromMemory(const Address &addr, } uint64_t Target::ReadUnsignedIntegerFromMemory(const Address &addr, - bool prefer_file_cache, size_t integer_byte_size, - uint64_t fail_value, - Status &error) { + uint64_t fail_value, Status &error, + bool force_live_memory) { Scalar scalar; - if (ReadScalarIntegerFromMemory(addr, prefer_file_cache, integer_byte_size, - false, scalar, error)) + if (ReadScalarIntegerFromMemory(addr, integer_byte_size, false, scalar, error, + force_live_memory)) return scalar.ULongLong(fail_value); return fail_value; } -bool Target::ReadPointerFromMemory(const Address &addr, bool prefer_file_cache, - Status &error, Address &pointer_addr) { +bool Target::ReadPointerFromMemory(const Address &addr, Status &error, + Address &pointer_addr, + bool force_live_memory) { Scalar scalar; - if (ReadScalarIntegerFromMemory(addr, prefer_file_cache, - m_arch.GetSpec().GetAddressByteSize(), false, - scalar, error)) { + if (ReadScalarIntegerFromMemory(addr, m_arch.GetSpec().GetAddressByteSize(), + false, scalar, error, force_live_memory)) { addr_t pointer_vm_addr = scalar.ULongLong(LLDB_INVALID_ADDRESS); if (pointer_vm_addr != LLDB_INVALID_ADDRESS) { SectionLoadList §ion_load_list = GetSectionLoadList(); @@ -2521,23 +2542,6 @@ SourceManager &Target::GetSourceManager() { return *m_source_manager_up; } -ClangModulesDeclVendor *Target::GetClangModulesDeclVendor() { - static std::mutex s_clang_modules_decl_vendor_mutex; // If this is contended - // we can make it - // per-target - - { - std::lock_guard<std::mutex> guard(s_clang_modules_decl_vendor_mutex); - - if (!m_clang_modules_decl_vendor_up) { - m_clang_modules_decl_vendor_up.reset( - ClangModulesDeclVendor::Create(*this)); - } - } - - return m_clang_modules_decl_vendor_up.get(); -} - Target::StopHookSP Target::CreateStopHook(StopHook::StopHookKind kind) { lldb::user_id_t new_uid = ++m_stop_hook_next_id; Target::StopHookSP stop_hook_sp; @@ -2607,12 +2611,6 @@ bool Target::RunStopHooks() { if (m_process_sp->GetState() != eStateStopped) return false; - // <rdar://problem/12027563> make sure we check that we are not stopped - // because of us running a user expression since in that case we do not want - // to run the stop-hooks - if (m_process_sp->GetModIDRef().IsLastResumeForUserExpression()) - return false; - if (m_stop_hooks.empty()) return false; @@ -2627,6 +2625,18 @@ bool Target::RunStopHooks() { if (!any_active_hooks) return false; + // <rdar://problem/12027563> make sure we check that we are not stopped + // because of us running a user expression since in that case we do not want + // to run the stop-hooks. Note, you can't just check whether the last stop + // was for a User Expression, because breakpoint commands get run before + // stop hooks, and one of them might have run an expression. You have + // to ensure you run the stop hooks once per natural stop. + uint32_t last_natural_stop = m_process_sp->GetModIDRef().GetLastNaturalStopID(); + if (last_natural_stop != 0 && m_latest_stop_hook_id == last_natural_stop) + return false; + + m_latest_stop_hook_id = last_natural_stop; + std::vector<ExecutionContext> exc_ctx_with_reasons; ThreadList &cur_threadlist = m_process_sp->GetThreadList(); @@ -2925,6 +2935,28 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) { launch_info.GetFlags().Set(eLaunchFlagDebug); + if (launch_info.IsScriptedProcess()) { + TargetPropertiesSP properties_sp = GetGlobalProperties(); + + if (!properties_sp) { + LLDB_LOGF(log, "Target::%s Couldn't fetch target global properties.", + __FUNCTION__); + return error; + } + + // Only copy scripted process launch options. + ProcessLaunchInfo &default_launch_info = + const_cast<ProcessLaunchInfo &>(properties_sp->GetProcessLaunchInfo()); + + default_launch_info.SetProcessPluginName("ScriptedProcess"); + default_launch_info.SetScriptedProcessClassName( + launch_info.GetScriptedProcessClassName()); + default_launch_info.SetScriptedProcessDictionarySP( + launch_info.GetScriptedProcessDictionarySP()); + + SetProcessLaunchInfo(launch_info); + } + // Get the value of synchronous execution here. If you wait till after you // have started to run, then you could have hit a breakpoint, whose command // might switch the value, and then you'll pick up that incorrect value. @@ -2950,7 +2982,7 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) { // If we're not already connected to the process, and if we have a platform // that can launch a process for debugging, go ahead and do that here. if (state != eStateConnected && platform_sp && - platform_sp->CanDebugProcess()) { + platform_sp->CanDebugProcess() && !launch_info.IsScriptedProcess()) { LLDB_LOGF(log, "Target::%s asking the platform to debug the process", __FUNCTION__); @@ -3053,7 +3085,38 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) { void Target::SetTrace(const TraceSP &trace_sp) { m_trace_sp = trace_sp; } -const TraceSP &Target::GetTrace() { return m_trace_sp; } +TraceSP Target::GetTrace() { return m_trace_sp; } + +llvm::Expected<TraceSP> Target::CreateTrace() { + if (!m_process_sp) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "A process is required for tracing"); + if (m_trace_sp) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "A trace already exists for the target"); + + llvm::Expected<TraceSupportedResponse> trace_type = + m_process_sp->TraceSupported(); + if (!trace_type) + return llvm::createStringError( + llvm::inconvertibleErrorCode(), "Tracing is not supported. %s", + llvm::toString(trace_type.takeError()).c_str()); + if (llvm::Expected<TraceSP> trace_sp = + Trace::FindPluginForLiveProcess(trace_type->name, *m_process_sp)) + m_trace_sp = *trace_sp; + else + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Couldn't create a Trace object for the process. %s", + llvm::toString(trace_sp.takeError()).c_str()); + return m_trace_sp; +} + +llvm::Expected<TraceSP> Target::GetTraceOrCreate() { + if (m_trace_sp) + return m_trace_sp; + return CreateTrace(); +} Status Target::Attach(ProcessAttachInfo &attach_info, Stream *stream) { auto state = eStateInvalid; @@ -3349,7 +3412,7 @@ Target::StopHookCommandLine::HandleStop(ExecutionContext &exc_ctx, // Force Async: bool old_async = debugger.GetAsyncExecution(); debugger.SetAsyncExecution(true); - debugger.GetCommandInterpreter().HandleCommands(GetCommands(), &exc_ctx, + debugger.GetCommandInterpreter().HandleCommands(GetCommands(), exc_ctx, options, result); debugger.SetAsyncExecution(old_async); lldb::ReturnStatus status = result.GetStatus(); @@ -3615,15 +3678,10 @@ enum { ePropertyExperimental, }; -class TargetOptionValueProperties : public OptionValueProperties { +class TargetOptionValueProperties + : public Cloneable<TargetOptionValueProperties, OptionValueProperties> { public: - TargetOptionValueProperties(ConstString name) : OptionValueProperties(name) {} - - // This constructor is used when creating TargetOptionValueProperties when it - // is part of a new lldb_private::Target instance. It will copy all current - // global property values as needed - TargetOptionValueProperties(const TargetPropertiesSP &target_properties_sp) - : OptionValueProperties(*target_properties_sp->GetValueProperties()) {} + TargetOptionValueProperties(ConstString name) : Cloneable(name) {} const Property *GetPropertyAtIndex(const ExecutionContext *exe_ctx, bool will_modify, @@ -3654,11 +3712,12 @@ enum { #include "TargetPropertiesEnum.inc" }; -class TargetExperimentalOptionValueProperties : public OptionValueProperties { +class TargetExperimentalOptionValueProperties + : public Cloneable<TargetExperimentalOptionValueProperties, + OptionValueProperties> { public: TargetExperimentalOptionValueProperties() - : OptionValueProperties( - ConstString(Properties::GetExperimentalSettingsName())) {} + : Cloneable(ConstString(Properties::GetExperimentalSettingsName())) {} }; TargetExperimentalProperties::TargetExperimentalProperties() @@ -3671,8 +3730,8 @@ TargetExperimentalProperties::TargetExperimentalProperties() TargetProperties::TargetProperties(Target *target) : Properties(), m_launch_info(), m_target(target) { if (target) { - m_collection_sp = std::make_shared<TargetOptionValueProperties>( - Target::GetGlobalProperties()); + m_collection_sp = + OptionValueProperties::CreateLocalCopy(*Target::GetGlobalProperties()); // Set callbacks to update launch_info whenever "settins set" updated any // of these properties @@ -4200,8 +4259,7 @@ void TargetProperties::SetNonStopModeEnabled(bool b) { m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); } -const ProcessLaunchInfo &TargetProperties::GetProcessLaunchInfo() { - m_launch_info.SetArg0(GetArg0()); // FIXME: Arg0 callback doesn't work +const ProcessLaunchInfo &TargetProperties::GetProcessLaunchInfo() const { return m_launch_info; } @@ -4307,6 +4365,17 @@ void TargetProperties::DisableSTDIOValueChangedCallback() { m_launch_info.GetFlags().Clear(lldb::eLaunchFlagDisableSTDIO); } +bool TargetProperties::GetDebugUtilityExpression() const { + const uint32_t idx = ePropertyDebugUtilityExpression; + return m_collection_sp->GetPropertyAtIndexAsBoolean( + nullptr, idx, g_target_properties[idx].default_uint_value != 0); +} + +void TargetProperties::SetDebugUtilityExpression(bool debug) { + const uint32_t idx = ePropertyDebugUtilityExpression; + m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, debug); +} + // Target::TargetEventData Target::TargetEventData::TargetEventData(const lldb::TargetSP &target_sp) diff --git a/contrib/llvm-project/lldb/source/Target/TargetList.cpp b/contrib/llvm-project/lldb/source/Target/TargetList.cpp index 1e5856dd0b22..595799cfc92a 100644 --- a/contrib/llvm-project/lldb/source/Target/TargetList.cpp +++ b/contrib/llvm-project/lldb/source/Target/TargetList.cpp @@ -48,6 +48,7 @@ Status TargetList::CreateTarget(Debugger &debugger, LoadDependentFiles load_dependent_files, const OptionGroupPlatform *platform_options, TargetSP &target_sp) { + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); auto result = TargetList::CreateTargetInternal( debugger, user_exe_path, triple_str, load_dependent_files, platform_options, target_sp); @@ -62,6 +63,7 @@ Status TargetList::CreateTarget(Debugger &debugger, const ArchSpec &specified_arch, LoadDependentFiles load_dependent_files, PlatformSP &platform_sp, TargetSP &target_sp) { + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); auto result = TargetList::CreateTargetInternal( debugger, user_exe_path, specified_arch, load_dependent_files, platform_sp, target_sp); diff --git a/contrib/llvm-project/lldb/source/Target/TargetProperties.td b/contrib/llvm-project/lldb/source/Target/TargetProperties.td index 2d6a4358082a..8f627ad0f1a8 100644 --- a/contrib/llvm-project/lldb/source/Target/TargetProperties.td +++ b/contrib/llvm-project/lldb/source/Target/TargetProperties.td @@ -172,6 +172,9 @@ let Definition = "target" in { def AutoInstallMainExecutable: Property<"auto-install-main-executable", "Boolean">, DefaultTrue, Desc<"Always install the main executable when connected to a remote platform.">; + def DebugUtilityExpression: Property<"debug-utility-expression", "Boolean">, + DefaultFalse, + Desc<"Enable debugging of LLDB-internal utility expressions.">; } let Definition = "process_experimental" in { @@ -203,6 +206,10 @@ let Definition = "process" in { Global, DefaultFalse, Desc<"If true, stop when a shared library is loaded or unloaded.">; + def DisableLangRuntimeUnwindPlans: Property<"disable-language-runtime-unwindplans", "Boolean">, + Global, + DefaultFalse, + Desc<"If true, LanguageRuntime plugins' UnwindPlans will not be used when backtracing.">; def DetachKeepsStopped: Property<"detach-keeps-stopped", "Boolean">, Global, DefaultFalse, @@ -223,9 +230,15 @@ let Definition = "process" in { def UtilityExpressionTimeout: Property<"utility-expression-timeout", "UInt64">, DefaultUnsignedValue<15>, Desc<"The time in seconds to wait for LLDB-internal utility expressions.">; + def InterruptTimeout: Property<"interrupt-timeout", "UInt64">, + DefaultUnsignedValue<20>, + Desc<"The time in seconds to wait for an interrupt succeed in stopping the target.">; def SteppingRunsAllThreads: Property<"run-all-threads", "Boolean">, DefaultFalse, Desc<"If true, stepping operations will run all threads. This is equivalent to setting the run-mode option to 'all-threads'.">; + def VirtualAddressableBits: Property<"virtual-addressable-bits", "UInt64">, + DefaultUnsignedValue<0>, + Desc<"The number of bits used for addressing. If the value is 39, then bits 0..38 are used for addressing. The default value of 0 means unspecified.">; } let Definition = "platform" in { diff --git a/contrib/llvm-project/lldb/source/Target/Thread.cpp b/contrib/llvm-project/lldb/source/Target/Thread.cpp index 049e458d8b19..b423f1b5f1fe 100644 --- a/contrib/llvm-project/lldb/source/Target/Thread.cpp +++ b/contrib/llvm-project/lldb/source/Target/Thread.cpp @@ -71,16 +71,10 @@ enum { #include "TargetPropertiesEnum.inc" }; -class ThreadOptionValueProperties : public OptionValueProperties { +class ThreadOptionValueProperties + : public Cloneable<ThreadOptionValueProperties, OptionValueProperties> { public: - ThreadOptionValueProperties(ConstString name) - : OptionValueProperties(name) {} - - // This constructor is used when creating ThreadOptionValueProperties when it - // is part of a new lldb_private::Thread instance. It will copy all current - // global property values as needed - ThreadOptionValueProperties(ThreadProperties *global_properties) - : OptionValueProperties(*global_properties->GetValueProperties()) {} + ThreadOptionValueProperties(ConstString name) : Cloneable(name) {} const Property *GetPropertyAtIndex(const ExecutionContext *exe_ctx, bool will_modify, @@ -108,8 +102,8 @@ ThreadProperties::ThreadProperties(bool is_global) : Properties() { std::make_shared<ThreadOptionValueProperties>(ConstString("thread")); m_collection_sp->Initialize(g_thread_properties); } else - m_collection_sp = std::make_shared<ThreadOptionValueProperties>( - Thread::GetGlobalProperties().get()); + m_collection_sp = + OptionValueProperties::CreateLocalCopy(*Thread::GetGlobalProperties()); } ThreadProperties::~ThreadProperties() = default; @@ -530,7 +524,7 @@ bool Thread::RestoreRegisterStateFromCheckpoint( return false; } -bool Thread::RestoreThreadStateFromCheckpoint( +void Thread::RestoreThreadStateFromCheckpoint( ThreadStateCheckpoint &saved_state) { if (saved_state.stop_info_sp) saved_state.stop_info_sp->MakeStopInfoValid(); @@ -539,7 +533,6 @@ bool Thread::RestoreThreadStateFromCheckpoint( saved_state.current_inlined_depth); GetPlans().RestoreCompletedPlanCheckpoint( saved_state.m_completed_plan_checkpoint); - return true; } StateType Thread::GetState() const { @@ -830,6 +823,8 @@ bool Thread::ShouldStop(Event *event_ptr) { ThreadPlan *plan_ptr = current_plan; while ((plan_ptr = GetPreviousPlan(plan_ptr)) != nullptr) { if (plan_ptr->PlanExplainsStop(event_ptr)) { + LLDB_LOGF(log, "Plan %s explains stop.", plan_ptr->GetName()); + should_stop = plan_ptr->ShouldStop(event_ptr); // plan_ptr explains the stop, next check whether plan_ptr is done, @@ -861,10 +856,7 @@ bool Thread::ShouldStop(Event *event_ptr) { } if (!done_processing_current_plan) { - bool over_ride_stop = current_plan->ShouldAutoContinue(event_ptr); - - LLDB_LOGF(log, "Plan %s explains stop, auto-continue %i.", - current_plan->GetName(), over_ride_stop); + bool override_stop = false; // We're starting from the base plan, so just let it decide; if (current_plan->IsBasePlan()) { @@ -885,20 +877,24 @@ bool Thread::ShouldStop(Event *event_ptr) { if (should_stop) current_plan->WillStop(); - // If a Master Plan wants to stop, and wants to stick on the stack, - // we let it. Otherwise, see if the plan's parent wants to stop. + if (current_plan->ShouldAutoContinue(event_ptr)) { + override_stop = true; + LLDB_LOGF(log, "Plan %s auto-continue: true.", + current_plan->GetName()); + } + + // If a Master Plan wants to stop, we let it. Otherwise, see if the + // plan's parent wants to stop. + PopPlan(); if (should_stop && current_plan->IsMasterPlan() && !current_plan->OkayToDiscard()) { - PopPlan(); break; - } else { - PopPlan(); + } - current_plan = GetCurrentPlan(); - if (current_plan == nullptr) { - break; - } + current_plan = GetCurrentPlan(); + if (current_plan == nullptr) { + break; } } else { break; @@ -906,7 +902,7 @@ bool Thread::ShouldStop(Event *event_ptr) { } } - if (over_ride_stop) + if (override_stop) should_stop = false; } @@ -1181,14 +1177,6 @@ Status Thread::QueueThreadPlan(ThreadPlanSP &thread_plan_sp, return status; } -void Thread::EnableTracer(bool value, bool single_stepping) { - GetPlans().EnableTracer(value, single_stepping); -} - -void Thread::SetTracer(lldb::ThreadPlanTracerSP &tracer_sp) { - GetPlans().SetTracer(tracer_sp); -} - bool Thread::DiscardUserThreadPlansUpToIndex(uint32_t plan_index) { // Count the user thread plans from the back end to get the number of the one // we want to discard: @@ -1241,7 +1229,7 @@ Status Thread::UnwindInnermostExpression() { return error; } -ThreadPlanSP Thread::QueueFundamentalPlan(bool abort_other_plans) { +ThreadPlanSP Thread::QueueBasePlan(bool abort_other_plans) { ThreadPlanSP thread_plan_sp(new ThreadPlanBase(*this)); QueueThreadPlan(thread_plan_sp, abort_other_plans); return thread_plan_sp; @@ -1289,16 +1277,10 @@ ThreadPlanSP Thread::QueueThreadPlanForStepInRange( lldb::RunMode stop_other_threads, Status &status, LazyBool step_in_avoids_code_without_debug_info, LazyBool step_out_avoids_code_without_debug_info) { - ThreadPlanSP thread_plan_sp( - new ThreadPlanStepInRange(*this, range, addr_context, stop_other_threads, - step_in_avoids_code_without_debug_info, - step_out_avoids_code_without_debug_info)); - ThreadPlanStepInRange *plan = - static_cast<ThreadPlanStepInRange *>(thread_plan_sp.get()); - - if (step_in_target) - plan->SetStepInTarget(step_in_target); - + ThreadPlanSP thread_plan_sp(new ThreadPlanStepInRange( + *this, range, addr_context, step_in_target, stop_other_threads, + step_in_avoids_code_without_debug_info, + step_out_avoids_code_without_debug_info)); status = QueueThreadPlan(thread_plan_sp, abort_other_plans); return thread_plan_sp; } @@ -1321,11 +1303,12 @@ ThreadPlanSP Thread::QueueThreadPlanForStepInRange( ThreadPlanSP Thread::QueueThreadPlanForStepOut( bool abort_other_plans, SymbolContext *addr_context, bool first_insn, - bool stop_other_threads, Vote stop_vote, Vote run_vote, uint32_t frame_idx, - Status &status, LazyBool step_out_avoids_code_without_debug_info) { + bool stop_other_threads, Vote report_stop_vote, Vote report_run_vote, + uint32_t frame_idx, Status &status, + LazyBool step_out_avoids_code_without_debug_info) { ThreadPlanSP thread_plan_sp(new ThreadPlanStepOut( - *this, addr_context, first_insn, stop_other_threads, stop_vote, run_vote, - frame_idx, step_out_avoids_code_without_debug_info)); + *this, addr_context, first_insn, stop_other_threads, report_stop_vote, + report_run_vote, frame_idx, step_out_avoids_code_without_debug_info)); status = QueueThreadPlan(thread_plan_sp, abort_other_plans); return thread_plan_sp; @@ -1333,13 +1316,14 @@ ThreadPlanSP Thread::QueueThreadPlanForStepOut( ThreadPlanSP Thread::QueueThreadPlanForStepOutNoShouldStop( bool abort_other_plans, SymbolContext *addr_context, bool first_insn, - bool stop_other_threads, Vote stop_vote, Vote run_vote, uint32_t frame_idx, - Status &status, bool continue_to_next_branch) { + bool stop_other_threads, Vote report_stop_vote, Vote report_run_vote, + uint32_t frame_idx, Status &status, bool continue_to_next_branch) { const bool calculate_return_value = false; // No need to calculate the return value here. ThreadPlanSP thread_plan_sp(new ThreadPlanStepOut( - *this, addr_context, first_insn, stop_other_threads, stop_vote, run_vote, - frame_idx, eLazyBoolNo, continue_to_next_branch, calculate_return_value)); + *this, addr_context, first_insn, stop_other_threads, report_stop_vote, + report_run_vote, frame_idx, eLazyBoolNo, continue_to_next_branch, + calculate_return_value)); ThreadPlanStepOut *new_plan = static_cast<ThreadPlanStepOut *>(thread_plan_sp.get()); @@ -1695,12 +1679,20 @@ std::string Thread::StopReasonAsString(lldb::StopReason reason) { return "exception"; case eStopReasonExec: return "exec"; + case eStopReasonFork: + return "fork"; + case eStopReasonVFork: + return "vfork"; + case eStopReasonVForkDone: + return "vfork done"; case eStopReasonPlanComplete: return "plan complete"; case eStopReasonThreadExiting: return "thread exiting"; case eStopReasonInstrumentation: return "instrumentation break"; + case eStopReasonProcessorTrace: + return "processor trace"; } return "StopReason = " + std::to_string(reason); diff --git a/contrib/llvm-project/lldb/source/Target/ThreadCollection.cpp b/contrib/llvm-project/lldb/source/Target/ThreadCollection.cpp index 05b041c20dd0..8c2309795a4c 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadCollection.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadCollection.cpp @@ -5,7 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -#include <stdlib.h> +#include <cstdlib> #include <algorithm> #include <mutex> diff --git a/contrib/llvm-project/lldb/source/Target/ThreadList.cpp b/contrib/llvm-project/lldb/source/Target/ThreadList.cpp index 032dcc9e5fbd..df2cc8ef6328 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadList.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadList.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include <stdlib.h> +#include <cstdlib> #include <algorithm> diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlan.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlan.cpp index c7a00e2450c8..6b55f3912d11 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlan.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlan.cpp @@ -20,9 +20,9 @@ using namespace lldb_private; // ThreadPlan constructor ThreadPlan::ThreadPlan(ThreadPlanKind kind, const char *name, Thread &thread, - Vote stop_vote, Vote run_vote) + Vote report_stop_vote, Vote report_run_vote) : m_process(*thread.GetProcess().get()), m_tid(thread.GetID()), - m_stop_vote(stop_vote), m_run_vote(run_vote), + m_report_stop_vote(report_stop_vote), m_report_run_vote(report_run_vote), m_takes_iteration_count(false), m_could_not_resolve_hw_bp(false), m_thread(&thread), m_kind(kind), m_name(name), m_plan_complete_mutex(), m_cached_plan_explains_stop(eLazyBoolCalculate), m_plan_complete(false), @@ -50,7 +50,7 @@ Thread &ThreadPlan::GetThread() { bool ThreadPlan::PlanExplainsStop(Event *event_ptr) { if (m_cached_plan_explains_stop == eLazyBoolCalculate) { bool actual_value = DoPlanExplainsStop(event_ptr); - m_cached_plan_explains_stop = actual_value ? eLazyBoolYes : eLazyBoolNo; + CachePlanExplainsStop(actual_value); return actual_value; } else { return m_cached_plan_explains_stop == eLazyBoolYes; @@ -78,7 +78,7 @@ bool ThreadPlan::MischiefManaged() { Vote ThreadPlan::ShouldReportStop(Event *event_ptr) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); - if (m_stop_vote == eVoteNoOpinion) { + if (m_report_stop_vote == eVoteNoOpinion) { ThreadPlan *prev_plan = GetPreviousPlan(); if (prev_plan) { Vote prev_vote = prev_plan->ShouldReportStop(event_ptr); @@ -86,17 +86,17 @@ Vote ThreadPlan::ShouldReportStop(Event *event_ptr) { return prev_vote; } } - LLDB_LOG(log, "Returning vote: {0}", m_stop_vote); - return m_stop_vote; + LLDB_LOG(log, "Returning vote: {0}", m_report_stop_vote); + return m_report_stop_vote; } Vote ThreadPlan::ShouldReportRun(Event *event_ptr) { - if (m_run_vote == eVoteNoOpinion) { + if (m_report_run_vote == eVoteNoOpinion) { ThreadPlan *prev_plan = GetPreviousPlan(); if (prev_plan) return prev_plan->ShouldReportRun(event_ptr); } - return m_run_vote; + return m_report_run_vote; } void ThreadPlan::ClearThreadCache() { m_thread = nullptr; } @@ -156,8 +156,7 @@ bool ThreadPlan::OkayToDiscard() { } lldb::StateType ThreadPlan::RunState() { - if (m_tracer_sp && m_tracer_sp->TracingEnabled() && - m_tracer_sp->SingleStepEnabled()) + if (m_tracer_sp && m_tracer_sp->TracingEnabled()) return eStateStepping; else return GetPlanRunState(); diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanBase.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanBase.cpp index 650393d678e8..c6c4d97c1655 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanBase.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanBase.cpp @@ -43,7 +43,7 @@ ThreadPlanBase::ThreadPlanBase(Thread &thread) SetIsMasterPlan(true); } -ThreadPlanBase::~ThreadPlanBase() {} +ThreadPlanBase::~ThreadPlanBase() = default; void ThreadPlanBase::GetDescription(Stream *s, lldb::DescriptionLevel level) { s->Printf("Base thread plan."); @@ -70,8 +70,8 @@ Vote ThreadPlanBase::ShouldReportStop(Event *event_ptr) { } bool ThreadPlanBase::ShouldStop(Event *event_ptr) { - m_stop_vote = eVoteYes; - m_run_vote = eVoteYes; + m_report_stop_vote = eVoteYes; + m_report_run_vote = eVoteYes; Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); @@ -82,8 +82,8 @@ bool ThreadPlanBase::ShouldStop(Event *event_ptr) { case eStopReasonInvalid: case eStopReasonNone: // This - m_run_vote = eVoteNoOpinion; - m_stop_vote = eVoteNo; + m_report_run_vote = eVoteNoOpinion; + m_report_stop_vote = eVoteNo; return false; case eStopReasonBreakpoint: @@ -106,11 +106,11 @@ bool ThreadPlanBase::ShouldStop(Event *event_ptr) { // with "restarted" so the UI will know to wait and expect the consequent // "running". if (stop_info_sp->ShouldNotify(event_ptr)) { - m_stop_vote = eVoteYes; - m_run_vote = eVoteYes; + m_report_stop_vote = eVoteYes; + m_report_run_vote = eVoteYes; } else { - m_stop_vote = eVoteNo; - m_run_vote = eVoteNo; + m_report_stop_vote = eVoteNo; + m_report_run_vote = eVoteNo; } return false; @@ -156,9 +156,9 @@ bool ThreadPlanBase::ShouldStop(Event *event_ptr) { // We're not going to stop, but while we are here, let's figure out // whether to report this. if (stop_info_sp->ShouldNotify(event_ptr)) - m_stop_vote = eVoteYes; + m_report_stop_vote = eVoteYes; else - m_stop_vote = eVoteNo; + m_report_stop_vote = eVoteNo; } return false; @@ -167,8 +167,8 @@ bool ThreadPlanBase::ShouldStop(Event *event_ptr) { } } else { - m_run_vote = eVoteNoOpinion; - m_stop_vote = eVoteNo; + m_report_run_vote = eVoteNoOpinion; + m_report_stop_vote = eVoteNo; } // If there's no explicit reason to stop, then we will continue. @@ -185,8 +185,8 @@ bool ThreadPlanBase::DoWillResume(lldb::StateType resume_state, bool current_plan) { // Reset these to the default values so we don't set them wrong, then not get // asked for a while, then return the wrong answer. - m_run_vote = eVoteNoOpinion; - m_stop_vote = eVoteNo; + m_report_run_vote = eVoteNoOpinion; + m_report_stop_vote = eVoteNo; return true; } diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanCallFunction.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanCallFunction.cpp index f525173f8a51..3699a507d058 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanCallFunction.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanCallFunction.cpp @@ -454,8 +454,8 @@ void ThreadPlanCallFunction::SetStopOthers(bool new_value) { m_subplan_sp->SetStopOthers(new_value); } -bool ThreadPlanCallFunction::RestoreThreadState() { - return GetThread().RestoreThreadStateFromCheckpoint(m_stored_thread_state); +void ThreadPlanCallFunction::RestoreThreadState() { + GetThread().RestoreThreadStateFromCheckpoint(m_stored_thread_state); } void ThreadPlanCallFunction::SetReturnValue() { diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanCallUserExpression.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanCallUserExpression.cpp index 00b01c76d900..9dddd850b6ab 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanCallUserExpression.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanCallUserExpression.cpp @@ -43,7 +43,7 @@ ThreadPlanCallUserExpression::ThreadPlanCallUserExpression( SetOkayToDiscard(false); } -ThreadPlanCallUserExpression::~ThreadPlanCallUserExpression() {} +ThreadPlanCallUserExpression::~ThreadPlanCallUserExpression() = default; void ThreadPlanCallUserExpression::GetDescription( Stream *s, lldb::DescriptionLevel level) { diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanStack.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanStack.cpp index ad37669c31fd..d25602d25b91 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanStack.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanStack.cpp @@ -39,6 +39,7 @@ ThreadPlanStack::ThreadPlanStack(const Thread &thread, bool make_null) { void ThreadPlanStack::DumpThreadPlans(Stream &s, lldb::DescriptionLevel desc_level, bool include_internal) const { + std::lock_guard<std::recursive_mutex> guard(m_stack_mutex); s.IndentMore(); PrintOneStack(s, "Active plan stack", m_plans, desc_level, include_internal); PrintOneStack(s, "Completed plan stack", m_completed_plans, desc_level, @@ -52,6 +53,7 @@ void ThreadPlanStack::PrintOneStack(Stream &s, llvm::StringRef stack_name, const PlanStack &stack, lldb::DescriptionLevel desc_level, bool include_internal) const { + std::lock_guard<std::recursive_mutex> guard(m_stack_mutex); // If the stack is empty, just exit: if (stack.empty()) return; @@ -80,6 +82,7 @@ void ThreadPlanStack::PrintOneStack(Stream &s, llvm::StringRef stack_name, } size_t ThreadPlanStack::CheckpointCompletedPlans() { + std::lock_guard<std::recursive_mutex> guard(m_stack_mutex); m_completed_plan_checkpoint++; m_completed_plan_store.insert( std::make_pair(m_completed_plan_checkpoint, m_completed_plans)); @@ -87,6 +90,7 @@ size_t ThreadPlanStack::CheckpointCompletedPlans() { } void ThreadPlanStack::RestoreCompletedPlanCheckpoint(size_t checkpoint) { + std::lock_guard<std::recursive_mutex> guard(m_stack_mutex); auto result = m_completed_plan_store.find(checkpoint); assert(result != m_completed_plan_store.end() && "Asked for a checkpoint that didn't exist"); @@ -95,11 +99,13 @@ void ThreadPlanStack::RestoreCompletedPlanCheckpoint(size_t checkpoint) { } void ThreadPlanStack::DiscardCompletedPlanCheckpoint(size_t checkpoint) { + std::lock_guard<std::recursive_mutex> guard(m_stack_mutex); m_completed_plan_store.erase(checkpoint); } void ThreadPlanStack::ThreadDestroyed(Thread *thread) { // Tell the plan stacks that this thread is going away: + std::lock_guard<std::recursive_mutex> guard(m_stack_mutex); for (ThreadPlanSP plan : m_plans) plan->ThreadDestroyed(); @@ -124,24 +130,11 @@ void ThreadPlanStack::ThreadDestroyed(Thread *thread) { } } -void ThreadPlanStack::EnableTracer(bool value, bool single_stepping) { - for (ThreadPlanSP plan : m_plans) { - if (plan->GetThreadPlanTracer()) { - plan->GetThreadPlanTracer()->EnableTracing(value); - plan->GetThreadPlanTracer()->EnableSingleStep(single_stepping); - } - } -} - -void ThreadPlanStack::SetTracer(lldb::ThreadPlanTracerSP &tracer_sp) { - for (ThreadPlanSP plan : m_plans) - plan->SetThreadPlanTracer(tracer_sp); -} - void ThreadPlanStack::PushPlan(lldb::ThreadPlanSP new_plan_sp) { // If the thread plan doesn't already have a tracer, give it its parent's // tracer: // The first plan has to be a base plan: + std::lock_guard<std::recursive_mutex> guard(m_stack_mutex); assert((m_plans.size() > 0 || new_plan_sp->IsBasePlan()) && "Zeroth plan must be a base plan"); @@ -154,6 +147,7 @@ void ThreadPlanStack::PushPlan(lldb::ThreadPlanSP new_plan_sp) { } lldb::ThreadPlanSP ThreadPlanStack::PopPlan() { + std::lock_guard<std::recursive_mutex> guard(m_stack_mutex); assert(m_plans.size() > 1 && "Can't pop the base thread plan"); lldb::ThreadPlanSP plan_sp = std::move(m_plans.back()); @@ -164,6 +158,7 @@ lldb::ThreadPlanSP ThreadPlanStack::PopPlan() { } lldb::ThreadPlanSP ThreadPlanStack::DiscardPlan() { + std::lock_guard<std::recursive_mutex> guard(m_stack_mutex); assert(m_plans.size() > 1 && "Can't discard the base thread plan"); lldb::ThreadPlanSP plan_sp = std::move(m_plans.back()); @@ -176,6 +171,7 @@ lldb::ThreadPlanSP ThreadPlanStack::DiscardPlan() { // If the input plan is nullptr, discard all plans. Otherwise make sure this // plan is in the stack, and if so discard up to and including it. void ThreadPlanStack::DiscardPlansUpToPlan(ThreadPlan *up_to_plan_ptr) { + std::lock_guard<std::recursive_mutex> guard(m_stack_mutex); int stack_size = m_plans.size(); if (up_to_plan_ptr == nullptr) { @@ -203,6 +199,7 @@ void ThreadPlanStack::DiscardPlansUpToPlan(ThreadPlan *up_to_plan_ptr) { } void ThreadPlanStack::DiscardAllPlans() { + std::lock_guard<std::recursive_mutex> guard(m_stack_mutex); int stack_size = m_plans.size(); for (int i = stack_size - 1; i > 0; i--) { DiscardPlan(); @@ -211,6 +208,7 @@ void ThreadPlanStack::DiscardAllPlans() { } void ThreadPlanStack::DiscardConsultingMasterPlans() { + std::lock_guard<std::recursive_mutex> guard(m_stack_mutex); while (true) { int master_plan_idx; bool discard = true; @@ -244,11 +242,13 @@ void ThreadPlanStack::DiscardConsultingMasterPlans() { } lldb::ThreadPlanSP ThreadPlanStack::GetCurrentPlan() const { + std::lock_guard<std::recursive_mutex> guard(m_stack_mutex); assert(m_plans.size() != 0 && "There will always be a base plan."); return m_plans.back(); } lldb::ThreadPlanSP ThreadPlanStack::GetCompletedPlan(bool skip_private) const { + std::lock_guard<std::recursive_mutex> guard(m_stack_mutex); if (m_completed_plans.empty()) return {}; @@ -266,6 +266,7 @@ lldb::ThreadPlanSP ThreadPlanStack::GetCompletedPlan(bool skip_private) const { lldb::ThreadPlanSP ThreadPlanStack::GetPlanByIndex(uint32_t plan_idx, bool skip_private) const { + std::lock_guard<std::recursive_mutex> guard(m_stack_mutex); uint32_t idx = 0; for (lldb::ThreadPlanSP plan_sp : m_plans) { @@ -279,6 +280,7 @@ lldb::ThreadPlanSP ThreadPlanStack::GetPlanByIndex(uint32_t plan_idx, } lldb::ValueObjectSP ThreadPlanStack::GetReturnValueObject() const { + std::lock_guard<std::recursive_mutex> guard(m_stack_mutex); if (m_completed_plans.empty()) return {}; @@ -292,6 +294,7 @@ lldb::ValueObjectSP ThreadPlanStack::GetReturnValueObject() const { } lldb::ExpressionVariableSP ThreadPlanStack::GetExpressionVariable() const { + std::lock_guard<std::recursive_mutex> guard(m_stack_mutex); if (m_completed_plans.empty()) return {}; @@ -304,19 +307,23 @@ lldb::ExpressionVariableSP ThreadPlanStack::GetExpressionVariable() const { return {}; } bool ThreadPlanStack::AnyPlans() const { + std::lock_guard<std::recursive_mutex> guard(m_stack_mutex); // There is always a base plan... return m_plans.size() > 1; } bool ThreadPlanStack::AnyCompletedPlans() const { + std::lock_guard<std::recursive_mutex> guard(m_stack_mutex); return !m_completed_plans.empty(); } bool ThreadPlanStack::AnyDiscardedPlans() const { + std::lock_guard<std::recursive_mutex> guard(m_stack_mutex); return !m_discarded_plans.empty(); } bool ThreadPlanStack::IsPlanDone(ThreadPlan *in_plan) const { + std::lock_guard<std::recursive_mutex> guard(m_stack_mutex); for (auto plan : m_completed_plans) { if (plan.get() == in_plan) return true; @@ -325,6 +332,7 @@ bool ThreadPlanStack::IsPlanDone(ThreadPlan *in_plan) const { } bool ThreadPlanStack::WasPlanDiscarded(ThreadPlan *in_plan) const { + std::lock_guard<std::recursive_mutex> guard(m_stack_mutex); for (auto plan : m_discarded_plans) { if (plan.get() == in_plan) return true; @@ -333,6 +341,7 @@ bool ThreadPlanStack::WasPlanDiscarded(ThreadPlan *in_plan) const { } ThreadPlan *ThreadPlanStack::GetPreviousPlan(ThreadPlan *current_plan) const { + std::lock_guard<std::recursive_mutex> guard(m_stack_mutex); if (current_plan == nullptr) return nullptr; @@ -360,6 +369,7 @@ ThreadPlan *ThreadPlanStack::GetPreviousPlan(ThreadPlan *current_plan) const { } ThreadPlan *ThreadPlanStack::GetInnermostExpression() const { + std::lock_guard<std::recursive_mutex> guard(m_stack_mutex); int stack_size = m_plans.size(); for (int i = stack_size - 1; i > 0; i--) { @@ -370,11 +380,13 @@ ThreadPlan *ThreadPlanStack::GetInnermostExpression() const { } void ThreadPlanStack::ClearThreadCache() { + std::lock_guard<std::recursive_mutex> guard(m_stack_mutex); for (lldb::ThreadPlanSP thread_plan_sp : m_plans) thread_plan_sp->ClearThreadCache(); } void ThreadPlanStack::WillResume() { + std::lock_guard<std::recursive_mutex> guard(m_stack_mutex); m_completed_plans.clear(); m_discarded_plans.clear(); } @@ -389,7 +401,7 @@ void ThreadPlanStackMap::Update(ThreadList ¤t_threads, lldb::tid_t cur_tid = thread->GetID(); if (!Find(cur_tid)) { AddThread(*thread.get()); - thread->QueueFundamentalPlan(true); + thread->QueueBasePlan(true); } } } @@ -402,7 +414,7 @@ void ThreadPlanStackMap::Update(ThreadList ¤t_threads, std::vector<lldb::tid_t> missing_threads; // If we are going to delete plans from the plan stack, // then scan for absent TID's: - for (auto thread_plans : m_plans_list) { + for (auto &thread_plans : m_plans_list) { lldb::tid_t cur_tid = thread_plans.first; ThreadSP thread_sp = current_threads.FindThreadByID(cur_tid); if (!thread_sp) @@ -417,7 +429,7 @@ void ThreadPlanStackMap::DumpPlans(Stream &strm, lldb::DescriptionLevel desc_level, bool internal, bool condense_if_trivial, bool skip_unreported) { - for (auto elem : m_plans_list) { + for (auto &elem : m_plans_list) { lldb::tid_t tid = elem.first; uint32_t index_id = 0; ThreadSP thread_sp = m_process.GetThreadList().FindThreadByID(tid); diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepInRange.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepInRange.cpp index a03bd93ac638..69b4b918d467 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepInRange.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepInRange.cpp @@ -33,14 +33,14 @@ uint32_t ThreadPlanStepInRange::s_default_flag_values = ThreadPlanStepInRange::ThreadPlanStepInRange( Thread &thread, const AddressRange &range, - const SymbolContext &addr_context, lldb::RunMode stop_others, - LazyBool step_in_avoids_code_without_debug_info, + const SymbolContext &addr_context, const char *step_into_target, + lldb::RunMode stop_others, LazyBool step_in_avoids_code_without_debug_info, LazyBool step_out_avoids_code_without_debug_info) : ThreadPlanStepRange(ThreadPlan::eKindStepInRange, "Step Range stepping in", thread, range, addr_context, stop_others), ThreadPlanShouldStopHere(this), m_step_past_prologue(true), - m_virtual_step(false) { + m_virtual_step(false), m_step_into_target(step_into_target) { SetCallbacks(); SetFlagsToDefault(); SetupAvoidNoDebug(step_in_avoids_code_without_debug_info, @@ -291,11 +291,10 @@ bool ThreadPlanStepInRange::ShouldStop(Event *event_ptr) { } void ThreadPlanStepInRange::SetAvoidRegexp(const char *name) { - auto name_ref = llvm::StringRef::withNullAsEmpty(name); if (m_avoid_regexp_up) - *m_avoid_regexp_up = RegularExpression(name_ref); + *m_avoid_regexp_up = RegularExpression(name); else - m_avoid_regexp_up = std::make_unique<RegularExpression>(name_ref); + m_avoid_regexp_up = std::make_unique<RegularExpression>(name); } void ThreadPlanStepInRange::SetDefaultFlagValue(uint32_t new_value) { diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepInstruction.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepInstruction.cpp index c0da735c44b6..e34e41e8bce8 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepInstruction.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepInstruction.cpp @@ -23,10 +23,11 @@ using namespace lldb_private; ThreadPlanStepInstruction::ThreadPlanStepInstruction(Thread &thread, bool step_over, bool stop_other_threads, - Vote stop_vote, - Vote run_vote) + Vote report_stop_vote, + Vote report_run_vote) : ThreadPlan(ThreadPlan::eKindStepInstruction, - "Step over single instruction", thread, stop_vote, run_vote), + "Step over single instruction", thread, report_stop_vote, + report_run_vote), m_instruction_addr(0), m_stop_other_threads(stop_other_threads), m_step_over(step_over) { m_takes_iteration_count = true; diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepOut.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepOut.cpp index 9f0749c0fdb3..86ccac2ec499 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepOut.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepOut.cpp @@ -33,11 +33,11 @@ uint32_t ThreadPlanStepOut::s_default_flag_values = 0; // ThreadPlanStepOut: Step out of the current frame ThreadPlanStepOut::ThreadPlanStepOut( Thread &thread, SymbolContext *context, bool first_insn, bool stop_others, - Vote stop_vote, Vote run_vote, uint32_t frame_idx, + Vote report_stop_vote, Vote report_run_vote, uint32_t frame_idx, LazyBool step_out_avoids_code_without_debug_info, bool continue_to_next_branch, bool gather_return_value) - : ThreadPlan(ThreadPlan::eKindStepOut, "Step out", thread, stop_vote, - run_vote), + : ThreadPlan(ThreadPlan::eKindStepOut, "Step out", thread, report_stop_vote, + report_run_vote), ThreadPlanShouldStopHere(this), m_step_from_insn(LLDB_INVALID_ADDRESS), m_return_bp_id(LLDB_INVALID_BREAK_ID), m_return_addr(LLDB_INVALID_ADDRESS), m_stop_others(stop_others), diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp index f188d827faae..965a7b3a9960 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp @@ -36,7 +36,7 @@ ThreadPlanStepOverBreakpoint::ThreadPlanStepOverBreakpoint(Thread &thread) m_breakpoint_addr); } -ThreadPlanStepOverBreakpoint::~ThreadPlanStepOverBreakpoint() {} +ThreadPlanStepOverBreakpoint::~ThreadPlanStepOverBreakpoint() = default; void ThreadPlanStepOverBreakpoint::GetDescription( Stream *s, lldb::DescriptionLevel level) { @@ -49,16 +49,6 @@ bool ThreadPlanStepOverBreakpoint::ValidatePlan(Stream *error) { return true; } bool ThreadPlanStepOverBreakpoint::DoPlanExplainsStop(Event *event_ptr) { StopInfoSP stop_info_sp = GetPrivateStopInfo(); if (stop_info_sp) { - // It's a little surprising that we stop here for a breakpoint hit. - // However, when you single step ONTO a breakpoint we still want to call - // that a breakpoint hit, and trigger the actions, etc. Otherwise you - // would see the - // PC at the breakpoint without having triggered the actions, then you'd - // continue, the PC wouldn't change, - // and you'd see the breakpoint hit, which would be odd. So the lower - // levels fake "step onto breakpoint address" and return that as a - // breakpoint. So our trace step COULD appear as a breakpoint hit if the - // next instruction also contained a breakpoint. StopReason reason = stop_info_sp->GetStopReason(); Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepRange.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepRange.cpp index 3c42cd750dad..896e647bbb52 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepRange.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepRange.cpp @@ -264,10 +264,9 @@ InstructionList *ThreadPlanStepRange::GetInstructionsForAddress( // Disassemble the address range given: const char *plugin_name = nullptr; const char *flavor = nullptr; - const bool prefer_file_cache = true; m_instruction_ranges[i] = Disassembler::DisassembleRange( GetTarget().GetArchitecture(), plugin_name, flavor, GetTarget(), - m_address_ranges[i], prefer_file_cache); + m_address_ranges[i]); } if (!m_instruction_ranges[i]) return nullptr; diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepThrough.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepThrough.cpp index 06b626935aba..6fc0312222fb 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepThrough.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepThrough.cpp @@ -22,7 +22,6 @@ using namespace lldb_private; // ThreadPlanStepThrough: If the current instruction is a trampoline, step // through it If it is the beginning of the prologue of a function, step // through that as well. -// FIXME: At present only handles DYLD trampolines. ThreadPlanStepThrough::ThreadPlanStepThrough(Thread &thread, StackID &m_stack_id, diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanTracer.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanTracer.cpp index c00415f3c1ee..754ce655729c 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanTracer.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanTracer.cpp @@ -35,11 +35,11 @@ using namespace lldb_private; ThreadPlanTracer::ThreadPlanTracer(Thread &thread, lldb::StreamSP &stream_sp) : m_process(*thread.GetProcess().get()), m_tid(thread.GetID()), - m_single_step(true), m_enabled(false), m_stream_sp(stream_sp) {} + m_enabled(false), m_stream_sp(stream_sp) {} ThreadPlanTracer::ThreadPlanTracer(Thread &thread) : m_process(*thread.GetProcess().get()), m_tid(thread.GetID()), - m_single_step(true), m_enabled(false), m_stream_sp() {} + m_enabled(false), m_stream_sp() {} Stream *ThreadPlanTracer::GetLogStream() { if (m_stream_sp) @@ -75,7 +75,7 @@ void ThreadPlanTracer::Log() { } bool ThreadPlanTracer::TracerExplainsStop() { - if (m_enabled && m_single_step) { + if (m_enabled) { lldb::StopInfoSP stop_info = GetThread().GetStopInfo(); return (stop_info->GetStopReason() == eStopReasonTrace); } else @@ -191,7 +191,7 @@ void ThreadPlanAssemblyTracer::Log() { for (int arg_index = 0; arg_index < num_args; ++arg_index) { Value value; - value.SetValueType(Value::eValueTypeScalar); + value.SetValueType(Value::ValueType::Scalar); value.SetCompilerType(intptr_type); value_list.PushValue(value); } diff --git a/contrib/llvm-project/lldb/source/Target/ThreadSpec.cpp b/contrib/llvm-project/lldb/source/Target/ThreadSpec.cpp index 1f6639379c45..ba4c3aa89455 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadSpec.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadSpec.cpp @@ -17,9 +17,7 @@ const char *ThreadSpec::g_option_names[static_cast<uint32_t>( ThreadSpec::OptionNames::LastOptionName)]{"Index", "ID", "Name", "QueueName"}; -ThreadSpec::ThreadSpec() - : m_index(UINT32_MAX), m_tid(LLDB_INVALID_THREAD_ID), m_name(), - m_queue_name() {} +ThreadSpec::ThreadSpec() : m_name(), m_queue_name() {} std::unique_ptr<ThreadSpec> ThreadSpec::CreateFromStructuredData( const StructuredData::Dictionary &spec_dict, Status &error) { diff --git a/contrib/llvm-project/lldb/source/Target/Trace.cpp b/contrib/llvm-project/lldb/source/Target/Trace.cpp index d19115b2d1f9..827f3264c096 100644 --- a/contrib/llvm-project/lldb/source/Target/Trace.cpp +++ b/contrib/llvm-project/lldb/source/Target/Trace.cpp @@ -13,6 +13,7 @@ #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Symbol/Function.h" +#include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Thread.h" @@ -57,9 +58,10 @@ static Error createInvalidPlugInError(StringRef plugin_name) { plugin_name.data()); } -Expected<lldb::TraceSP> Trace::FindPlugin(Debugger &debugger, - const json::Value &trace_session_file, - StringRef session_file_dir) { +Expected<lldb::TraceSP> +Trace::FindPluginForPostMortemProcess(Debugger &debugger, + const json::Value &trace_session_file, + StringRef session_file_dir) { JSONSimpleTraceSession json_session; json::Path::Root root("traceSession"); if (!json::fromJSON(trace_session_file, json_session, root)) @@ -72,6 +74,20 @@ Expected<lldb::TraceSP> Trace::FindPlugin(Debugger &debugger, return createInvalidPlugInError(json_session.trace.type); } +Expected<lldb::TraceSP> +Trace::FindPluginForLiveProcess(llvm::StringRef plugin_name, Process &process) { + if (!process.IsLiveDebugSession()) + return createStringError(inconvertibleErrorCode(), + "Can't trace non-live processes"); + + ConstString name(plugin_name); + if (auto create_callback = + PluginManager::GetTraceCreateCallbackForLiveProcess(name)) + return create_callback(process); + + return createInvalidPlugInError(plugin_name); +} + Expected<StringRef> Trace::FindPluginSchema(StringRef name) { ConstString plugin_name(name); StringRef schema = PluginManager::GetTraceSchema(plugin_name); @@ -81,188 +97,125 @@ Expected<StringRef> Trace::FindPluginSchema(StringRef name) { return createInvalidPlugInError(name); } -static int GetNumberOfDigits(size_t num) { - return num == 0 ? 1 : static_cast<int>(log10(num)) + 1; +Error Trace::Start(const llvm::json::Value &request) { + if (!m_live_process) + return createStringError(inconvertibleErrorCode(), + "Tracing requires a live process."); + return m_live_process->TraceStart(request); } -/// Dump the symbol context of the given instruction address if it's different -/// from the symbol context of the previous instruction in the trace. -/// -/// \param[in] prev_sc -/// The symbol context of the previous instruction in the trace. -/// -/// \param[in] address -/// The address whose symbol information will be dumped. -/// -/// \return -/// The symbol context of the current address, which might differ from the -/// previous one. -static SymbolContext DumpSymbolContext(Stream &s, const SymbolContext &prev_sc, - Target &target, const Address &address) { - AddressRange range; - if (prev_sc.GetAddressRange(eSymbolContextEverything, 0, - /*inline_block_range*/ false, range) && - range.ContainsFileAddress(address)) - return prev_sc; - - SymbolContext sc; - address.CalculateSymbolContext(&sc, eSymbolContextEverything); - - if (!prev_sc.module_sp && !sc.module_sp) - return sc; - if (prev_sc.module_sp == sc.module_sp && !sc.function && !sc.symbol && - !prev_sc.function && !prev_sc.symbol) - return sc; - - s.Printf(" "); - - if (!sc.module_sp) - s.Printf("(none)"); - else if (!sc.function && !sc.symbol) - s.Printf("%s`(none)", - sc.module_sp->GetFileSpec().GetFilename().AsCString()); - else - sc.DumpStopContext(&s, &target, address, /*show_fullpath*/ false, - /*show_module*/ true, /*show_inlined_frames*/ false, - /*show_function_arguments*/ true, - /*show_function_name*/ true, - /*show_inline_callsite_line_info*/ false); - s.Printf("\n"); - return sc; +Error Trace::Stop() { + if (!m_live_process) + return createStringError(inconvertibleErrorCode(), + "Tracing requires a live process."); + return m_live_process->TraceStop( + TraceStopRequest(GetPluginName().AsCString())); } -/// Dump an instruction given by its address using a given disassembler, unless -/// the instruction is not present in the disassembler. -/// -/// \param[in] disassembler -/// A disassembler containing a certain instruction list. -/// -/// \param[in] address -/// The address of the instruction to dump. -/// -/// \return -/// \b true if the information could be dumped, \b false otherwise. -static bool TryDumpInstructionInfo(Stream &s, - const DisassemblerSP &disassembler, - const ExecutionContext &exe_ctx, - const Address &address) { - if (!disassembler) - return false; - - if (InstructionSP instruction = - disassembler->GetInstructionList().GetInstructionAtAddress(address)) { - instruction->Dump(&s, /*show_address*/ false, /*show_bytes*/ false, - /*max_opcode_byte_size*/ 0, &exe_ctx, - /*sym_ctx*/ nullptr, /*prev_sym_ctx*/ nullptr, - /*disassembly_addr_format*/ nullptr, - /*max_address_text_size*/ 0); - return true; - } +Error Trace::Stop(llvm::ArrayRef<lldb::tid_t> tids) { + if (!m_live_process) + return createStringError(inconvertibleErrorCode(), + "Tracing requires a live process."); + return m_live_process->TraceStop( + TraceStopRequest(GetPluginName().AsCString(), tids)); +} - return false; +Expected<std::string> Trace::GetLiveProcessState() { + if (!m_live_process) + return createStringError(inconvertibleErrorCode(), + "Tracing requires a live process."); + return m_live_process->TraceGetState(GetPluginName().AsCString()); } -/// Dump an instruction instruction given by its address. -/// -/// \param[in] prev_disassembler -/// The disassembler that was used to dump the previous instruction in the -/// trace. It is useful to avoid recomputations. -/// -/// \param[in] address -/// The address of the instruction to dump. -/// -/// \return -/// A disassembler that contains the given instruction, which might differ -/// from the previous disassembler. -static DisassemblerSP -DumpInstructionInfo(Stream &s, const SymbolContext &sc, - const DisassemblerSP &prev_disassembler, - ExecutionContext &exe_ctx, const Address &address) { - // We first try to use the previous disassembler - if (TryDumpInstructionInfo(s, prev_disassembler, exe_ctx, address)) - return prev_disassembler; - - // Now we try using the current function's disassembler - if (sc.function) { - DisassemblerSP disassembler = - sc.function->GetInstructions(exe_ctx, nullptr, true); - if (TryDumpInstructionInfo(s, disassembler, exe_ctx, address)) - return disassembler; - } +Optional<size_t> Trace::GetLiveThreadBinaryDataSize(lldb::tid_t tid, + llvm::StringRef kind) { + auto it = m_live_thread_data.find(tid); + if (it == m_live_thread_data.end()) + return None; + std::unordered_map<std::string, size_t> &single_thread_data = it->second; + auto single_thread_data_it = single_thread_data.find(kind.str()); + if (single_thread_data_it == single_thread_data.end()) + return None; + return single_thread_data_it->second; +} + +Optional<size_t> Trace::GetLiveProcessBinaryDataSize(llvm::StringRef kind) { + auto data_it = m_live_process_data.find(kind.str()); + if (data_it == m_live_process_data.end()) + return None; + return data_it->second; +} + +Expected<ArrayRef<uint8_t>> +Trace::GetLiveThreadBinaryData(lldb::tid_t tid, llvm::StringRef kind) { + if (!m_live_process) + return createStringError(inconvertibleErrorCode(), + "Tracing requires a live process."); + llvm::Optional<size_t> size = GetLiveThreadBinaryDataSize(tid, kind); + if (!size) + return createStringError( + inconvertibleErrorCode(), + "Tracing data \"%s\" is not available for thread %" PRIu64 ".", + kind.data(), tid); + + TraceGetBinaryDataRequest request{GetPluginName().AsCString(), kind.str(), + static_cast<int64_t>(tid), 0, + static_cast<int64_t>(*size)}; + return m_live_process->TraceGetBinaryData(request); +} - // We fallback to disassembly one instruction - Target &target = exe_ctx.GetTargetRef(); - const ArchSpec &arch = target.GetArchitecture(); - AddressRange range(address, arch.GetMaximumOpcodeByteSize() * 1); - DisassemblerSP disassembler = Disassembler::DisassembleRange( - arch, /*plugin_name*/ nullptr, - /*flavor*/ nullptr, target, range, /*prefer_file_cache*/ true); - if (TryDumpInstructionInfo(s, disassembler, exe_ctx, address)) - return disassembler; - return nullptr; +Expected<ArrayRef<uint8_t>> +Trace::GetLiveProcessBinaryData(llvm::StringRef kind) { + if (!m_live_process) + return createStringError(inconvertibleErrorCode(), + "Tracing requires a live process."); + llvm::Optional<size_t> size = GetLiveProcessBinaryDataSize(kind); + if (!size) + return createStringError( + inconvertibleErrorCode(), + "Tracing data \"%s\" is not available for the process.", kind.data()); + + TraceGetBinaryDataRequest request{GetPluginName().AsCString(), kind.str(), + None, 0, static_cast<int64_t>(*size)}; + return m_live_process->TraceGetBinaryData(request); } -void Trace::DumpTraceInstructions(Thread &thread, Stream &s, size_t count, - size_t end_position, bool raw) { - size_t instructions_count = GetInstructionCount(thread); - s.Printf("thread #%u: tid = %" PRIu64 ", total instructions = %zu\n", - thread.GetIndexID(), thread.GetID(), instructions_count); +void Trace::RefreshLiveProcessState() { + if (!m_live_process) + return; + + uint32_t new_stop_id = m_live_process->GetStopID(); + if (new_stop_id == m_stop_id) + return; - if (count == 0 || end_position >= instructions_count) + m_stop_id = new_stop_id; + m_live_thread_data.clear(); + + Expected<std::string> json_string = GetLiveProcessState(); + if (!json_string) { + DoRefreshLiveProcessState(json_string.takeError()); + return; + } + Expected<TraceGetStateResponse> live_process_state = + json::parse<TraceGetStateResponse>(*json_string, "TraceGetStateResponse"); + if (!live_process_state) { + DoRefreshLiveProcessState(live_process_state.takeError()); return; + } + + for (const TraceThreadState &thread_state : + live_process_state->tracedThreads) { + for (const TraceBinaryData &item : thread_state.binaryData) + m_live_thread_data[thread_state.tid][item.kind] = item.size; + } + + for (const TraceBinaryData &item : live_process_state->processBinaryData) + m_live_process_data[item.kind] = item.size; + + DoRefreshLiveProcessState(std::move(live_process_state)); +} - size_t start_position = - end_position + 1 < count ? 0 : end_position + 1 - count; - - int digits_count = GetNumberOfDigits(end_position); - auto printInstructionIndex = [&](size_t index) { - s.Printf(" [%*zu] ", digits_count, index); - }; - - bool was_prev_instruction_an_error = false; - Target &target = thread.GetProcess()->GetTarget(); - - SymbolContext sc; - DisassemblerSP disassembler; - ExecutionContext exe_ctx; - target.CalculateExecutionContext(exe_ctx); - - TraverseInstructions( - thread, start_position, TraceDirection::Forwards, - [&](size_t index, Expected<lldb::addr_t> load_address) -> bool { - if (load_address) { - // We print an empty line after a sequence of errors to show more - // clearly that there's a gap in the trace - if (was_prev_instruction_an_error) - s.Printf(" ...missing instructions\n"); - - Address address; - if (!raw) { - target.GetSectionLoadList().ResolveLoadAddress(*load_address, - address); - - sc = DumpSymbolContext(s, sc, target, address); - } - - printInstructionIndex(index); - s.Printf("0x%016" PRIx64 " ", *load_address); - - if (!raw) { - disassembler = - DumpInstructionInfo(s, sc, disassembler, exe_ctx, address); - } - - was_prev_instruction_an_error = false; - } else { - printInstructionIndex(index); - s << toString(load_address.takeError()); - was_prev_instruction_an_error = true; - if (!raw) - sc = SymbolContext(); - } - - s.Printf("\n"); - - return index < end_position; - }); +uint32_t Trace::GetStopID() { + RefreshLiveProcessState(); + return m_stop_id; } diff --git a/contrib/llvm-project/lldb/source/Target/TraceCursor.cpp b/contrib/llvm-project/lldb/source/Target/TraceCursor.cpp new file mode 100644 index 000000000000..d0f69642cb90 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Target/TraceCursor.cpp @@ -0,0 +1,35 @@ +//===-- TraceCursor.cpp -----------------------------------------*- 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 +// +//===----------------------------------------------------------------------===// + +#include "lldb/Target/TraceCursor.h" + +#include "lldb/Target/ExecutionContext.h" + +using namespace lldb; +using namespace lldb_private; +using namespace llvm; + +TraceCursor::TraceCursor(lldb::ThreadSP thread_sp) + : m_exe_ctx_ref(ExecutionContext(thread_sp)) {} + +ExecutionContextRef &TraceCursor::GetExecutionContextRef() { + return m_exe_ctx_ref; +} + +void TraceCursor::SetGranularity( + lldb::TraceInstructionControlFlowType granularity) { + m_granularity = granularity; +} + +void TraceCursor::SetIgnoreErrors(bool ignore_errors) { + m_ignore_errors = ignore_errors; +} + +void TraceCursor::SetForwards(bool forwards) { m_forwards = forwards; } + +bool TraceCursor::IsForwards() const { return m_forwards; } diff --git a/contrib/llvm-project/lldb/source/Target/TraceExporter.cpp b/contrib/llvm-project/lldb/source/Target/TraceExporter.cpp new file mode 100644 index 000000000000..1a6571dba4a0 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Target/TraceExporter.cpp @@ -0,0 +1,32 @@ +//===-- TraceExporter.cpp -------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "lldb/Target/TraceExporter.h" + +#include "lldb/Core/PluginManager.h" + +using namespace lldb; +using namespace lldb_private; +using namespace llvm; + +static Error createInvalidPlugInError(StringRef plugin_name) { + return createStringError( + std::errc::invalid_argument, + "no trace expoter plug-in matches the specified type: \"%s\"", + plugin_name.data()); +} + +Expected<lldb::TraceExporterUP> +TraceExporter::FindPlugin(llvm::StringRef plugin_name) { + ConstString name(plugin_name); + if (auto create_callback = + PluginManager::GetTraceExporterCreateCallback(name)) + return create_callback(); + + return createInvalidPlugInError(plugin_name); +} diff --git a/contrib/llvm-project/lldb/source/Target/TraceInstructionDumper.cpp b/contrib/llvm-project/lldb/source/Target/TraceInstructionDumper.cpp new file mode 100644 index 000000000000..dc1e86481c36 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Target/TraceInstructionDumper.cpp @@ -0,0 +1,292 @@ +//===-- TraceInstructionDumper.cpp ----------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "lldb/Target/TraceInstructionDumper.h" + +#include "lldb/Core/Module.h" +#include "lldb/Symbol/Function.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/SectionLoadList.h" + +using namespace lldb; +using namespace lldb_private; +using namespace llvm; + +TraceInstructionDumper::TraceInstructionDumper(lldb::TraceCursorUP &&cursor_up, + int initial_index, bool raw, + bool show_tsc) + : m_cursor_up(std::move(cursor_up)), m_index(initial_index), m_raw(raw), + m_show_tsc(show_tsc) {} + +/// \return +/// Return \b true if the cursor could move one step. +bool TraceInstructionDumper::TryMoveOneStep() { + if (!m_cursor_up->Next()) { + SetNoMoreData(); + return false; + } + m_index += m_cursor_up->IsForwards() ? 1 : -1; + return true; +} + +/// \return +/// The number of characters that would be needed to print the given +/// integer. +static int GetNumberOfChars(int num) { + if (num == 0) + return 1; + return (num < 0 ? 1 : 0) + static_cast<int>(log10(abs(num))) + 1; +} + +/// Helper struct that holds symbol, disassembly and address information of an +/// instruction. +struct InstructionSymbolInfo { + SymbolContext sc; + Address address; + lldb::addr_t load_address; + lldb::DisassemblerSP disassembler; + lldb::InstructionSP instruction; + lldb_private::ExecutionContext exe_ctx; +}; + +// This custom LineEntry validator is neded because some line_entries have +// 0 as line, which is meaningless. Notice that LineEntry::IsValid only +// checks that line is not LLDB_INVALID_LINE_NUMBER, i.e. UINT32_MAX. +static bool IsLineEntryValid(const LineEntry &line_entry) { + return line_entry.IsValid() && line_entry.line > 0; +} + +/// \return +/// \b true if the provided line entries match line, column and source file. +/// This function assumes that the line entries are valid. +static bool FileLineAndColumnMatches(const LineEntry &a, const LineEntry &b) { + if (a.line != b.line) + return false; + if (a.column != b.column) + return false; + return a.file == b.file; +} + +/// Compare the symbol contexts of the provided \a InstructionSymbolInfo +/// objects. +/// +/// \return +/// \a true if both instructions belong to the same scope level analized +/// in the following order: +/// - module +/// - symbol +/// - function +/// - line +static bool +IsSameInstructionSymbolContext(const InstructionSymbolInfo &prev_insn, + const InstructionSymbolInfo &insn) { + // module checks + if (insn.sc.module_sp != prev_insn.sc.module_sp) + return false; + + // symbol checks + if (insn.sc.symbol != prev_insn.sc.symbol) + return false; + + // function checks + if (!insn.sc.function && !prev_insn.sc.function) + return true; + else if (insn.sc.function != prev_insn.sc.function) + return false; + + // line entry checks + const bool curr_line_valid = IsLineEntryValid(insn.sc.line_entry); + const bool prev_line_valid = IsLineEntryValid(prev_insn.sc.line_entry); + if (curr_line_valid && prev_line_valid) + return FileLineAndColumnMatches(insn.sc.line_entry, + prev_insn.sc.line_entry); + return curr_line_valid == prev_line_valid; +} + +/// Dump the symbol context of the given instruction address if it's different +/// from the symbol context of the previous instruction in the trace. +/// +/// \param[in] prev_sc +/// The symbol context of the previous instruction in the trace. +/// +/// \param[in] address +/// The address whose symbol information will be dumped. +/// +/// \return +/// The symbol context of the current address, which might differ from the +/// previous one. +static void +DumpInstructionSymbolContext(Stream &s, + Optional<InstructionSymbolInfo> prev_insn, + InstructionSymbolInfo &insn) { + if (prev_insn && IsSameInstructionSymbolContext(*prev_insn, insn)) + return; + + s.Printf(" "); + + if (!insn.sc.module_sp) + s.Printf("(none)"); + else if (!insn.sc.function && !insn.sc.symbol) + s.Printf("%s`(none)", + insn.sc.module_sp->GetFileSpec().GetFilename().AsCString()); + else + insn.sc.DumpStopContext(&s, insn.exe_ctx.GetTargetPtr(), insn.address, + /*show_fullpath=*/false, + /*show_module=*/true, /*show_inlined_frames=*/false, + /*show_function_arguments=*/true, + /*show_function_name=*/true); + s.Printf("\n"); +} + +static void DumpInstructionDisassembly(Stream &s, InstructionSymbolInfo &insn) { + if (!insn.instruction) + return; + s.Printf(" "); + insn.instruction->Dump(&s, /*show_address=*/false, /*show_bytes=*/false, + /*max_opcode_byte_size=*/0, &insn.exe_ctx, &insn.sc, + /*prev_sym_ctx=*/nullptr, + /*disassembly_addr_format=*/nullptr, + /*max_address_text_size=*/0); +} + +void TraceInstructionDumper::SetNoMoreData() { m_no_more_data = true; } + +bool TraceInstructionDumper::HasMoreData() { return !m_no_more_data; } + +void TraceInstructionDumper::DumpInstructions(Stream &s, size_t count) { + ThreadSP thread_sp = m_cursor_up->GetExecutionContextRef().GetThreadSP(); + if (!thread_sp) { + s.Printf("invalid thread"); + return; + } + + s.Printf("thread #%u: tid = %" PRIu64 "\n", thread_sp->GetIndexID(), + thread_sp->GetID()); + + int digits_count = GetNumberOfChars( + m_cursor_up->IsForwards() ? m_index + count - 1 : m_index - count + 1); + bool was_prev_instruction_an_error = false; + + auto printMissingInstructionsMessage = [&]() { + s.Printf(" ...missing instructions\n"); + }; + + auto printInstructionIndex = [&]() { + s.Printf(" [%*d] ", digits_count, m_index); + + if (m_show_tsc) { + s.Printf("[tsc="); + + if (Optional<uint64_t> timestamp = m_cursor_up->GetTimestampCounter()) + s.Printf("0x%016" PRIx64, *timestamp); + else + s.Printf("unavailable"); + + s.Printf("] "); + } + }; + + InstructionSymbolInfo prev_insn_info; + + Target &target = thread_sp->GetProcess()->GetTarget(); + ExecutionContext exe_ctx; + target.CalculateExecutionContext(exe_ctx); + const ArchSpec &arch = target.GetArchitecture(); + + // Find the symbol context for the given address reusing the previous + // instruction's symbol context when possible. + auto calculateSymbolContext = [&](const Address &address) { + AddressRange range; + if (prev_insn_info.sc.GetAddressRange(eSymbolContextEverything, 0, + /*inline_block_range*/ false, + range) && + range.Contains(address)) + return prev_insn_info.sc; + + SymbolContext sc; + address.CalculateSymbolContext(&sc, eSymbolContextEverything); + return sc; + }; + + // Find the disassembler for the given address reusing the previous + // instruction's disassembler when possible. + auto calculateDisass = [&](const Address &address, const SymbolContext &sc) { + if (prev_insn_info.disassembler) { + if (InstructionSP instruction = + prev_insn_info.disassembler->GetInstructionList() + .GetInstructionAtAddress(address)) + return std::make_tuple(prev_insn_info.disassembler, instruction); + } + + if (sc.function) { + if (DisassemblerSP disassembler = + sc.function->GetInstructions(exe_ctx, nullptr)) { + if (InstructionSP instruction = + disassembler->GetInstructionList().GetInstructionAtAddress( + address)) + return std::make_tuple(disassembler, instruction); + } + } + // We fallback to a single instruction disassembler + AddressRange range(address, arch.GetMaximumOpcodeByteSize()); + DisassemblerSP disassembler = + Disassembler::DisassembleRange(arch, /*plugin_name*/ nullptr, + /*flavor*/ nullptr, target, range); + return std::make_tuple(disassembler, + disassembler ? disassembler->GetInstructionList() + .GetInstructionAtAddress(address) + : InstructionSP()); + }; + + for (size_t i = 0; i < count; i++) { + if (!HasMoreData()) { + s.Printf(" no more data\n"); + break; + } + + if (Error err = m_cursor_up->GetError()) { + if (!m_cursor_up->IsForwards() && !was_prev_instruction_an_error) + printMissingInstructionsMessage(); + + was_prev_instruction_an_error = true; + + printInstructionIndex(); + s << toString(std::move(err)); + } else { + if (m_cursor_up->IsForwards() && was_prev_instruction_an_error) + printMissingInstructionsMessage(); + + was_prev_instruction_an_error = false; + + InstructionSymbolInfo insn_info; + + if (!m_raw) { + insn_info.load_address = m_cursor_up->GetLoadAddress(); + insn_info.exe_ctx = exe_ctx; + insn_info.address.SetLoadAddress(insn_info.load_address, &target); + insn_info.sc = calculateSymbolContext(insn_info.address); + std::tie(insn_info.disassembler, insn_info.instruction) = + calculateDisass(insn_info.address, insn_info.sc); + + DumpInstructionSymbolContext(s, prev_insn_info, insn_info); + } + + printInstructionIndex(); + s.Printf("0x%016" PRIx64, m_cursor_up->GetLoadAddress()); + + if (!m_raw) + DumpInstructionDisassembly(s, insn_info); + + prev_insn_info = insn_info; + } + + s.Printf("\n"); + TryMoveOneStep(); + } +} diff --git a/contrib/llvm-project/lldb/source/Target/UnwindLLDB.cpp b/contrib/llvm-project/lldb/source/Target/UnwindLLDB.cpp index 980ad4d2e342..047147112f3b 100644 --- a/contrib/llvm-project/lldb/source/Target/UnwindLLDB.cpp +++ b/contrib/llvm-project/lldb/source/Target/UnwindLLDB.cpp @@ -420,6 +420,8 @@ bool UnwindLLDB::DoGetFrameInfoAtIndex(uint32_t idx, addr_t &cfa, addr_t &pc, // too behaves like the zeroth frame (i.e. the pc might not // be pointing just past a call in it) behaves_like_zeroth_frame = true; + } else if (m_frames[idx]->reg_ctx_lldb_sp->BehavesLikeZerothFrame()) { + behaves_like_zeroth_frame = true; } else { behaves_like_zeroth_frame = false; } diff --git a/contrib/llvm-project/lldb/source/Utility/ArchSpec.cpp b/contrib/llvm-project/lldb/source/Utility/ArchSpec.cpp index c13e2389cfed..74a437042345 100644 --- a/contrib/llvm-project/lldb/source/Utility/ArchSpec.cpp +++ b/contrib/llvm-project/lldb/source/Utility/ArchSpec.cpp @@ -291,8 +291,8 @@ static const ArchDefinitionEntry g_macho_arch_entries[] = { {ArchSpec::eCore_arm_armv7m, llvm::MachO::CPU_TYPE_ARM, llvm::MachO::CPU_SUBTYPE_ARM_V7M, UINT32_MAX, SUBTYPE_MASK}, {ArchSpec::eCore_arm_armv7em, llvm::MachO::CPU_TYPE_ARM, llvm::MachO::CPU_SUBTYPE_ARM_V7EM, UINT32_MAX, SUBTYPE_MASK}, {ArchSpec::eCore_arm_arm64e, llvm::MachO::CPU_TYPE_ARM64, llvm::MachO::CPU_SUBTYPE_ARM64E, UINT32_MAX, SUBTYPE_MASK}, - {ArchSpec::eCore_arm_arm64, llvm::MachO::CPU_TYPE_ARM64, llvm::MachO::CPU_SUBTYPE_ARM64_V8, UINT32_MAX, SUBTYPE_MASK}, {ArchSpec::eCore_arm_arm64, llvm::MachO::CPU_TYPE_ARM64, llvm::MachO::CPU_SUBTYPE_ARM64_ALL, UINT32_MAX, SUBTYPE_MASK}, + {ArchSpec::eCore_arm_arm64, llvm::MachO::CPU_TYPE_ARM64, llvm::MachO::CPU_SUBTYPE_ARM64_V8, UINT32_MAX, SUBTYPE_MASK}, {ArchSpec::eCore_arm_arm64, llvm::MachO::CPU_TYPE_ARM64, 13, UINT32_MAX, SUBTYPE_MASK}, {ArchSpec::eCore_arm_arm64_32, llvm::MachO::CPU_TYPE_ARM64_32, 0, UINT32_MAX, SUBTYPE_MASK}, {ArchSpec::eCore_arm_arm64_32, llvm::MachO::CPU_TYPE_ARM64_32, 1, UINT32_MAX, SUBTYPE_MASK}, @@ -464,7 +464,7 @@ static const ArchDefinition *FindArchDefinition(ArchitectureType arch_type) { // Get an architecture definition by name. static const CoreDefinition *FindCoreDefinition(llvm::StringRef name) { for (unsigned int i = 0; i < llvm::array_lengthof(g_core_definitions); ++i) { - if (name.equals_lower(g_core_definitions[i].name)) + if (name.equals_insensitive(g_core_definitions[i].name)) return &g_core_definitions[i]; } return nullptr; @@ -507,7 +507,7 @@ FindArchDefinitionEntry(const ArchDefinition *def, ArchSpec::Core core) { //===----------------------------------------------------------------------===// // Constructors and destructors. -ArchSpec::ArchSpec() {} +ArchSpec::ArchSpec() = default; ArchSpec::ArchSpec(const char *triple_cstr) { if (triple_cstr) @@ -1118,18 +1118,6 @@ static bool cores_match(const ArchSpec::Core core1, const ArchSpec::Core core2, return true; break; - case ArchSpec::eCore_arm_armv6m: - if (!enforce_exact_match) { - if (core2 == ArchSpec::eCore_arm_generic) - return true; - try_inverse = false; - if (core2 == ArchSpec::eCore_arm_armv7) - return true; - if (core2 == ArchSpec::eCore_arm_armv6m) - return true; - } - break; - case ArchSpec::kCore_hexagon_any: if ((core2 >= ArchSpec::kCore_hexagon_first && core2 <= ArchSpec::kCore_hexagon_last) || @@ -1138,8 +1126,9 @@ static bool cores_match(const ArchSpec::Core core1, const ArchSpec::Core core2, break; // v. https://en.wikipedia.org/wiki/ARM_Cortex-M#Silicon_customization - // Cortex-M0 - ARMv6-M - armv6m Cortex-M3 - ARMv7-M - armv7m Cortex-M4 - - // ARMv7E-M - armv7em + // Cortex-M0 - ARMv6-M - armv6m + // Cortex-M3 - ARMv7-M - armv7m + // Cortex-M4 - ARMv7E-M - armv7em case ArchSpec::eCore_arm_armv7em: if (!enforce_exact_match) { if (core2 == ArchSpec::eCore_arm_generic) @@ -1155,8 +1144,9 @@ static bool cores_match(const ArchSpec::Core core1, const ArchSpec::Core core2, break; // v. https://en.wikipedia.org/wiki/ARM_Cortex-M#Silicon_customization - // Cortex-M0 - ARMv6-M - armv6m Cortex-M3 - ARMv7-M - armv7m Cortex-M4 - - // ARMv7E-M - armv7em + // Cortex-M0 - ARMv6-M - armv6m + // Cortex-M3 - ARMv7-M - armv7m + // Cortex-M4 - ARMv7E-M - armv7em case ArchSpec::eCore_arm_armv7m: if (!enforce_exact_match) { if (core2 == ArchSpec::eCore_arm_generic) @@ -1171,6 +1161,24 @@ static bool cores_match(const ArchSpec::Core core1, const ArchSpec::Core core2, } break; + // v. https://en.wikipedia.org/wiki/ARM_Cortex-M#Silicon_customization + // Cortex-M0 - ARMv6-M - armv6m + // Cortex-M3 - ARMv7-M - armv7m + // Cortex-M4 - ARMv7E-M - armv7em + case ArchSpec::eCore_arm_armv6m: + if (!enforce_exact_match) { + if (core2 == ArchSpec::eCore_arm_generic) + return true; + if (core2 == ArchSpec::eCore_arm_armv7em) + return true; + if (core2 == ArchSpec::eCore_arm_armv7) + return true; + if (core2 == ArchSpec::eCore_arm_armv6m) + return true; + try_inverse = false; + } + break; + case ArchSpec::eCore_arm_armv7f: case ArchSpec::eCore_arm_armv7k: case ArchSpec::eCore_arm_armv7s: diff --git a/contrib/llvm-project/lldb/source/Utility/Args.cpp b/contrib/llvm-project/lldb/source/Utility/Args.cpp index ed61e1c16303..0334659ab7dd 100644 --- a/contrib/llvm-project/lldb/source/Utility/Args.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Args.cpp @@ -194,7 +194,7 @@ Args &Args::operator=(const Args &rhs) { } // Destructor -Args::~Args() {} +Args::~Args() = default; void Args::Dump(Stream &s, const char *label_name) const { if (!label_name) @@ -256,8 +256,6 @@ void Args::SetCommandString(llvm::StringRef command) { m_argv.push_back(nullptr); } -size_t Args::GetArgumentCount() const { return m_entries.size(); } - const char *Args::GetArgumentAtIndex(size_t idx) const { if (idx < m_argv.size()) return m_argv[idx]; @@ -388,6 +386,7 @@ std::string Args::GetShellSafeArgument(const FileSpec &shell, static ShellDescriptor g_Shells[] = {{ConstString("bash"), " '\"<>()&"}, {ConstString("tcsh"), " '\"<>()&$"}, + {ConstString("zsh"), " '\"<>()&;\\|"}, {ConstString("sh"), " '\"<>()&"}}; // safe minimal set diff --git a/contrib/llvm-project/lldb/source/Utility/Broadcaster.cpp b/contrib/llvm-project/lldb/source/Utility/Broadcaster.cpp index 342548c0b0e6..6e0672496321 100644 --- a/contrib/llvm-project/lldb/source/Utility/Broadcaster.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Broadcaster.cpp @@ -19,8 +19,8 @@ #include <memory> #include <utility> -#include <assert.h> -#include <stddef.h> +#include <cassert> +#include <cstddef> using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm-project/lldb/source/Utility/ConstString.cpp b/contrib/llvm-project/lldb/source/Utility/ConstString.cpp index 11f48d0fcaba..e5e1b2387e64 100644 --- a/contrib/llvm-project/lldb/source/Utility/ConstString.cpp +++ b/contrib/llvm-project/lldb/source/Utility/ConstString.cpp @@ -21,9 +21,9 @@ #include <array> #include <utility> -#include <inttypes.h> -#include <stdint.h> -#include <string.h> +#include <cinttypes> +#include <cstdint> +#include <cstring> using namespace lldb_private; @@ -253,7 +253,7 @@ bool ConstString::Equals(ConstString lhs, ConstString rhs, // perform case insensitive equality test llvm::StringRef lhs_string_ref(lhs.GetStringRef()); llvm::StringRef rhs_string_ref(rhs.GetStringRef()); - return lhs_string_ref.equals_lower(rhs_string_ref); + return lhs_string_ref.equals_insensitive(rhs_string_ref); } int ConstString::Compare(ConstString lhs, ConstString rhs, @@ -270,7 +270,7 @@ int ConstString::Compare(ConstString lhs, ConstString rhs, if (case_sensitive) { return lhs_string_ref.compare(rhs_string_ref); } else { - return lhs_string_ref.compare_lower(rhs_string_ref); + return lhs_string_ref.compare_insensitive(rhs_string_ref); } } diff --git a/contrib/llvm-project/lldb/source/Utility/DataBufferLLVM.cpp b/contrib/llvm-project/lldb/source/Utility/DataBufferLLVM.cpp index 235123a31cee..c5aeddd683f4 100644 --- a/contrib/llvm-project/lldb/source/Utility/DataBufferLLVM.cpp +++ b/contrib/llvm-project/lldb/source/Utility/DataBufferLLVM.cpp @@ -10,7 +10,7 @@ #include "llvm/Support/MemoryBuffer.h" -#include <assert.h> +#include <cassert> using namespace lldb_private; @@ -21,7 +21,7 @@ DataBufferLLVM::DataBufferLLVM( "Cannot construct a DataBufferLLVM with a null buffer"); } -DataBufferLLVM::~DataBufferLLVM() {} +DataBufferLLVM::~DataBufferLLVM() = default; uint8_t *DataBufferLLVM::GetBytes() { return reinterpret_cast<uint8_t *>(Buffer->getBufferStart()); diff --git a/contrib/llvm-project/lldb/source/Utility/DataEncoder.cpp b/contrib/llvm-project/lldb/source/Utility/DataEncoder.cpp index 7532ac1fdcaf..e88cd23c1d84 100644 --- a/contrib/llvm-project/lldb/source/Utility/DataEncoder.cpp +++ b/contrib/llvm-project/lldb/source/Utility/DataEncoder.cpp @@ -16,7 +16,7 @@ #include <cstddef> -#include <string.h> +#include <cstring> using namespace lldb; using namespace lldb_private; @@ -24,8 +24,7 @@ using namespace llvm::support::endian; // Default constructor. DataEncoder::DataEncoder() - : m_start(nullptr), m_end(nullptr), - m_byte_order(endian::InlHostByteOrder()), m_addr_size(sizeof(void *)), + : m_byte_order(endian::InlHostByteOrder()), m_addr_size(sizeof(void *)), m_data_sp() {} // This constructor allows us to use data that is owned by someone else. The diff --git a/contrib/llvm-project/lldb/source/Utility/DataExtractor.cpp b/contrib/llvm-project/lldb/source/Utility/DataExtractor.cpp index 64b878d7dee7..bdd79fd9b411 100644 --- a/contrib/llvm-project/lldb/source/Utility/DataExtractor.cpp +++ b/contrib/llvm-project/lldb/source/Utility/DataExtractor.cpp @@ -33,9 +33,9 @@ #include <cstdint> #include <string> -#include <ctype.h> -#include <inttypes.h> -#include <string.h> +#include <cctype> +#include <cinttypes> +#include <cstring> using namespace lldb; using namespace lldb_private; @@ -120,9 +120,8 @@ static inline uint64_t ReadMaxInt64(const uint8_t *data, size_t byte_size, } DataExtractor::DataExtractor() - : m_start(nullptr), m_end(nullptr), - m_byte_order(endian::InlHostByteOrder()), m_addr_size(sizeof(void *)), - m_data_sp(), m_target_byte_size(1) {} + : m_byte_order(endian::InlHostByteOrder()), m_addr_size(sizeof(void *)), + m_data_sp() {} // This constructor allows us to use data that is owned by someone else. The // data must stay around as long as this object is valid. diff --git a/contrib/llvm-project/lldb/source/Utility/Event.cpp b/contrib/llvm-project/lldb/source/Utility/Event.cpp index 50cc7f061dc6..4c07293c92df 100644 --- a/contrib/llvm-project/lldb/source/Utility/Event.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Event.cpp @@ -17,7 +17,7 @@ #include <algorithm> -#include <ctype.h> +#include <cctype> using namespace lldb; using namespace lldb_private; @@ -198,7 +198,7 @@ EventDataStructuredData::EventDataStructuredData( : EventData(), m_process_sp(process_sp), m_object_sp(object_sp), m_plugin_sp(plugin_sp) {} -EventDataStructuredData::~EventDataStructuredData() {} +EventDataStructuredData::~EventDataStructuredData() = default; // EventDataStructuredData member functions diff --git a/contrib/llvm-project/lldb/source/Utility/FileSpec.cpp b/contrib/llvm-project/lldb/source/Utility/FileSpec.cpp index 1ec5d60e2780..bea3c6d6268b 100644 --- a/contrib/llvm-project/lldb/source/Utility/FileSpec.cpp +++ b/contrib/llvm-project/lldb/source/Utility/FileSpec.cpp @@ -24,10 +24,10 @@ #include <system_error> #include <vector> -#include <assert.h> -#include <limits.h> -#include <stdio.h> -#include <string.h> +#include <cassert> +#include <climits> +#include <cstdio> +#include <cstring> using namespace lldb; using namespace lldb_private; @@ -499,9 +499,9 @@ void FileSpec::MakeAbsolute(const FileSpec &dir) { void llvm::format_provider<FileSpec>::format(const FileSpec &F, raw_ostream &Stream, StringRef Style) { - assert( - (Style.empty() || Style.equals_lower("F") || Style.equals_lower("D")) && - "Invalid FileSpec style!"); + assert((Style.empty() || Style.equals_insensitive("F") || + Style.equals_insensitive("D")) && + "Invalid FileSpec style!"); StringRef dir = F.GetDirectory().GetStringRef(); StringRef file = F.GetFilename().GetStringRef(); @@ -511,7 +511,7 @@ void llvm::format_provider<FileSpec>::format(const FileSpec &F, return; } - if (Style.equals_lower("F")) { + if (Style.equals_insensitive("F")) { Stream << (file.empty() ? "(empty)" : file); return; } @@ -527,7 +527,7 @@ void llvm::format_provider<FileSpec>::format(const FileSpec &F, Stream << GetPreferredPathSeparator(F.GetPathStyle()); } - if (Style.equals_lower("D")) { + if (Style.equals_insensitive("D")) { // We only want to print the directory, so now just exit. if (dir.empty()) Stream << "(empty)"; diff --git a/contrib/llvm-project/lldb/source/Utility/GDBRemote.cpp b/contrib/llvm-project/lldb/source/Utility/GDBRemote.cpp index f267d00fc97e..91f94de4dc0d 100644 --- a/contrib/llvm-project/lldb/source/Utility/GDBRemote.cpp +++ b/contrib/llvm-project/lldb/source/Utility/GDBRemote.cpp @@ -11,7 +11,7 @@ #include "lldb/Utility/Flags.h" #include "lldb/Utility/Stream.h" -#include <stdio.h> +#include <cstdio> using namespace lldb; using namespace lldb_private::repro; @@ -24,7 +24,7 @@ StreamGDBRemote::StreamGDBRemote(uint32_t flags, uint32_t addr_size, ByteOrder byte_order) : StreamString(flags, addr_size, byte_order) {} -StreamGDBRemote::~StreamGDBRemote() {} +StreamGDBRemote::~StreamGDBRemote() = default; int StreamGDBRemote::PutEscapedBytes(const void *s, size_t src_len) { int bytes_written = 0; @@ -104,7 +104,7 @@ void GDBRemoteProvider::Keep() { FileSpec file = GetRoot().CopyByAppendingPathComponent(Info::file); std::error_code ec; - llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text); + llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_TextWithCRLF); if (ec) return; yaml::Output yout(os); @@ -150,8 +150,8 @@ llvm::raw_ostream *GDBRemoteProvider::GetHistoryStream() { FileSpec history_file = GetRoot().CopyByAppendingPathComponent(Info::file); std::error_code EC; - m_stream_up = std::make_unique<raw_fd_ostream>(history_file.GetPath(), EC, - sys::fs::OpenFlags::OF_Text); + m_stream_up = std::make_unique<raw_fd_ostream>( + history_file.GetPath(), EC, sys::fs::OpenFlags::OF_TextWithCRLF); return m_stream_up.get(); } diff --git a/contrib/llvm-project/lldb/source/Utility/LLDBAssert.cpp b/contrib/llvm-project/lldb/source/Utility/LLDBAssert.cpp index 6ae0ee50ef14..a8d8ef65a945 100644 --- a/contrib/llvm-project/lldb/source/Utility/LLDBAssert.cpp +++ b/contrib/llvm-project/lldb/source/Utility/LLDBAssert.cpp @@ -7,11 +7,15 @@ //===----------------------------------------------------------------------===// #include "lldb/Utility/LLDBAssert.h" - +#include "llvm/Config/llvm-config.h" #include "llvm/Support/Format.h" #include "llvm/Support/Signals.h" #include "llvm/Support/raw_ostream.h" +#if LLVM_SUPPORT_XCODE_SIGNPOSTS +#include <os/log.h> +#endif + using namespace llvm; using namespace lldb_private; @@ -24,6 +28,14 @@ void lldb_private::lldb_assert(bool expression, const char *expr_text, // If asserts are enabled abort here. assert(false && "lldb_assert failed"); +#if LLVM_SUPPORT_XCODE_SIGNPOSTS + if (__builtin_available(macos 10.12, iOS 10, tvOS 10, watchOS 3, *)) { + os_log_fault(OS_LOG_DEFAULT, + "Assertion failed: (%s), function %s, file %s, line %u\n", + expr_text, func, file, line); + } +#endif + // In a release configuration it will print a warning and encourage the user // to file a bug report, similar to LLVM’s crash handler, and then return // execution. diff --git a/contrib/llvm-project/lldb/source/Utility/Log.cpp b/contrib/llvm-project/lldb/source/Utility/Log.cpp index 4df82f2bf4d7..ff654ec93e78 100644 --- a/contrib/llvm-project/lldb/source/Utility/Log.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Log.cpp @@ -25,7 +25,7 @@ #include <mutex> #include <utility> -#include <assert.h> +#include <cassert> #if defined(_WIN32) #include <process.h> #else @@ -60,17 +60,18 @@ uint32_t Log::GetFlags(llvm::raw_ostream &stream, const ChannelMap::value_type & bool list_categories = false; uint32_t flags = 0; for (const char *category : categories) { - if (llvm::StringRef("all").equals_lower(category)) { + if (llvm::StringRef("all").equals_insensitive(category)) { flags |= UINT32_MAX; continue; } - if (llvm::StringRef("default").equals_lower(category)) { + if (llvm::StringRef("default").equals_insensitive(category)) { flags |= entry.second.m_channel.default_flags; continue; } - auto cat = llvm::find_if( - entry.second.m_channel.categories, - [&](const Log::Category &c) { return c.name.equals_lower(category); }); + auto cat = llvm::find_if(entry.second.m_channel.categories, + [&](const Log::Category &c) { + return c.name.equals_insensitive(category); + }); if (cat != entry.second.m_channel.categories.end()) { flags |= cat->flag; continue; diff --git a/contrib/llvm-project/lldb/source/Utility/Logging.cpp b/contrib/llvm-project/lldb/source/Utility/Logging.cpp index 435017e9d744..4648bec502c5 100644 --- a/contrib/llvm-project/lldb/source/Utility/Logging.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Logging.cpp @@ -11,7 +11,7 @@ #include "llvm/ADT/ArrayRef.h" -#include <stdarg.h> +#include <cstdarg> using namespace lldb_private; diff --git a/contrib/llvm-project/lldb/source/Utility/ProcessInfo.cpp b/contrib/llvm-project/lldb/source/Utility/ProcessInfo.cpp index 310d2b22b174..c9759bbe513e 100644 --- a/contrib/llvm-project/lldb/source/Utility/ProcessInfo.cpp +++ b/contrib/llvm-project/lldb/source/Utility/ProcessInfo.cpp @@ -22,8 +22,7 @@ using namespace lldb_private; using namespace lldb_private::repro; ProcessInfo::ProcessInfo() - : m_executable(), m_arguments(), m_environment(), m_uid(UINT32_MAX), - m_gid(UINT32_MAX), m_arch(), m_pid(LLDB_INVALID_PROCESS_ID) {} + : m_executable(), m_arguments(), m_environment(), m_arch() {} ProcessInfo::ProcessInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) diff --git a/contrib/llvm-project/lldb/source/Utility/RegisterValue.cpp b/contrib/llvm-project/lldb/source/Utility/RegisterValue.cpp index 7848f784d8f2..a298c70d370b 100644 --- a/contrib/llvm-project/lldb/source/Utility/RegisterValue.cpp +++ b/contrib/llvm-project/lldb/source/Utility/RegisterValue.cpp @@ -24,9 +24,9 @@ #include <tuple> #include <vector> -#include <assert.h> -#include <inttypes.h> -#include <stdio.h> +#include <cassert> +#include <cinttypes> +#include <cstdio> using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm-project/lldb/source/Utility/Reproducer.cpp b/contrib/llvm-project/lldb/source/Utility/Reproducer.cpp index f302cce4436f..b63863c535fa 100644 --- a/contrib/llvm-project/lldb/source/Utility/Reproducer.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Reproducer.cpp @@ -20,15 +20,6 @@ using namespace lldb_private::repro; using namespace llvm; using namespace llvm::yaml; -static llvm::Optional<bool> GetEnv(const char *var) { - std::string val = llvm::StringRef(getenv(var)).lower(); - if (val == "0" || val == "off") - return false; - if (val == "1" || val == "on") - return true; - return {}; -} - Reproducer &Reproducer::Instance() { return *InstanceImpl(); } llvm::Error Reproducer::Initialize(ReproducerMode mode, @@ -36,16 +27,6 @@ llvm::Error Reproducer::Initialize(ReproducerMode mode, lldbassert(!InstanceImpl() && "Already initialized."); InstanceImpl().emplace(); - // The environment can override the capture mode. - if (mode != ReproducerMode::Replay) { - if (llvm::Optional<bool> override = GetEnv("LLDB_CAPTURE_REPRODUCER")) { - if (*override) - mode = ReproducerMode::Capture; - else - mode = ReproducerMode::Off; - } - } - switch (mode) { case ReproducerMode::Capture: { if (!root) { @@ -374,7 +355,7 @@ static llvm::Error addPaths(StringRef path, SmallVector<StringRef, 0> paths; (*buffer)->getBuffer().split(paths, '\0'); for (StringRef p : paths) { - if (!p.empty()) + if (!p.empty() && llvm::sys::fs::exists(p)) callback(p); } diff --git a/contrib/llvm-project/lldb/source/Utility/ReproducerInstrumentation.cpp b/contrib/llvm-project/lldb/source/Utility/ReproducerInstrumentation.cpp index b274a10c98fd..e5bd2ba4b625 100644 --- a/contrib/llvm-project/lldb/source/Utility/ReproducerInstrumentation.cpp +++ b/contrib/llvm-project/lldb/source/Utility/ReproducerInstrumentation.cpp @@ -8,9 +8,9 @@ #include "lldb/Utility/ReproducerInstrumentation.h" #include "lldb/Utility/Reproducer.h" +#include <cstdio> +#include <cstdlib> #include <limits> -#include <stdio.h> -#include <stdlib.h> #include <thread> using namespace lldb_private; @@ -193,8 +193,8 @@ unsigned ObjectToIndex::GetIndexForObjectImpl(const void *object) { } Recorder::Recorder() - : m_serializer(nullptr), m_pretty_func(), m_pretty_args(), - m_local_boundary(false), m_result_recorded(true), + : m_pretty_func(), m_pretty_args(), + m_sequence(std::numeric_limits<unsigned>::max()) { if (!g_global_boundary) { g_global_boundary = true; diff --git a/contrib/llvm-project/lldb/source/Utility/ReproducerProvider.cpp b/contrib/llvm-project/lldb/source/Utility/ReproducerProvider.cpp index ed016820db21..5145819b717c 100644 --- a/contrib/llvm-project/lldb/source/Utility/ReproducerProvider.cpp +++ b/contrib/llvm-project/lldb/source/Utility/ReproducerProvider.cpp @@ -39,7 +39,7 @@ YamlRecorder::Create(const FileSpec &filename) { void VersionProvider::Keep() { FileSpec file = GetRoot().CopyByAppendingPathComponent(Info::file); std::error_code ec; - llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text); + llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_TextWithCRLF); if (ec) return; os << m_version << "\n"; @@ -108,7 +108,7 @@ void ProcessInfoProvider::Keep() { FileSpec file = GetRoot().CopyByAppendingPathComponent(Info::file); std::error_code ec; - llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text); + llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_TextWithCRLF); if (ec) return; llvm::yaml::Output yout(os); @@ -153,7 +153,7 @@ void SymbolFileProvider::AddSymbolFile(const UUID *uuid, void SymbolFileProvider::Keep() { FileSpec file = this->GetRoot().CopyByAppendingPathComponent(Info::file); std::error_code ec; - llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text); + llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_TextWithCRLF); if (ec) return; diff --git a/contrib/llvm-project/lldb/source/Utility/Scalar.cpp b/contrib/llvm-project/lldb/source/Utility/Scalar.cpp index 9bf633d0c4e0..e0b26e89f3c1 100644 --- a/contrib/llvm-project/lldb/source/Utility/Scalar.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Scalar.cpp @@ -160,7 +160,7 @@ void Scalar::GetValue(Stream *s, bool show_type) const { case e_void: break; case e_int: - s->PutCString(m_integer.toString(10)); + s->PutCString(llvm::toString(m_integer, 10)); break; case e_float: llvm::SmallString<24> string; diff --git a/contrib/llvm-project/lldb/source/Utility/SelectHelper.cpp b/contrib/llvm-project/lldb/source/Utility/SelectHelper.cpp index 40c85bee6072..059f810e2194 100644 --- a/contrib/llvm-project/lldb/source/Utility/SelectHelper.cpp +++ b/contrib/llvm-project/lldb/source/Utility/SelectHelper.cpp @@ -25,7 +25,7 @@ #include <algorithm> #include <chrono> -#include <errno.h> +#include <cerrno> #if defined(_WIN32) // Define NOMINMAX to avoid macros that conflict with std::min and std::max #define NOMINMAX diff --git a/contrib/llvm-project/lldb/source/Utility/Status.cpp b/contrib/llvm-project/lldb/source/Utility/Status.cpp index e3c4284a8e8a..72fd087decc0 100644 --- a/contrib/llvm-project/lldb/source/Utility/Status.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Status.cpp @@ -28,7 +28,7 @@ #ifdef _WIN32 #include <windows.h> #endif -#include <stdint.h> +#include <cstdint> namespace llvm { class raw_ostream; @@ -37,7 +37,7 @@ class raw_ostream; using namespace lldb; using namespace lldb_private; -Status::Status() : m_code(0), m_type(eErrorTypeInvalid), m_string() {} +Status::Status() : m_string() {} Status::Status(ValueType err, ErrorType type) : m_code(err), m_type(type), m_string() {} diff --git a/contrib/llvm-project/lldb/source/Utility/Stream.cpp b/contrib/llvm-project/lldb/source/Utility/Stream.cpp index a0623bfa6e54..a1e2de9da4d9 100644 --- a/contrib/llvm-project/lldb/source/Utility/Stream.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Stream.cpp @@ -16,8 +16,8 @@ #include <string> -#include <inttypes.h> -#include <stddef.h> +#include <cinttypes> +#include <cstddef> using namespace lldb; using namespace lldb_private; @@ -28,11 +28,11 @@ Stream::Stream(uint32_t flags, uint32_t addr_size, ByteOrder byte_order, m_indent_level(0), m_forwarder(*this, colors) {} Stream::Stream(bool colors) - : m_flags(0), m_addr_size(4), m_byte_order(endian::InlHostByteOrder()), - m_indent_level(0), m_forwarder(*this, colors) {} + : m_flags(0), m_byte_order(endian::InlHostByteOrder()), + m_forwarder(*this, colors) {} // Destructor -Stream::~Stream() {} +Stream::~Stream() = default; ByteOrder Stream::SetByteOrder(ByteOrder byte_order) { ByteOrder old_byte_order = m_byte_order; diff --git a/contrib/llvm-project/lldb/source/Utility/StreamString.cpp b/contrib/llvm-project/lldb/source/Utility/StreamString.cpp index 190be588e887..745a85b75765 100644 --- a/contrib/llvm-project/lldb/source/Utility/StreamString.cpp +++ b/contrib/llvm-project/lldb/source/Utility/StreamString.cpp @@ -17,7 +17,7 @@ StreamString::StreamString(uint32_t flags, uint32_t addr_size, ByteOrder byte_order) : Stream(flags, addr_size, byte_order), m_packet() {} -StreamString::~StreamString() {} +StreamString::~StreamString() = default; void StreamString::Flush() { // Nothing to do when flushing a buffer based stream... diff --git a/contrib/llvm-project/lldb/source/Utility/StringExtractor.cpp b/contrib/llvm-project/lldb/source/Utility/StringExtractor.cpp index 0553a63a021e..d082c86f8463 100644 --- a/contrib/llvm-project/lldb/source/Utility/StringExtractor.cpp +++ b/contrib/llvm-project/lldb/source/Utility/StringExtractor.cpp @@ -11,9 +11,9 @@ #include <tuple> -#include <ctype.h> -#include <stdlib.h> -#include <string.h> +#include <cctype> +#include <cstdlib> +#include <cstring> static inline int xdigit_to_sint(char ch) { if (ch >= 'a' && ch <= 'f') @@ -26,7 +26,7 @@ static inline int xdigit_to_sint(char ch) { } // StringExtractor constructor -StringExtractor::StringExtractor() : m_packet(), m_index(0) {} +StringExtractor::StringExtractor() : m_packet() {} StringExtractor::StringExtractor(llvm::StringRef packet_str) : m_packet(), m_index(0) { @@ -40,7 +40,7 @@ StringExtractor::StringExtractor(const char *packet_cstr) } // Destructor -StringExtractor::~StringExtractor() {} +StringExtractor::~StringExtractor() = default; char StringExtractor::GetChar(char fail_value) { if (m_index < m_packet.size()) { diff --git a/contrib/llvm-project/lldb/source/Utility/StringExtractorGDBRemote.cpp b/contrib/llvm-project/lldb/source/Utility/StringExtractorGDBRemote.cpp index def096866426..29cf585bea56 100644 --- a/contrib/llvm-project/lldb/source/Utility/StringExtractorGDBRemote.cpp +++ b/contrib/llvm-project/lldb/source/Utility/StringExtractorGDBRemote.cpp @@ -8,8 +8,11 @@ #include "lldb/Utility/StringExtractorGDBRemote.h" -#include <ctype.h> -#include <string.h> +#include <cctype> +#include <cstring> + +constexpr lldb::pid_t StringExtractorGDBRemote::AllProcesses; +constexpr lldb::tid_t StringExtractorGDBRemote::AllThreads; StringExtractorGDBRemote::ResponseType StringExtractorGDBRemote::GetResponseType() const { @@ -140,6 +143,11 @@ StringExtractorGDBRemote::GetServerPacketType() const { return eServerPacketType_QListThreadsInStopReply; break; + case 'M': + if (PACKET_STARTS_WITH("QMemTags")) + return eServerPacketType_QMemTags; + break; + case 'R': if (PACKET_STARTS_WITH("QRestoreRegisterState:")) return eServerPacketType_QRestoreRegisterState; @@ -220,6 +228,8 @@ StringExtractorGDBRemote::GetServerPacketType() const { return eServerPacketType_qMemoryRegionInfoSupported; if (PACKET_STARTS_WITH("qModuleInfo:")) return eServerPacketType_qModuleInfo; + if (PACKET_STARTS_WITH("qMemTags:")) + return eServerPacketType_qMemTags; break; case 'P': @@ -300,18 +310,17 @@ StringExtractorGDBRemote::GetServerPacketType() const { return eServerPacketType_jSignalsInfo; if (PACKET_MATCHES("jThreadsInfo")) return eServerPacketType_jThreadsInfo; - if (PACKET_STARTS_WITH("jTraceBufferRead:")) - return eServerPacketType_jTraceBufferRead; - if (PACKET_STARTS_WITH("jTraceConfigRead:")) - return eServerPacketType_jTraceConfigRead; - if (PACKET_STARTS_WITH("jTraceMetaRead:")) - return eServerPacketType_jTraceMetaRead; - if (PACKET_STARTS_WITH("jTraceStart:")) - return eServerPacketType_jTraceStart; - if (PACKET_STARTS_WITH("jTraceStop:")) - return eServerPacketType_jTraceStop; - if (PACKET_MATCHES("jLLDBTraceSupportedType")) - return eServerPacketType_jLLDBTraceSupportedType; + + if (PACKET_MATCHES("jLLDBTraceSupported")) + return eServerPacketType_jLLDBTraceSupported; + if (PACKET_STARTS_WITH("jLLDBTraceStop:")) + return eServerPacketType_jLLDBTraceStop; + if (PACKET_STARTS_WITH("jLLDBTraceStart:")) + return eServerPacketType_jLLDBTraceStart; + if (PACKET_STARTS_WITH("jLLDBTraceGetState:")) + return eServerPacketType_jLLDBTraceGetState; + if (PACKET_STARTS_WITH("jLLDBTraceGetBinaryData:")) + return eServerPacketType_jLLDBTraceGetBinaryData; break; case 'v': @@ -376,9 +385,7 @@ StringExtractorGDBRemote::GetServerPacketType() const { return eServerPacketType_C; case 'D': - if (packet_size == 1) - return eServerPacketType_D; - break; + return eServerPacketType_D; case 'g': return eServerPacketType_g; @@ -606,3 +613,46 @@ bool StringExtractorGDBRemote::ValidateResponse() const { else return true; // No validator, so response is valid } + +llvm::Optional<std::pair<lldb::pid_t, lldb::tid_t>> +StringExtractorGDBRemote::GetPidTid(lldb::pid_t default_pid) { + llvm::StringRef view = llvm::StringRef(m_packet).substr(m_index); + size_t initial_length = view.size(); + lldb::pid_t pid = default_pid; + lldb::tid_t tid; + + if (view.consume_front("p")) { + // process identifier + if (view.consume_front("-1")) { + // -1 is a special case + pid = AllProcesses; + } else if (view.consumeInteger(16, pid) || pid == 0) { + // not a valid hex integer OR unsupported pid 0 + m_index = UINT64_MAX; + return llvm::None; + } + + // "." must follow if we expect TID too; otherwise, we assume -1 + if (!view.consume_front(".")) { + // update m_index + m_index += initial_length - view.size(); + + return {{pid, AllThreads}}; + } + } + + // thread identifier + if (view.consume_front("-1")) { + // -1 is a special case + tid = AllThreads; + } else if (view.consumeInteger(16, tid) || tid == 0 || pid == AllProcesses) { + // not a valid hex integer OR tid 0 OR pid -1 + a specific tid + m_index = UINT64_MAX; + return llvm::None; + } + + // update m_index + m_index += initial_length - view.size(); + + return {{pid, tid}}; +} diff --git a/contrib/llvm-project/lldb/source/Utility/StringLexer.cpp b/contrib/llvm-project/lldb/source/Utility/StringLexer.cpp index 26185517e275..bda6e25ce7a3 100644 --- a/contrib/llvm-project/lldb/source/Utility/StringLexer.cpp +++ b/contrib/llvm-project/lldb/source/Utility/StringLexer.cpp @@ -9,7 +9,7 @@ #include "lldb/Utility/StringLexer.h" #include <algorithm> -#include <assert.h> +#include <cassert> #include <utility> using namespace lldb_private; diff --git a/contrib/llvm-project/lldb/source/Utility/StringList.cpp b/contrib/llvm-project/lldb/source/Utility/StringList.cpp index d3896ca60ac9..baff34ae3a5e 100644 --- a/contrib/llvm-project/lldb/source/Utility/StringList.cpp +++ b/contrib/llvm-project/lldb/source/Utility/StringList.cpp @@ -14,8 +14,8 @@ #include "llvm/ADT/ArrayRef.h" #include <algorithm> -#include <stdint.h> -#include <string.h> +#include <cstdint> +#include <cstring> using namespace lldb_private; @@ -33,7 +33,7 @@ StringList::StringList(const char **strv, int strc) : m_strings() { } } -StringList::~StringList() {} +StringList::~StringList() = default; void StringList::AppendString(const char *str) { if (str) diff --git a/contrib/llvm-project/lldb/source/Utility/StructuredData.cpp b/contrib/llvm-project/lldb/source/Utility/StructuredData.cpp index b349de7b0b78..fc10fa539e9e 100644 --- a/contrib/llvm-project/lldb/source/Utility/StructuredData.cpp +++ b/contrib/llvm-project/lldb/source/Utility/StructuredData.cpp @@ -11,8 +11,8 @@ #include "lldb/Utility/Status.h" #include "llvm/Support/MemoryBuffer.h" #include <cerrno> +#include <cinttypes> #include <cstdlib> -#include <inttypes.h> using namespace lldb_private; using namespace llvm; diff --git a/contrib/llvm-project/lldb/source/Utility/TildeExpressionResolver.cpp b/contrib/llvm-project/lldb/source/Utility/TildeExpressionResolver.cpp index 75d9c47e656d..6311ae062f1f 100644 --- a/contrib/llvm-project/lldb/source/Utility/TildeExpressionResolver.cpp +++ b/contrib/llvm-project/lldb/source/Utility/TildeExpressionResolver.cpp @@ -8,7 +8,7 @@ #include "lldb/Utility/TildeExpressionResolver.h" -#include <assert.h> +#include <cassert> #include <system_error> #include "llvm/ADT/STLExtras.h" @@ -27,7 +27,7 @@ using namespace llvm; namespace fs = llvm::sys::fs; namespace path = llvm::sys::path; -TildeExpressionResolver::~TildeExpressionResolver() {} +TildeExpressionResolver::~TildeExpressionResolver() = default; bool StandardTildeExpressionResolver::ResolveExact( StringRef Expr, SmallVectorImpl<char> &Output) { diff --git a/contrib/llvm-project/lldb/source/Utility/Timer.cpp b/contrib/llvm-project/lldb/source/Utility/Timer.cpp index 7ead51069529..b59ce3b9f556 100644 --- a/contrib/llvm-project/lldb/source/Utility/Timer.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Timer.cpp @@ -16,10 +16,10 @@ #include <utility> #include <vector> -#include <assert.h> -#include <inttypes.h> -#include <stdarg.h> -#include <stdio.h> +#include <cassert> +#include <cinttypes> +#include <cstdarg> +#include <cstdio> using namespace lldb_private; @@ -33,6 +33,8 @@ static std::atomic<Timer::Category *> g_categories; /// Allows llvm::Timer to emit signposts when supported. static llvm::ManagedStatic<llvm::SignpostEmitter> Signposts; +llvm::SignpostEmitter &lldb_private::GetSignposts() { return *Signposts; } + std::atomic<bool> Timer::g_quiet(true); std::atomic<unsigned> Timer::g_display_depth(0); static std::mutex &GetFileMutex() { @@ -59,7 +61,6 @@ void Timer::SetQuiet(bool value) { g_quiet = value; } Timer::Timer(Timer::Category &category, const char *format, ...) : m_category(category), m_total_start(std::chrono::steady_clock::now()) { - Signposts->startInterval(this, m_category.GetName()); TimerStack &stack = GetTimerStackForCurrentThread(); stack.push_back(this); @@ -86,8 +87,6 @@ Timer::~Timer() { auto total_dur = stop_time - m_total_start; auto timer_dur = total_dur - m_child_duration; - Signposts->endInterval(this, m_category.GetName()); - TimerStack &stack = GetTimerStackForCurrentThread(); if (g_quiet && stack.size() <= g_display_depth) { std::lock_guard<std::mutex> lock(GetFileMutex()); diff --git a/contrib/llvm-project/lldb/source/Utility/TraceGDBRemotePackets.cpp b/contrib/llvm-project/lldb/source/Utility/TraceGDBRemotePackets.cpp new file mode 100644 index 000000000000..5c1326a5f353 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Utility/TraceGDBRemotePackets.cpp @@ -0,0 +1,130 @@ +//===-- TraceGDBRemotePackets.cpp -------------------------------*- 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 +// +//===----------------------------------------------------------------------===// + +#include "lldb/Utility/TraceGDBRemotePackets.h" + +using namespace llvm; +using namespace llvm::json; + +namespace lldb_private { +/// jLLDBTraceSupported +/// \{ +bool fromJSON(const json::Value &value, TraceSupportedResponse &packet, + Path path) { + ObjectMapper o(value, path); + return o && o.map("description", packet.description) && + o.map("name", packet.name); +} + +json::Value toJSON(const TraceSupportedResponse &packet) { + return json::Value( + Object{{"description", packet.description}, {"name", packet.name}}); +} +/// \} + +/// jLLDBTraceStart +/// \{ +bool TraceStartRequest::IsProcessTracing() const { return !(bool)tids; } + +bool fromJSON(const json::Value &value, TraceStartRequest &packet, Path path) { + ObjectMapper o(value, path); + return o && o.map("type", packet.type) && o.map("tids", packet.tids); +} + +json::Value toJSON(const TraceStartRequest &packet) { + return json::Value(Object{{"tids", packet.tids}, {"type", packet.type}}); +} +/// \} + +/// jLLDBTraceStop +/// \{ +TraceStopRequest::TraceStopRequest(llvm::StringRef type, + const std::vector<lldb::tid_t> &tids_) + : type(type) { + tids.emplace(); + for (lldb::tid_t tid : tids_) + tids->push_back(static_cast<int64_t>(tid)); +} + +bool TraceStopRequest::IsProcessTracing() const { return !(bool)tids; } + +bool fromJSON(const json::Value &value, TraceStopRequest &packet, Path path) { + ObjectMapper o(value, path); + return o && o.map("type", packet.type) && o.map("tids", packet.tids); +} + +json::Value toJSON(const TraceStopRequest &packet) { + return json::Value(Object{{"type", packet.type}, {"tids", packet.tids}}); +} +/// \} + +/// jLLDBTraceGetState +/// \{ +bool fromJSON(const json::Value &value, TraceGetStateRequest &packet, + Path path) { + ObjectMapper o(value, path); + return o && o.map("type", packet.type); +} + +json::Value toJSON(const TraceGetStateRequest &packet) { + return json::Value(Object{{"type", packet.type}}); +} + +bool fromJSON(const json::Value &value, TraceBinaryData &packet, Path path) { + ObjectMapper o(value, path); + return o && o.map("kind", packet.kind) && o.map("size", packet.size); +} + +json::Value toJSON(const TraceBinaryData &packet) { + return json::Value(Object{{"kind", packet.kind}, {"size", packet.size}}); +} + +bool fromJSON(const json::Value &value, TraceThreadState &packet, Path path) { + ObjectMapper o(value, path); + return o && o.map("tid", packet.tid) && + o.map("binaryData", packet.binaryData); +} + +json::Value toJSON(const TraceThreadState &packet) { + return json::Value( + Object{{"tid", packet.tid}, {"binaryData", packet.binaryData}}); +} + +bool fromJSON(const json::Value &value, TraceGetStateResponse &packet, + Path path) { + ObjectMapper o(value, path); + return o && o.map("tracedThreads", packet.tracedThreads) && + o.map("processBinaryData", packet.processBinaryData); +} + +json::Value toJSON(const TraceGetStateResponse &packet) { + return json::Value(Object{{"tracedThreads", packet.tracedThreads}, + {"processBinaryData", packet.processBinaryData}}); +} +/// \} + +/// jLLDBTraceGetBinaryData +/// \{ +json::Value toJSON(const TraceGetBinaryDataRequest &packet) { + return json::Value(Object{{"type", packet.type}, + {"kind", packet.kind}, + {"offset", packet.offset}, + {"tid", packet.tid}, + {"size", packet.size}}); +} + +bool fromJSON(const json::Value &value, TraceGetBinaryDataRequest &packet, + Path path) { + ObjectMapper o(value, path); + return o && o.map("type", packet.type) && o.map("kind", packet.kind) && + o.map("tid", packet.tid) && o.map("offset", packet.offset) && + o.map("size", packet.size); +} +/// \} + +} // namespace lldb_private diff --git a/contrib/llvm-project/lldb/source/Utility/TraceIntelPTGDBRemotePackets.cpp b/contrib/llvm-project/lldb/source/Utility/TraceIntelPTGDBRemotePackets.cpp new file mode 100644 index 000000000000..dbb93d8d1c5c --- /dev/null +++ b/contrib/llvm-project/lldb/source/Utility/TraceIntelPTGDBRemotePackets.cpp @@ -0,0 +1,46 @@ +//===-- TraceIntelPTGDBRemotePackets.cpp ------------------------*- 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 +// +//===----------------------------------------------------------------------===// + +#include "lldb/Utility/TraceIntelPTGDBRemotePackets.h" + +using namespace llvm; +using namespace llvm::json; + +namespace lldb_private { + +bool fromJSON(const json::Value &value, TraceIntelPTStartRequest &packet, + Path path) { + ObjectMapper o(value, path); + if (!o || !fromJSON(value, (TraceStartRequest &)packet, path) || + !o.map("enableTsc", packet.enableTsc) || + !o.map("psbPeriod", packet.psbPeriod) || + !o.map("threadBufferSize", packet.threadBufferSize) || + !o.map("processBufferSizeLimit", packet.processBufferSizeLimit)) + return false; + if (packet.tids && packet.processBufferSizeLimit) { + path.report("processBufferSizeLimit must be provided"); + return false; + } + if (!packet.tids && !packet.processBufferSizeLimit) { + path.report("processBufferSizeLimit must not be provided"); + return false; + } + return true; +} + +json::Value toJSON(const TraceIntelPTStartRequest &packet) { + json::Value base = toJSON((const TraceStartRequest &)packet); + base.getAsObject()->try_emplace("threadBufferSize", packet.threadBufferSize); + base.getAsObject()->try_emplace("processBufferSizeLimit", + packet.processBufferSizeLimit); + base.getAsObject()->try_emplace("psbPeriod", packet.psbPeriod); + base.getAsObject()->try_emplace("enableTsc", packet.enableTsc); + return base; +} + +} // namespace lldb_private diff --git a/contrib/llvm-project/lldb/source/Utility/TraceOptions.cpp b/contrib/llvm-project/lldb/source/Utility/TraceOptions.cpp deleted file mode 100644 index 292fb600e6ed..000000000000 --- a/contrib/llvm-project/lldb/source/Utility/TraceOptions.cpp +++ /dev/null @@ -1,25 +0,0 @@ -//===-- TraceOptions.cpp ----------------------------------------*- 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 -// -//===----------------------------------------------------------------------===// - -#include "lldb/Utility/TraceOptions.h" - -using namespace lldb_private; - -namespace llvm { -namespace json { - -bool fromJSON(const Value &value, TraceTypeInfo &info, Path path) { - ObjectMapper o(value, path); - if (!o) - return false; - o.map("description", info.description); - return o.map("name", info.name); -} - -} // namespace json -} // namespace llvm diff --git a/contrib/llvm-project/lldb/source/Utility/UUID.cpp b/contrib/llvm-project/lldb/source/Utility/UUID.cpp index 73088fb22db8..0adeb06e4c04 100644 --- a/contrib/llvm-project/lldb/source/Utility/UUID.cpp +++ b/contrib/llvm-project/lldb/source/Utility/UUID.cpp @@ -12,9 +12,9 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/Format.h" -#include <ctype.h> -#include <stdio.h> -#include <string.h> +#include <cctype> +#include <cstdio> +#include <cstring> using namespace lldb_private; diff --git a/contrib/llvm-project/lldb/source/Utility/UriParser.cpp b/contrib/llvm-project/lldb/source/Utility/UriParser.cpp index 8169b0eee121..c6ed24985896 100644 --- a/contrib/llvm-project/lldb/source/Utility/UriParser.cpp +++ b/contrib/llvm-project/lldb/source/Utility/UriParser.cpp @@ -10,7 +10,7 @@ #include <string> -#include <stdint.h> +#include <cstdint> #include <tuple> using namespace lldb_private; diff --git a/contrib/llvm-project/lldb/source/Utility/UserID.cpp b/contrib/llvm-project/lldb/source/Utility/UserID.cpp index 8e0146b93498..5bae91a91288 100644 --- a/contrib/llvm-project/lldb/source/Utility/UserID.cpp +++ b/contrib/llvm-project/lldb/source/Utility/UserID.cpp @@ -9,7 +9,7 @@ #include "lldb/Utility/UserID.h" #include "lldb/Utility/Stream.h" -#include <inttypes.h> +#include <cinttypes> using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm-project/lldb/source/Utility/VASprintf.cpp b/contrib/llvm-project/lldb/source/Utility/VASprintf.cpp index aea68dfff9f1..5d361edf06e6 100644 --- a/contrib/llvm-project/lldb/source/Utility/VASprintf.cpp +++ b/contrib/llvm-project/lldb/source/Utility/VASprintf.cpp @@ -12,9 +12,9 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" -#include <assert.h> -#include <stdarg.h> -#include <stdio.h> +#include <cassert> +#include <cstdarg> +#include <cstdio> bool lldb_private::VASprintf(llvm::SmallVectorImpl<char> &buf, const char *fmt, va_list args) { diff --git a/contrib/llvm-project/lldb/source/Utility/VMRange.cpp b/contrib/llvm-project/lldb/source/Utility/VMRange.cpp index 16c50d6e81b8..184531b4bb27 100644 --- a/contrib/llvm-project/lldb/source/Utility/VMRange.cpp +++ b/contrib/llvm-project/lldb/source/Utility/VMRange.cpp @@ -15,8 +15,8 @@ #include <iterator> #include <vector> -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm-project/lldb/source/lldb.cpp b/contrib/llvm-project/lldb/source/lldb.cpp index 10fc2d7cf556..371902f6c1b5 100644 --- a/contrib/llvm-project/lldb/source/lldb.cpp +++ b/contrib/llvm-project/lldb/source/lldb.cpp @@ -6,14 +6,25 @@ // //===----------------------------------------------------------------------===// +#include "VCSVersion.inc" #include "lldb/lldb-private.h" +#include "clang/Basic/Version.h" using namespace lldb; using namespace lldb_private; -#include "clang/Basic/Version.h" +// LLDB_VERSION_STRING is set through a define so unlike the other defines +// expanded with CMake, it lacks the double quotes. +#define QUOTE(str) #str +#define EXPAND_AND_QUOTE(str) QUOTE(str) -#include "VCSVersion.inc" +static const char *GetLLDBVersion() { +#ifdef LLDB_VERSION_STRING + return EXPAND_AND_QUOTE(LLDB_VERSION_STRING); +#else + return "lldb version " CLANG_VERSION_STRING; +#endif +} static const char *GetLLDBRevision() { #ifdef LLDB_REVISION @@ -34,11 +45,10 @@ static const char *GetLLDBRepository() { const char *lldb_private::GetVersion() { static std::string g_version_str; if (g_version_str.empty()) { - g_version_str += "lldb version "; - g_version_str += CLANG_VERSION_STRING; - + const char *lldb_version = GetLLDBVersion(); const char *lldb_repo = GetLLDBRepository(); const char *lldb_rev = GetLLDBRevision(); + g_version_str += lldb_version; if (lldb_repo || lldb_rev) { g_version_str += " ("; if (lldb_repo) diff --git a/contrib/llvm-project/lldb/tools/driver/Driver.cpp b/contrib/llvm-project/lldb/tools/driver/Driver.cpp index 210a712f9741..a6a4a2a1b80b 100644 --- a/contrib/llvm-project/lldb/tools/driver/Driver.cpp +++ b/contrib/llvm-project/lldb/tools/driver/Driver.cpp @@ -31,16 +31,17 @@ #include <algorithm> #include <atomic> #include <bitset> +#include <clocale> #include <csignal> #include <string> #include <thread> #include <utility> +#include <climits> +#include <cstdio> +#include <cstdlib> +#include <cstring> #include <fcntl.h> -#include <limits.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> // Includes for pipe() #if defined(_WIN32) @@ -740,7 +741,7 @@ void reproducer_handler(void *finalize_cmd) { static void printHelp(LLDBOptTable &table, llvm::StringRef tool_name) { std::string usage_str = tool_name.str() + " [options]"; - table.PrintHelp(llvm::outs(), usage_str.c_str(), "LLDB", false); + table.printHelp(llvm::outs(), usage_str.c_str(), "LLDB", false); std::string examples = R"___( EXAMPLES: @@ -784,8 +785,8 @@ EXAMPLES: llvm::outs() << examples << '\n'; } -llvm::Optional<int> InitializeReproducer(llvm::StringRef argv0, - opt::InputArgList &input_args) { +static llvm::Optional<int> InitializeReproducer(llvm::StringRef argv0, + opt::InputArgList &input_args) { if (auto *finalize_path = input_args.getLastArg(OPT_reproducer_finalize)) { if (const char *error = SBReproducer::Finalize(finalize_path->getValue())) { WithColor::error() << "reproducer finalization failed: " << error << '\n'; @@ -853,8 +854,7 @@ llvm::Optional<int> InitializeReproducer(llvm::StringRef argv0, // Register the reproducer signal handler. if (!input_args.hasArg(OPT_no_generate_on_signal)) { if (const char *reproducer_path = SBReproducer::GetPath()) { - // Leaking the string on purpose. - std::string *finalize_cmd = new std::string(argv0); + static std::string *finalize_cmd = new std::string(argv0); finalize_cmd->append(" --reproducer-finalize '"); finalize_cmd->append(reproducer_path); finalize_cmd->append("'"); @@ -868,6 +868,10 @@ llvm::Optional<int> InitializeReproducer(llvm::StringRef argv0, } int main(int argc, char const *argv[]) { + // Editline uses for example iswprint which is dependent on LC_CTYPE. + std::setlocale(LC_ALL, ""); + std::setlocale(LC_CTYPE, ""); + // Setup LLVM signal handlers and make sure we call llvm_shutdown() on // destruction. llvm::InitLLVM IL(argc, argv, /*InstallPipeSignalExitHandler=*/false); diff --git a/contrib/llvm-project/lldb/tools/driver/Platform.cpp b/contrib/llvm-project/lldb/tools/driver/Platform.cpp index f3a71eb79dec..0891cfa1fa8d 100644 --- a/contrib/llvm-project/lldb/tools/driver/Platform.cpp +++ b/contrib/llvm-project/lldb/tools/driver/Platform.cpp @@ -9,9 +9,9 @@ // this file is only relevant for Visual C++ #if defined(_WIN32) -#include <assert.h> +#include <cassert> +#include <cstdlib> #include <process.h> -#include <stdlib.h> #include "Platform.h" #include "llvm/Support/ErrorHandling.h" diff --git a/contrib/llvm-project/lldb/tools/driver/Platform.h b/contrib/llvm-project/lldb/tools/driver/Platform.h index 6b893f91f442..d7573b75bf32 100644 --- a/contrib/llvm-project/lldb/tools/driver/Platform.h +++ b/contrib/llvm-project/lldb/tools/driver/Platform.h @@ -15,13 +15,13 @@ #include <io.h> #if defined(_MSC_VER) -#include <signal.h> +#include <csignal> #endif #if HAVE_SYS_TYPES_H #include <sys/types.h> #endif #include "lldb/Host/windows/windows.h" -#include <inttypes.h> +#include <cinttypes> struct winsize { long ws_col; @@ -76,7 +76,7 @@ extern int tcsetattr(int fd, int optional_actions, extern int tcgetattr(int fildes, struct termios *termios_p); #else -#include <inttypes.h> +#include <cinttypes> #include <libgen.h> #include <sys/ioctl.h> diff --git a/contrib/llvm-project/lldb/tools/lldb-instr/Instrument.cpp b/contrib/llvm-project/lldb/tools/lldb-instr/Instrument.cpp index 8ec01304891b..8fbc3e64833c 100644 --- a/contrib/llvm-project/lldb/tools/lldb-instr/Instrument.cpp +++ b/contrib/llvm-project/lldb/tools/lldb-instr/Instrument.cpp @@ -342,9 +342,15 @@ private: }; int main(int argc, const char **argv) { - CommonOptionsParser OP(argc, argv, InstrCategory, - "Utility for generating the macros for LLDB's " - "instrumentation framework."); + auto ExpectedParser = CommonOptionsParser::create( + argc, argv, InstrCategory, llvm::cl::OneOrMore, + "Utility for generating the macros for LLDB's " + "instrumentation framework."); + if (!ExpectedParser) { + llvm::errs() << ExpectedParser.takeError(); + return 1; + } + CommonOptionsParser &OP = ExpectedParser.get(); auto PCHOpts = std::make_shared<PCHContainerOperations>(); PCHOpts->registerWriter(std::make_unique<ObjectFilePCHContainerWriter>()); diff --git a/contrib/llvm-project/lldb/tools/lldb-server/LLDBServerUtilities.cpp b/contrib/llvm-project/lldb/tools/lldb-server/LLDBServerUtilities.cpp index 7f9271e36b68..a427af4800f7 100644 --- a/contrib/llvm-project/lldb/tools/lldb-server/LLDBServerUtilities.cpp +++ b/contrib/llvm-project/lldb/tools/lldb-server/LLDBServerUtilities.cpp @@ -24,7 +24,7 @@ static std::shared_ptr<raw_ostream> GetLogStream(StringRef log_file) { if (!log_file.empty()) { std::error_code EC; std::shared_ptr<raw_ostream> stream_sp = std::make_shared<raw_fd_ostream>( - log_file, EC, sys::fs::OF_Text | sys::fs::OF_Append); + log_file, EC, sys::fs::OF_TextWithCRLF | sys::fs::OF_Append); if (!EC) return stream_sp; errs() << llvm::formatv( diff --git a/contrib/llvm-project/lldb/tools/lldb-server/SystemInitializerLLGS.h b/contrib/llvm-project/lldb/tools/lldb-server/SystemInitializerLLGS.h index f3d015e94f8c..4469a8ba5f60 100644 --- a/contrib/llvm-project/lldb/tools/lldb-server/SystemInitializerLLGS.h +++ b/contrib/llvm-project/lldb/tools/lldb-server/SystemInitializerLLGS.h @@ -14,6 +14,8 @@ class SystemInitializerLLGS : public lldb_private::SystemInitializerCommon { public: + SystemInitializerLLGS() : SystemInitializerCommon(nullptr) {} + llvm::Error Initialize() override; void Terminate() override; }; diff --git a/contrib/llvm-project/lldb/tools/lldb-server/lldb-gdbserver.cpp b/contrib/llvm-project/lldb/tools/lldb-server/lldb-gdbserver.cpp index a9db73f90098..888ba728fa91 100644 --- a/contrib/llvm-project/lldb/tools/lldb-server/lldb-gdbserver.cpp +++ b/contrib/llvm-project/lldb/tools/lldb-server/lldb-gdbserver.cpp @@ -6,14 +6,14 @@ // //===----------------------------------------------------------------------===// -#include <errno.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> +#include <cerrno> +#include <cstdint> +#include <cstdio> +#include <cstdlib> +#include <cstring> #ifndef _WIN32 -#include <signal.h> +#include <csignal> #include <unistd.h> #endif @@ -356,7 +356,7 @@ public: void PrintHelp(llvm::StringRef Name) { std::string Usage = (Name + " [options] [[host]:port] [[--] program args...]").str(); - OptTable::PrintHelp(llvm::outs(), Usage.c_str(), "lldb-server"); + OptTable::printHelp(llvm::outs(), Usage.c_str(), "lldb-server"); llvm::outs() << R"( DESCRIPTION lldb-server connects to the LLDB client, which drives the debugging session. diff --git a/contrib/llvm-project/lldb/tools/lldb-server/lldb-platform.cpp b/contrib/llvm-project/lldb/tools/lldb-server/lldb-platform.cpp index a5d4ecfa3f29..d4b54362bb46 100644 --- a/contrib/llvm-project/lldb/tools/lldb-server/lldb-platform.cpp +++ b/contrib/llvm-project/lldb/tools/lldb-server/lldb-platform.cpp @@ -6,15 +6,15 @@ // //===----------------------------------------------------------------------===// -#include <errno.h> +#include <cerrno> #if defined(__APPLE__) #include <netinet/in.h> #endif -#include <signal.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> +#include <csignal> +#include <cstdint> +#include <cstdio> +#include <cstdlib> +#include <cstring> #if !defined(_WIN32) #include <sys/wait.h> #endif @@ -22,6 +22,7 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/FileUtilities.h" +#include "llvm/Support/WithColor.h" #include "llvm/Support/raw_ostream.h" #include "Acceptor.h" @@ -202,14 +203,15 @@ int main_platform(int argc, char *argv[]) { case 'p': { if (!llvm::to_integer(optarg, port_offset)) { - llvm::errs() << "error: invalid port offset string " << optarg << "\n"; + WithColor::error() << "invalid port offset string " << optarg << "\n"; option_error = 4; break; } if (port_offset < LOW_PORT || port_offset > HIGH_PORT) { - llvm::errs() << llvm::formatv("error: port offset {0} is not in the " - "valid user port range of {1} - {2}\n", - port_offset, LOW_PORT, HIGH_PORT); + WithColor::error() << llvm::formatv( + "port offset {0} is not in the " + "valid user port range of {1} - {2}\n", + port_offset, LOW_PORT, HIGH_PORT); option_error = 5; } } break; @@ -219,14 +221,15 @@ int main_platform(int argc, char *argv[]) { case 'M': { uint16_t portnum; if (!llvm::to_integer(optarg, portnum)) { - llvm::errs() << "error: invalid port number string " << optarg << "\n"; + WithColor::error() << "invalid port number string " << optarg << "\n"; option_error = 2; break; } if (portnum < LOW_PORT || portnum > HIGH_PORT) { - llvm::errs() << llvm::formatv("error: port number {0} is not in the " - "valid user port range of {1} - {2}\n", - portnum, LOW_PORT, HIGH_PORT); + WithColor::error() << llvm::formatv( + "port number {0} is not in the " + "valid user port range of {1} - {2}\n", + portnum, LOW_PORT, HIGH_PORT); option_error = 1; break; } @@ -253,9 +256,10 @@ int main_platform(int argc, char *argv[]) { gdbserver_portmap = GDBRemoteCommunicationServerPlatform::PortMap( min_gdbserver_port, max_gdbserver_port); } else if (min_gdbserver_port || max_gdbserver_port) { - fprintf(stderr, "error: --min-gdbserver-port (%u) is not lower than " - "--max-gdbserver-port (%u)\n", - min_gdbserver_port, max_gdbserver_port); + WithColor::error() << llvm::formatv( + "--min-gdbserver-port ({0}) is not lower than " + "--max-gdbserver-port ({1})\n", + min_gdbserver_port, max_gdbserver_port); option_error = 3; } @@ -317,7 +321,7 @@ int main_platform(int argc, char *argv[]) { Connection *conn = nullptr; error = acceptor_up->Accept(children_inherit_accept_socket, conn); if (error.Fail()) { - printf("error: %s\n", error.AsCString()); + WithColor::error() << error.AsCString() << '\n'; exit(socket_error); } printf("Connection established.\n"); @@ -372,10 +376,10 @@ int main_platform(int argc, char *argv[]) { } if (error.Fail()) { - fprintf(stderr, "error: %s\n", error.AsCString()); + WithColor::error() << error.AsCString() << '\n'; } } else { - fprintf(stderr, "error: handshake with client failed\n"); + WithColor::error() << "handshake with client failed\n"; } } } while (g_server); diff --git a/contrib/llvm-project/lldb/tools/lldb-server/lldb-server.cpp b/contrib/llvm-project/lldb/tools/lldb-server/lldb-server.cpp index 749a381ebca0..1e001ac7185b 100644 --- a/contrib/llvm-project/lldb/tools/lldb-server/lldb-server.cpp +++ b/contrib/llvm-project/lldb/tools/lldb-server/lldb-server.cpp @@ -17,8 +17,8 @@ #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Signals.h" -#include <stdio.h> -#include <stdlib.h> +#include <cstdio> +#include <cstdlib> static llvm::ManagedStatic<lldb_private::SystemLifetimeManager> g_debugger_lifetime; @@ -50,8 +50,6 @@ static void terminate_debugger() { g_debugger_lifetime->Terminate(); } // main int main(int argc, char *argv[]) { llvm::InitLLVM IL(argc, argv, /*InstallPipeSignalExitHandler=*/false); - llvm::StringRef ToolName = argv[0]; - llvm::sys::PrintStackTraceOnErrorSignal(ToolName); llvm::PrettyStackTraceProgram X(argc, argv); int option_error = 0; |