diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2022-07-04 19:20:19 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-02-08 19:02:26 +0000 |
commit | 81ad626541db97eb356e2c1d4a20eb2a26a766ab (patch) | |
tree | 311b6a8987c32b1e1dcbab65c54cfac3fdb56175 /contrib/llvm-project/lldb | |
parent | 5fff09660e06a66bed6482da9c70df328e16bbb6 (diff) | |
parent | 145449b1e420787bb99721a429341fa6be3adfb6 (diff) |
Diffstat (limited to 'contrib/llvm-project/lldb')
685 files changed, 17483 insertions, 10286 deletions
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBCommandInterpreter.i b/contrib/llvm-project/lldb/bindings/interface/SBCommandInterpreter.i index b9a32716cfd6..cad79248d0a2 100644 --- a/contrib/llvm-project/lldb/bindings/interface/SBCommandInterpreter.i +++ b/contrib/llvm-project/lldb/bindings/interface/SBCommandInterpreter.i @@ -125,6 +125,9 @@ public: bool HasAliasOptions (); + bool + IsInteractive (); + lldb::SBProcess GetProcess (); diff --git a/contrib/llvm-project/lldb/bindings/interface/SBCompileUnit.i b/contrib/llvm-project/lldb/bindings/interface/SBCompileUnit.i index 4c8efaedb7dc..5a03069b4e04 100644 --- a/contrib/llvm-project/lldb/bindings/interface/SBCompileUnit.i +++ b/contrib/llvm-project/lldb/bindings/interface/SBCompileUnit.i @@ -67,6 +67,22 @@ public: lldb::SBLineEntry GetLineEntryAtIndex (uint32_t idx) const; + %feature("docstring", " + Get the index for a provided line entry in this compile unit. + + @param[in] line_entry + The SBLineEntry object for which we are looking for the index. + + @param[in] exact + An optional boolean defaulting to false that ensures that the provided + line entry has a perfect match in the compile unit. + + @return + The index of the user-provided line entry. UINT32_MAX if the line entry + was not found in the compile unit.") FindLineEntryIndex; + uint32_t + FindLineEntryIndex (lldb::SBLineEntry &line_entry, bool exact = false) const; + uint32_t FindLineEntryIndex (uint32_t start_idx, uint32_t line, diff --git a/contrib/llvm-project/lldb/bindings/interface/SBDebugger.i b/contrib/llvm-project/lldb/bindings/interface/SBDebugger.i index f21e60d62873..5d51a6ac20d2 100644 --- a/contrib/llvm-project/lldb/bindings/interface/SBDebugger.i +++ b/contrib/llvm-project/lldb/bindings/interface/SBDebugger.i @@ -117,6 +117,23 @@ or the equivalent arguments for :py:class:`SBTarget.AttachToProcessWithID` .") S class SBDebugger { public: + enum + { + eBroadcastBitProgress = (1 << 0), + eBroadcastBitWarning = (1 << 1), + eBroadcastBitError = (1 << 2), + }; + + + static const char *GetProgressFromEvent(const lldb::SBEvent &event, + uint64_t &OUTPUT, + uint64_t &OUTPUT, + uint64_t &OUTPUT, + bool &OUTPUT); + + static lldb::SBStructuredData GetDiagnosticFromEvent(const lldb::SBEvent &event); + + SBBroadcaster GetBroadcaster(); static void Initialize(); @@ -124,6 +141,8 @@ public: static SBError InitializeWithErrorHandling(); + static void PrintStackTraceOnError(); + static void Terminate(); @@ -523,6 +542,8 @@ Example: :: lldb::SBError RunREPL (lldb::LanguageType language, const char *repl_options); + SBTrace LoadTraceFromFile(SBError &error, const SBFileSpec &trace_description_file); + #ifdef SWIGPYTHON %pythoncode%{ def __iter__(self): diff --git a/contrib/llvm-project/lldb/bindings/interface/SBProcess.i b/contrib/llvm-project/lldb/bindings/interface/SBProcess.i index 14566a2942d0..7a9f8fc5757c 100644 --- a/contrib/llvm-project/lldb/bindings/interface/SBProcess.i +++ b/contrib/llvm-project/lldb/bindings/interface/SBProcess.i @@ -398,6 +398,9 @@ public: IsInstrumentationRuntimePresent(lldb::InstrumentationRuntimeType type); lldb::SBError + SaveCore(const char *file_name, const char *flavor, lldb::SaveCoreStyle core_style); + + lldb::SBError SaveCore(const char *file_name); lldb::SBError diff --git a/contrib/llvm-project/lldb/bindings/interface/SBTarget.i b/contrib/llvm-project/lldb/bindings/interface/SBTarget.i index b98aa70849be..a6a764944d02 100644 --- a/contrib/llvm-project/lldb/bindings/interface/SBTarget.i +++ b/contrib/llvm-project/lldb/bindings/interface/SBTarget.i @@ -394,6 +394,9 @@ public: const char * GetTriple (); + const char * + GetABIName(); + %feature("docstring", " Architecture data byte width accessor diff --git a/contrib/llvm-project/lldb/bindings/interface/SBType.i b/contrib/llvm-project/lldb/bindings/interface/SBType.i index d6e8db3ab428..8db2fa749634 100644 --- a/contrib/llvm-project/lldb/bindings/interface/SBType.i +++ b/contrib/llvm-project/lldb/bindings/interface/SBType.i @@ -355,6 +355,18 @@ public: IsScopedEnumerationType (); %feature("docstring", + "Returns true if this type is an aggregate type. + + Language-specific behaviour: + + * C: Returns true for struct values, arrays, and vectors. + * C++: Same a C. Also includes class instances. + * Objective-C: Same as C. Also includes class instances. + ") IsAggregateType; + bool + IsAggregateType (); + + %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 diff --git a/contrib/llvm-project/lldb/bindings/macros.swig b/contrib/llvm-project/lldb/bindings/macros.swig index 6793a11c5bd9..84f244245738 100644 --- a/contrib/llvm-project/lldb/bindings/macros.swig +++ b/contrib/llvm-project/lldb/bindings/macros.swig @@ -1,6 +1,6 @@ %define STRING_EXTENSION_LEVEL(Class, Level) %extend { - std::string lldb:: ## Class ## ::__str__(){ + std::string lldb:: ## Class ## ::__repr__(){ lldb::SBStream stream; $self->GetDescription (stream, Level); const char *desc = stream.GetData(); @@ -15,7 +15,7 @@ %define STRING_EXTENSION(Class) %extend { - std::string lldb:: ## Class ## ::__str__(){ + std::string lldb:: ## Class ## ::__repr__(){ lldb::SBStream stream; $self->GetDescription (stream); const char *desc = stream.GetData(); diff --git a/contrib/llvm-project/lldb/bindings/python/createPythonInit.py b/contrib/llvm-project/lldb/bindings/python/createPythonInit.py index 3deb9159b702..4ad7320675f4 100644 --- a/contrib/llvm-project/lldb/bindings/python/createPythonInit.py +++ b/contrib/llvm-project/lldb/bindings/python/createPythonInit.py @@ -10,6 +10,14 @@ importNames = ', '.join('"{}"'.format(getFileName(f)) for f in pkgFiles) script = """__all__ = [{import_names}] for x in __all__: __import__('lldb.{pkg_name}.' + x) + +def __lldb_init_module(debugger, internal_dict): + import lldb + for x in __all__: + submodule = getattr(lldb.{pkg_name}, x) + lldb_init = getattr(submodule, '__lldb_init_module', None) + if lldb_init: + lldb_init(debugger, internal_dict) """.format(import_names=importNames, pkg_name=pkgRelDir.replace("/", ".")) pkgIniFile = os.path.normpath(os.path.join(pkgRelDir, "__init__.py")) diff --git a/contrib/llvm-project/lldb/bindings/python/python-extensions.swig b/contrib/llvm-project/lldb/bindings/python/python-extensions.swig index b98b0d458f0c..cb841af070ad 100644 --- a/contrib/llvm-project/lldb/bindings/python/python-extensions.swig +++ b/contrib/llvm-project/lldb/bindings/python/python-extensions.swig @@ -565,6 +565,7 @@ def is_numeric_type(basic_type): if basic_type == eBasicTypeUnsignedWChar: return (True,False) if basic_type == eBasicTypeChar16: return (True,False) if basic_type == eBasicTypeChar32: return (True,False) + if basic_type == eBasicTypeChar8: return (True,False) if basic_type == eBasicTypeShort: return (True,True) if basic_type == eBasicTypeUnsignedShort: return (True,False) if basic_type == eBasicTypeInt: return (True,True) diff --git a/contrib/llvm-project/lldb/docs/python_api_enums.rst b/contrib/llvm-project/lldb/docs/python_api_enums.rst index 58100b2aa9a2..6ae73df68c8a 100644 --- a/contrib/llvm-project/lldb/docs/python_api_enums.rst +++ b/contrib/llvm-project/lldb/docs/python_api_enums.rst @@ -1019,6 +1019,7 @@ BasicType .. py:data:: eBasicTypeUnsignedWChar .. py:data:: eBasicTypeChar16 .. py:data:: eBasicTypeChar32 +.. py:data:: eBasicTypeChar8 .. py:data:: eBasicTypeShort .. py:data:: eBasicTypeUnsignedShort .. py:data:: eBasicTypeInt diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBCommandInterpreter.h b/contrib/llvm-project/lldb/include/lldb/API/SBCommandInterpreter.h index 2364a8dae88c..0d344fc7fbcb 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBCommandInterpreter.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBCommandInterpreter.h @@ -59,6 +59,8 @@ public: bool HasAliasOptions(); + bool IsInteractive(); + lldb::SBProcess GetProcess(); lldb::SBDebugger GetDebugger(); @@ -145,6 +147,8 @@ public: const char *help, const char *syntax, const char *auto_repeat_command); + void SourceInitFileInGlobalDirectory(lldb::SBCommandReturnObject &result); + void SourceInitFileInHomeDirectory(lldb::SBCommandReturnObject &result); void SourceInitFileInHomeDirectory(lldb::SBCommandReturnObject &result, bool is_repl); diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBCompileUnit.h b/contrib/llvm-project/lldb/include/lldb/API/SBCompileUnit.h index d965b9d966b9..36492d9398ce 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBCompileUnit.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBCompileUnit.h @@ -34,6 +34,9 @@ public: lldb::SBLineEntry GetLineEntryAtIndex(uint32_t idx) const; + uint32_t FindLineEntryIndex(lldb::SBLineEntry &line_entry, + bool exact = false) const; + uint32_t FindLineEntryIndex(uint32_t start_idx, uint32_t line, lldb::SBFileSpec *inline_file_spec) const; diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBDebugger.h b/contrib/llvm-project/lldb/include/lldb/API/SBDebugger.h index a82c147053eb..b9a9b593d0ad 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBDebugger.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBDebugger.h @@ -33,7 +33,11 @@ public: class LLDB_API SBDebugger { public: - FLAGS_ANONYMOUS_ENUM(){eBroadcastBitProgress = (1 << 0)}; + FLAGS_ANONYMOUS_ENUM(){ + eBroadcastBitProgress = (1 << 0), + eBroadcastBitWarning = (1 << 1), + eBroadcastBitError = (1 << 2), + }; SBDebugger(); @@ -79,12 +83,17 @@ public: uint64_t &completed, uint64_t &total, bool &is_debugger_specific); + static lldb::SBStructuredData + GetDiagnosticFromEvent(const lldb::SBEvent &event); + lldb::SBDebugger &operator=(const lldb::SBDebugger &rhs); static void Initialize(); static lldb::SBError InitializeWithErrorHandling(); + static void PrintStackTraceOnError(); + static void Terminate(); // Deprecated, use the one that takes a source_init_files bool. @@ -382,6 +391,17 @@ public: SBError RunREPL(lldb::LanguageType language, const char *repl_options); + /// Load a trace from a trace description file and create Targets, + /// Processes and Threads based on the contents of such file. + /// + /// \param[out] error + /// An error if the trace could not be created. + /// + /// \param[in] trace_description_file + /// The file containing the necessary information to load the trace. + SBTrace LoadTraceFromFile(SBError &error, + const SBFileSpec &trace_description_file); + private: friend class SBCommandInterpreter; friend class SBInputReader; @@ -389,6 +409,7 @@ private: friend class SBProcess; friend class SBSourceManager; friend class SBTarget; + friend class SBTrace; lldb::SBTarget FindTargetWithLLDBProcess(const lldb::ProcessSP &processSP); diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBFileSpec.h b/contrib/llvm-project/lldb/include/lldb/API/SBFileSpec.h index a2f02ac78208..a286912f109e 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBFileSpec.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBFileSpec.h @@ -74,6 +74,7 @@ private: friend class SBSourceManager; friend class SBTarget; friend class SBThread; + friend class SBTrace; SBFileSpec(const lldb_private::FileSpec &fspec); diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBProcess.h b/contrib/llvm-project/lldb/include/lldb/API/SBProcess.h index 73a8d918f4d6..49b3256869ed 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBProcess.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBProcess.h @@ -337,7 +337,21 @@ public: bool IsInstrumentationRuntimePresent(InstrumentationRuntimeType type); - /// Save the state of the process in a core file (or mini dump on Windows). + /// Save the state of the process in a core file. + /// + /// \param[in] file_name - The name of the file to save the core file to. + /// + /// \param[in] flavor - Specify the flavor of a core file plug-in to save. + /// Currently supported flavors include "mach-o" and "minidump" + /// + /// \param[in] core_style - Specify the style of a core file to save. + lldb::SBError SaveCore(const char *file_name, const char *flavor, + SaveCoreStyle core_style); + + /// Save the state of the process with the a flavor that matches the + /// current process' main executable (if supported). + /// + /// \param[in] file_name - The name of the file to save the core file to. lldb::SBError SaveCore(const char *file_name); /// Query the address load_addr and store the details of the memory diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBTarget.h b/contrib/llvm-project/lldb/include/lldb/API/SBTarget.h index abd9ebf07407..018acfd595ad 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBTarget.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBTarget.h @@ -321,6 +321,8 @@ public: uint32_t GetAddressByteSize(); const char *GetTriple(); + + const char *GetABIName(); /// Architecture data byte width accessor /// diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBTrace.h b/contrib/llvm-project/lldb/include/lldb/API/SBTrace.h index 1685caaf4efa..d5cf30f56637 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBTrace.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBTrace.h @@ -12,8 +12,6 @@ #include "lldb/API/SBDefines.h" #include "lldb/API/SBError.h" -class TraceImpl; - namespace lldb { class LLDB_API SBTrace { @@ -23,6 +21,10 @@ public: SBTrace(const lldb::TraceSP &trace_sp); + /// See SBDebugger::LoadTraceFromFile. + static SBTrace LoadTraceFromFile(SBError &error, SBDebugger &debugger, + const SBFileSpec &trace_description_file); + /// \return /// A description of the parameters to use for the \a SBTrace::Start /// method, or \b null if the object is invalid. diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBType.h b/contrib/llvm-project/lldb/include/lldb/API/SBType.h index 529b4d0eeffc..244d328b51f4 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBType.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBType.h @@ -133,6 +133,8 @@ public: bool IsScopedEnumerationType(); + bool IsAggregateType(); + lldb::SBType GetPointerType(); lldb::SBType GetPointeeType(); diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/Breakpoint.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/Breakpoint.h index 113f8c4905e1..39c6d0b7f3a7 100644 --- a/contrib/llvm-project/lldb/include/lldb/Breakpoint/Breakpoint.h +++ b/contrib/llvm-project/lldb/include/lldb/Breakpoint/Breakpoint.h @@ -81,6 +81,8 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>, public Stoppoint { public: static ConstString GetEventIdentifier(); + static const char * + BreakpointEventTypeAsCString(lldb::BreakpointEventType type); /// An enum specifying the match style for breakpoint settings. At present /// only used for function name style breakpoints. @@ -105,12 +107,14 @@ public: ~BreakpointEventData() override; static ConstString GetFlavorString(); + + Log *GetLogChannel() override; ConstString GetFlavor() const override; lldb::BreakpointEventType GetBreakpointEventType() const; - lldb::BreakpointSP &GetBreakpoint(); + lldb::BreakpointSP GetBreakpoint() const; BreakpointLocationCollection &GetBreakpointLocationCollection() { return m_locations; diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointOptions.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointOptions.h index c2456024d919..7bf545717422 100644 --- a/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointOptions.h +++ b/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointOptions.h @@ -43,7 +43,7 @@ public: | eCondition | eAutoContinue) }; struct CommandData { - CommandData() {} + CommandData() = default; CommandData(const StringList &user_source, lldb::ScriptLanguage interp) : user_source(user_source), interpreter(interp), stop_on_error(true) {} diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/WatchpointOptions.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/WatchpointOptions.h index c5ad90c334c4..369120e98534 100644 --- a/contrib/llvm-project/lldb/include/lldb/Breakpoint/WatchpointOptions.h +++ b/contrib/llvm-project/lldb/include/lldb/Breakpoint/WatchpointOptions.h @@ -166,7 +166,7 @@ public: lldb::user_id_t watch_id); struct CommandData { - CommandData() {} + CommandData() = default; ~CommandData() = default; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Address.h b/contrib/llvm-project/lldb/include/lldb/Core/Address.h index f77ffc2fd25e..b19e69442754 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/Address.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/Address.h @@ -116,7 +116,7 @@ public: /// /// Initialize with a invalid section (NULL) and an invalid offset /// (LLDB_INVALID_ADDRESS). - Address() {} + Address() = default; /// Copy constructor /// @@ -229,6 +229,14 @@ public: /// \param[in] fallback_style /// The display style for the address. /// + /// \param[in] addr_byte_size + /// The address byte size for the address. + /// + /// \param[in] all_ranges + /// If true, dump all valid ranges and value ranges for the variable that + /// contains the address, otherwise dumping the range that contains the + /// address. + /// /// \return /// Returns \b true if the address was able to be displayed. /// File and load addresses may be unresolved and it may not be @@ -238,7 +246,8 @@ public: /// \see Address::DumpStyle bool Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style = DumpStyleInvalid, - uint32_t addr_byte_size = UINT32_MAX) const; + uint32_t addr_byte_size = UINT32_MAX, + bool all_ranges = false) const; AddressClass GetAddressClass() const; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Communication.h b/contrib/llvm-project/lldb/include/lldb/Core/Communication.h index fdcb6c5fb982..44b3a16a0526 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/Communication.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/Communication.h @@ -277,7 +277,7 @@ public: /// \b True if the read thread is running, \b false otherwise. bool ReadThreadIsRunning(); - /// The static read thread function. This function will call the "DoRead" + /// The read thread function. This function will call the "DoRead" /// function continuously and wait for data to become available. When data /// is received it will append the available data to the internal cache and /// broadcast a \b eBroadcastBitReadThreadGotBytes event. @@ -289,7 +289,7 @@ public: /// \b NULL. /// /// \see void Communication::ReadThreadGotBytes (const uint8_t *, size_t); - static lldb::thread_result_t ReadThread(lldb::thread_arg_t comm_ptr); + lldb::thread_result_t ReadThread(); void SetReadThreadBytesReceivedCallback(ReadThreadBytesReceived callback, void *callback_baton); diff --git a/contrib/llvm-project/lldb/include/lldb/Core/DataFileCache.h b/contrib/llvm-project/lldb/include/lldb/Core/DataFileCache.h index 3016c531f674..2dc69f6ce6b0 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/DataFileCache.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/DataFileCache.h @@ -13,6 +13,7 @@ #include "lldb/Utility/Status.h" #include "lldb/Utility/UUID.h" #include "lldb/lldb-forward.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/Support/Caching.h" #include <mutex> @@ -118,22 +119,22 @@ struct CacheSignature { m_obj_mod_time = llvm::None; } - /// Return true if any of the signature member variables have valid values. - bool IsValid() const { - return m_uuid.hasValue() || m_mod_time.hasValue() || - m_obj_mod_time.hasValue(); - } + /// Return true only if the CacheSignature is valid. + /// + /// Cache signatures are considered valid only if there is a UUID in the file + /// that can uniquely identify the file. Some build systems play with + /// modification times of file so we can not trust them without using valid + /// unique idenifier like the UUID being valid. + bool IsValid() const { return m_uuid.has_value(); } /// Check if two signatures are the same. - bool operator!=(const CacheSignature &rhs) { - if (m_uuid != rhs.m_uuid) - return true; - if (m_mod_time != rhs.m_mod_time) - return true; - if (m_obj_mod_time != rhs.m_obj_mod_time) - return true; - return false; + bool operator==(const CacheSignature &rhs) const { + return m_uuid == rhs.m_uuid && m_mod_time == rhs.m_mod_time && + m_obj_mod_time == rhs.m_obj_mod_time; } + + /// Check if two signatures differ. + bool operator!=(const CacheSignature &rhs) const { return !(*this == rhs); } /// Encode this object into a data encoder object. /// /// This allows this object to be serialized to disk. The CacheSignature @@ -148,7 +149,7 @@ struct CacheSignature { /// True if a signature was encoded, and false if there were no member /// variables that had value. False indicates this data should not be /// cached to disk because we were unable to encode a valid signature. - bool Encode(DataEncoder &encoder); + bool Encode(DataEncoder &encoder) const; /// Decode a serialized version of this object from data. /// @@ -190,7 +191,7 @@ public: private: std::vector<ConstString> m_strings; - std::map<ConstString, uint32_t> m_string_to_offset; + llvm::DenseMap<ConstString, uint32_t> m_string_to_offset; /// Skip one byte to start the string table off with an empty string. uint32_t m_next_offset = 1; }; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Debugger.h b/contrib/llvm-project/lldb/include/lldb/Core/Debugger.h index f9a1f1eea54f..031c9a9674d7 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/Debugger.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/Debugger.h @@ -14,6 +14,7 @@ #include <memory> #include <vector> +#include "lldb/Core/DebuggerEvents.h" #include "lldb/Core/FormatEntity.h" #include "lldb/Core/IOHandler.h" #include "lldb/Core/SourceManager.h" @@ -48,11 +49,14 @@ namespace llvm { class raw_ostream; +class ThreadPool; } namespace lldb_private { class Address; +class CallbackLogHandler; class CommandInterpreter; +class LogHandler; class Process; class Stream; class SymbolContext; @@ -76,6 +80,8 @@ public: /// Broadcaster event bits definitions. enum { eBroadcastBitProgress = (1 << 0), + eBroadcastBitWarning = (1 << 1), + eBroadcastBitError = (1 << 2), }; static ConstString GetStaticBroadcasterClass(); @@ -84,39 +90,6 @@ public: 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 @@ -272,6 +245,7 @@ public: bool EnableLog(llvm::StringRef channel, llvm::ArrayRef<const char *> categories, llvm::StringRef log_file, uint32_t log_options, + size_t buffer_size, LogHandlerKind log_handler_kind, llvm::raw_ostream &error_stream); void SetLoggingCallback(lldb::LogOutputCallback log_callback, void *baton); @@ -329,8 +303,20 @@ public: bool SetUseColor(bool use_color); + bool GetShowProgress() const; + + bool SetShowProgress(bool show_progress); + + llvm::StringRef GetShowProgressAnsiPrefix() const; + + llvm::StringRef GetShowProgressAnsiSuffix() const; + bool GetUseAutosuggestion() const; + llvm::StringRef GetAutosuggestionAnsiPrefix() const; + + llvm::StringRef GetAutosuggestionAnsiSuffix() const; + bool GetUseSourceCache() const; bool SetUseSourceCache(bool use_source_cache); @@ -397,6 +383,53 @@ public: return m_broadcaster_manager_sp; } + /// Shared thread poll. Use only with ThreadPoolTaskGroup. + static llvm::ThreadPool &GetThreadPool(); + + /// Report warning events. + /// + /// Progress events will be delivered to any debuggers that have listeners + /// for the eBroadcastBitError. + /// + /// \param[in] message + /// The warning message to be reported. + /// + /// \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. + /// + /// \param [in] once + /// If a pointer is passed to a std::once_flag, then it will be used to + /// ensure the given warning is only broadcast once. + static void + ReportWarning(std::string messsage, + llvm::Optional<lldb::user_id_t> debugger_id = llvm::None, + std::once_flag *once = nullptr); + + /// Report error events. + /// + /// Progress events will be delivered to any debuggers that have listeners + /// for the eBroadcastBitError. + /// + /// \param[in] message + /// The error message to be reported. + /// + /// \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. + /// + /// \param [in] once + /// If a pointer is passed to a std::once_flag, then it will be used to + /// ensure the given error is only broadcast once. + static void + ReportError(std::string messsage, + llvm::Optional<lldb::user_id_t> debugger_id = llvm::None, + std::once_flag *once = nullptr); + protected: friend class CommandInterpreter; friend class REPL; @@ -435,12 +468,17 @@ protected: uint64_t completed, uint64_t total, llvm::Optional<lldb::user_id_t> debugger_id); + static void ReportDiagnosticImpl(DiagnosticEventData::Type type, + std::string message, + llvm::Optional<lldb::user_id_t> debugger_id, + std::once_flag *once); + + void PrintProgress(const ProgressEventData &data); + bool StartEventHandlerThread(); void StopEventHandlerThread(); - static lldb::thread_result_t EventHandlerThread(lldb::thread_arg_t arg); - void PushIOHandler(const lldb::IOHandlerSP &reader_sp, bool cancel_top_handler = true); @@ -454,9 +492,9 @@ protected: void JoinIOHandlerThread(); - static lldb::thread_result_t IOHandlerThread(lldb::thread_arg_t arg); + lldb::thread_result_t IOHandlerThread(); - void DefaultEventHandler(); + lldb::thread_result_t DefaultEventHandler(); void HandleBreakpointEvent(const lldb::EventSP &event_sp); @@ -464,6 +502,10 @@ protected: void HandleThreadEvent(const lldb::EventSP &event_sp); + void HandleProgressEvent(const lldb::EventSP &event_sp); + + void HandleDiagnosticEvent(const lldb::EventSP &event_sp); + // Ensures two threads don't attempt to flush process output in parallel. std::mutex m_output_flush_mutex; void FlushProcessOutput(Process &process, bool flush_stdout, @@ -512,8 +554,10 @@ protected: IOHandlerStack m_io_handler_stack; std::recursive_mutex m_io_handler_synchronous_mutex; - llvm::StringMap<std::weak_ptr<llvm::raw_ostream>> m_log_streams; - std::shared_ptr<llvm::raw_ostream> m_log_callback_stream_sp; + llvm::Optional<uint64_t> m_current_event_id; + + llvm::StringMap<std::weak_ptr<LogHandler>> m_stream_handlers; + std::shared_ptr<CallbackLogHandler> m_callback_handler_sp; ConstString m_instance_name; static LoadPluginCallbackType g_load_plugin_callback; typedef std::vector<llvm::sys::DynamicLibrary> LoadedPluginsList; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/DebuggerEvents.h b/contrib/llvm-project/lldb/include/lldb/Core/DebuggerEvents.h new file mode 100644 index 000000000000..b584b6285af8 --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Core/DebuggerEvents.h @@ -0,0 +1,87 @@ +//===-- DebuggerEvents.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/Utility/ConstString.h" +#include "lldb/Utility/Event.h" + +#include <string> + +#ifndef LLDB_CORE_DEBUGGER_EVENTS_H +#define LLDB_CORE_DEBUGGER_EVENTS_H + +namespace lldb_private { +class Stream; + +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; } + bool IsFinite() const { return m_total != UINT64_MAX; } + 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; +}; + +class DiagnosticEventData : public EventData { +public: + enum class Type { + Warning, + Error, + }; + DiagnosticEventData(Type type, std::string message, bool debugger_specific) + : m_message(std::move(message)), m_type(type), + m_debugger_specific(debugger_specific) {} + ~DiagnosticEventData() override = default; + + const std::string &GetMessage() const { return m_message; } + bool IsDebuggerSpecific() const { return m_debugger_specific; } + Type GetType() const { return m_type; } + + llvm::StringRef GetPrefix() const; + + void Dump(Stream *s) const override; + + static ConstString GetFlavorString(); + ConstString GetFlavor() const override; + + static const DiagnosticEventData * + GetEventDataFromEvent(const Event *event_ptr); + +protected: + std::string m_message; + Type m_type; + const bool m_debugger_specific; + + DiagnosticEventData(const DiagnosticEventData &) = delete; + const DiagnosticEventData &operator=(const DiagnosticEventData &) = delete; +}; + +} // namespace lldb_private + +#endif // LLDB_CORE_DEBUGGER_EVENTS_H diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Declaration.h b/contrib/llvm-project/lldb/include/lldb/Core/Declaration.h index 6ae21eb65eb3..4a0e9047b546 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/Declaration.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/Declaration.h @@ -24,7 +24,7 @@ namespace lldb_private { class Declaration { public: /// Default constructor. - Declaration() {} + Declaration() = default; /// Construct with file specification, and optional line and column. /// diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Disassembler.h b/contrib/llvm-project/lldb/include/lldb/Core/Disassembler.h index 87979fd92584..2dd1153031a6 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/Disassembler.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/Disassembler.h @@ -465,7 +465,7 @@ protected: uint32_t line = LLDB_INVALID_LINE_NUMBER; uint32_t column = 0; - SourceLine() {} + SourceLine() = default; bool operator==(const SourceLine &rhs) const { return file == rhs.file && line == rhs.line && rhs.column == column; @@ -489,7 +489,7 @@ protected: // Whether to print a blank line at the end of the source lines. bool print_source_context_end_eol = true; - SourceLinesToDisplay() {} + SourceLinesToDisplay() = default; }; // Get the function's declaration line number, hopefully a line number diff --git a/contrib/llvm-project/lldb/include/lldb/Core/IOHandler.h b/contrib/llvm-project/lldb/include/lldb/Core/IOHandler.h index 7011dd1e8e04..2ba421f7ba50 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/IOHandler.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/IOHandler.h @@ -34,7 +34,7 @@ class Debugger; namespace repro { class DataRecorder; } -} +} // namespace lldb_private namespace curses { class Application; @@ -85,11 +85,11 @@ public: virtual void GotEOF() = 0; - virtual bool IsActive() { return m_active && !m_done; } + bool IsActive() { return m_active && !m_done; } - virtual void SetIsDone(bool b) { m_done = b; } + void SetIsDone(bool b) { m_done = b; } - virtual bool GetIsDone() { return m_done; } + bool GetIsDone() { return m_done; } Type GetType() const { return m_type; } @@ -163,16 +163,16 @@ public: void WaitForPop(); - virtual void PrintAsync(Stream *stream, const char *s, size_t len) { - stream->Write(s, len); - stream->Flush(); - } + virtual void PrintAsync(const char *s, size_t len, bool is_stdout); + + std::recursive_mutex &GetOutputMutex() { return m_output_mutex; } protected: Debugger &m_debugger; lldb::FileSP m_input_sp; lldb::StreamFileSP m_output_sp; lldb::StreamFileSP m_error_sp; + std::recursive_mutex m_output_mutex; repro::DataRecorder *m_data_recorder; Predicate<bool> m_popped; Flags m_flags; @@ -415,7 +415,7 @@ public: uint32_t GetCurrentLineIndex() const; - void PrintAsync(Stream *stream, const char *s, size_t len) override; + void PrintAsync(const char *s, size_t len, bool is_stdout) override; private: #if LLDB_ENABLE_LIBEDIT @@ -540,7 +540,7 @@ public: return ((m_top != nullptr) ? m_top->GetHelpPrologue() : nullptr); } - void PrintAsync(Stream *stream, const char *s, size_t len); + bool PrintAsync(const char *s, size_t len, bool is_stdout); protected: typedef std::vector<lldb::IOHandlerSP> collection; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/LoadedModuleInfoList.h b/contrib/llvm-project/lldb/include/lldb/Core/LoadedModuleInfoList.h index 3f65ddc06d73..6ff456545840 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/LoadedModuleInfoList.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/LoadedModuleInfoList.h @@ -101,7 +101,7 @@ public: lldb::addr_t m_dynamic; }; - LoadedModuleInfoList() {} + LoadedModuleInfoList() = default; void add(const LoadedModuleInfo &mod) { m_list.push_back(mod); } diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Module.h b/contrib/llvm-project/lldb/include/lldb/Core/Module.h index f6c32586eda8..cc3edbb3f1bb 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/Module.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/Module.h @@ -300,7 +300,7 @@ public: /// containing function. If it is not inlined, then the block will be NULL. /// /// \param[in] name - /// The name of the compile unit we are looking for. + /// The name of the function we are looking for. /// /// \param[in] name_type_mask /// A bit mask of bits that indicate what kind of names should @@ -817,6 +817,12 @@ public: void ReportErrorIfModifyDetected(const char *format, ...) __attribute__((format(printf, 2, 3))); + void ReportWarningOptimization(llvm::Optional<lldb::user_id_t> debugger_id); + + void + ReportWarningUnsupportedLanguage(lldb::LanguageType language, + llvm::Optional<lldb::user_id_t> debugger_id); + // Return true if the file backing this module has changed since the module // was originally created since we saved the initial file modification time // when the module first gets created. @@ -905,7 +911,7 @@ public: /// correctly. class LookupInfo { public: - LookupInfo() {} + LookupInfo() = default; LookupInfo(ConstString name, lldb::FunctionNameType name_type_mask, lldb::LanguageType language); @@ -1053,6 +1059,9 @@ protected: /// time for the symbol tables can be aggregated here. StatsDuration m_symtab_index_time; + std::once_flag m_optimization_warning; + std::once_flag m_language_warning; + /// Resolve a file or load virtual address. /// /// Tries to resolve \a vm_addr as a file address (if \a diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ModuleList.h b/contrib/llvm-project/lldb/include/lldb/Core/ModuleList.h index 01b9991129eb..67205ca27e80 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ModuleList.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ModuleList.h @@ -68,6 +68,8 @@ public: FileSpec GetLLDBIndexCachePath() const; bool SetLLDBIndexCachePath(const FileSpec &path); + bool GetLoadSymbolOnDemand(); + PathMappingList GetSymlinkMappings() const; }; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ModuleSpec.h b/contrib/llvm-project/lldb/include/lldb/Core/ModuleSpec.h index bcf4ec30a673..451e347c9c7b 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ModuleSpec.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ModuleSpec.h @@ -13,6 +13,7 @@ #include "lldb/Target/PathMappingList.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/Iterable.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/UUID.h" @@ -25,7 +26,7 @@ namespace lldb_private { class ModuleSpec { public: - ModuleSpec() {} + ModuleSpec() = default; /// If the \c data argument is passed, its contents will be used /// as the module contents instead of trying to read them from @@ -273,7 +274,7 @@ protected: class ModuleSpecList { public: - ModuleSpecList() {} + ModuleSpecList() = default; ModuleSpecList(const ModuleSpecList &rhs) { std::lock_guard<std::recursive_mutex> lhs_guard(m_mutex); @@ -287,7 +288,7 @@ public: if (this != &rhs) { std::lock(m_mutex, rhs.m_mutex); std::lock_guard<std::recursive_mutex> lhs_guard(m_mutex, std::adopt_lock); - std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_mutex, + std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_mutex, std::adopt_lock); m_specs = rhs.m_specs; } @@ -387,8 +388,16 @@ public: } } + typedef std::vector<ModuleSpec> collection; + typedef LockingAdaptedIterable<collection, ModuleSpec, vector_adapter, + std::recursive_mutex> + ModuleSpecIterable; + + ModuleSpecIterable ModuleSpecs() { + return ModuleSpecIterable(m_specs, m_mutex); + } + protected: - typedef std::vector<ModuleSpec> collection; ///< The module collection type. collection m_specs; ///< The collection of modules. mutable std::recursive_mutex m_mutex; }; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/PluginManager.h b/contrib/llvm-project/lldb/include/lldb/Core/PluginManager.h index 1ab9d26d3af4..58be1d2b18dc 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/PluginManager.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/PluginManager.h @@ -174,7 +174,8 @@ public: ObjectFileCreateInstance create_callback, ObjectFileCreateMemoryInstance create_memory_callback, ObjectFileGetModuleSpecifications get_module_specifications, - ObjectFileSaveCore save_core = nullptr); + ObjectFileSaveCore save_core = nullptr, + DebuggerInitializeCallback debugger_init_callback = nullptr); static bool UnregisterPlugin(ObjectFileCreateInstance create_callback); @@ -335,21 +336,21 @@ public: // Trace static bool RegisterPlugin( llvm::StringRef name, llvm::StringRef description, - TraceCreateInstanceForSessionFile create_callback_for_session_file, + TraceCreateInstanceFromBundle create_callback_from_bundle, TraceCreateInstanceForLiveProcess create_callback_for_live_process, llvm::StringRef schema); static bool - UnregisterPlugin(TraceCreateInstanceForSessionFile create_callback); + UnregisterPlugin(TraceCreateInstanceFromBundle create_callback); - static TraceCreateInstanceForSessionFile + static TraceCreateInstanceFromBundle GetTraceCreateCallback(llvm::StringRef plugin_name); static TraceCreateInstanceForLiveProcess GetTraceCreateCallbackForLiveProcess(llvm::StringRef plugin_name); - /// Get the JSON schema for a trace session file corresponding to the given - /// plugin. + /// Get the JSON schema for a trace bundle description file corresponding to + /// the given plugin. /// /// \param[in] plugin_name /// The name of the plugin. @@ -359,8 +360,8 @@ public: /// otherwise the actual schema is returned. static llvm::StringRef GetTraceSchema(llvm::StringRef plugin_name); - /// Get the JSON schema for a trace session file corresponding to the plugin - /// given by its index. + /// Get the JSON schema for a trace bundle description file corresponding to + /// the plugin given by its index. /// /// \param[in] index /// The index of the plugin to get the schema of. @@ -483,6 +484,13 @@ public: ConstString description, bool is_global_property); static lldb::OptionValuePropertiesSP + GetSettingForObjectFilePlugin(Debugger &debugger, ConstString setting_name); + + static bool CreateSettingForObjectFilePlugin( + Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, + ConstString description, bool is_global_property); + + static lldb::OptionValuePropertiesSP GetSettingForSymbolFilePlugin(Debugger &debugger, ConstString setting_name); static bool CreateSettingForSymbolFilePlugin( diff --git a/contrib/llvm-project/lldb/include/lldb/Core/StreamAsynchronousIO.h b/contrib/llvm-project/lldb/include/lldb/Core/StreamAsynchronousIO.h index 30eff55b2e51..b7adbc42096c 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/StreamAsynchronousIO.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/StreamAsynchronousIO.h @@ -20,7 +20,7 @@ class Debugger; class StreamAsynchronousIO : public Stream { public: - StreamAsynchronousIO(Debugger &debugger, bool for_stdout); + StreamAsynchronousIO(Debugger &debugger, bool for_stdout, bool colors); ~StreamAsynchronousIO() override; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/StructuredDataImpl.h b/contrib/llvm-project/lldb/include/lldb/Core/StructuredDataImpl.h index 355aa77c4e5c..e755c53aaa9f 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/StructuredDataImpl.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/StructuredDataImpl.h @@ -25,7 +25,7 @@ namespace lldb_private { class StructuredDataImpl { public: - StructuredDataImpl() {} + StructuredDataImpl() = default; StructuredDataImpl(const StructuredDataImpl &rhs) = default; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Value.h b/contrib/llvm-project/lldb/include/lldb/Core/Value.h index 9f00a14251e2..fdda9f1db491 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/Value.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/Value.h @@ -156,13 +156,11 @@ protected: class ValueList { public: - ValueList() {} - - ValueList(const ValueList &rhs); - + ValueList() = default; ~ValueList() = default; - const ValueList &operator=(const ValueList &rhs); + ValueList(const ValueList &rhs) = default; + ValueList &operator=(const ValueList &rhs) = default; // void InsertValue (Value *value, size_t idx); void PushValue(const Value &value); diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObject.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObject.h index dac7aac06246..58a05352537f 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObject.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObject.h @@ -679,7 +679,7 @@ public: bool IsCStringContainer(bool check_pointer = false); std::pair<size_t, bool> - ReadPointedString(lldb::DataBufferSP &buffer_sp, Status &error, + ReadPointedString(lldb::WritableDataBufferSP &buffer_sp, Status &error, uint32_t max_length = 0, bool honor_array = true, lldb::Format item_format = lldb::eFormatCharArray); @@ -795,7 +795,7 @@ protected: class ChildrenManager { public: - ChildrenManager() {} + ChildrenManager() = default; bool HasChildAtIndex(size_t idx) { std::lock_guard<std::recursive_mutex> guard(m_mutex); diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectDynamicValue.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectDynamicValue.h index 09dcd0f968be..a36db44f449a 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectDynamicValue.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectDynamicValue.h @@ -32,7 +32,7 @@ class Status; /// set lldb type. class ValueObjectDynamicValue : public ValueObject { public: - ~ValueObjectDynamicValue() = default; + ~ValueObjectDynamicValue() override = default; llvm::Optional<uint64_t> GetByteSize() override; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/dwarf.h b/contrib/llvm-project/lldb/include/lldb/Core/dwarf.h index 968418e71c2f..60fbdec40bee 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/dwarf.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/dwarf.h @@ -15,8 +15,11 @@ // Get the DWARF constant definitions from llvm #include "llvm/BinaryFormat/Dwarf.h" -// and stuff them in our default namespace -using namespace llvm::dwarf; +namespace lldb_private { +namespace dwarf { + using namespace llvm::dwarf; +} +} typedef uint32_t dw_uleb128_t; typedef int32_t dw_sleb128_t; diff --git a/contrib/llvm-project/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h b/contrib/llvm-project/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h index cef43f45b8e4..c6306c7dab60 100644 --- a/contrib/llvm-project/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h +++ b/contrib/llvm-project/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h @@ -66,7 +66,7 @@ public: DumpValueObjectOptions & SetMaximumPointerDepth(PointerDepth depth = {PointerDepth::Mode::Never, 0}); - DumpValueObjectOptions &SetMaximumDepth(uint32_t depth = 0); + DumpValueObjectOptions &SetMaximumDepth(uint32_t depth, bool is_default); DumpValueObjectOptions &SetDeclPrintingHelper(DeclPrintingHelper helper); @@ -125,6 +125,7 @@ public: SetPointerAsArray(const PointerAsArraySettings &ptr_array); uint32_t m_max_depth = UINT32_MAX; + bool m_max_depth_is_default = true; lldb::DynamicValueType m_use_dynamic = lldb::eNoDynamicValues; uint32_t m_omit_summary_depth = 0; lldb::Format m_format = lldb::eFormatDefault; diff --git a/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormatClasses.h b/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormatClasses.h index 2b47bcdf3a69..158d2531d0da 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() {} + TypeNameSpecifierImpl() = default; TypeNameSpecifierImpl(llvm::StringRef name, bool is_regex) : m_is_regex(is_regex) { diff --git a/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeCategoryMap.h b/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeCategoryMap.h index 4dbca29db066..45dbb306aa75 100644 --- a/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeCategoryMap.h +++ b/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeCategoryMap.h @@ -23,13 +23,13 @@ namespace lldb_private { class TypeCategoryMap { private: - typedef ConstString KeyType; - typedef TypeCategoryImpl ValueType; - typedef ValueType::SharedPointer ValueSP; typedef std::list<lldb::TypeCategoryImplSP> ActiveCategoriesList; typedef ActiveCategoriesList::iterator ActiveCategoriesIterator; public: + typedef ConstString KeyType; + typedef TypeCategoryImpl ValueType; + typedef ValueType::SharedPointer ValueSP; typedef std::map<KeyType, ValueSP> MapType; typedef MapType::iterator MapIterator; typedef std::function<bool(const ValueSP &)> ForEachCallback; @@ -103,9 +103,6 @@ private: ActiveCategoriesList &active_list() { return m_active_categories; } std::recursive_mutex &mutex() { return m_map_mutex; } - - friend class FormattersContainer<ValueType>; - friend class FormatManager; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h b/contrib/llvm-project/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h index 833cd5eea356..90e54021a71f 100644 --- a/contrib/llvm-project/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h +++ b/contrib/llvm-project/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h @@ -117,6 +117,8 @@ protected: bool PrintChildrenOneLiner(bool hide_names); + bool HasReachedMaximumDepth(); + private: ValueObject *m_orig_valobj; ValueObject *m_valobj; diff --git a/contrib/llvm-project/lldb/include/lldb/Expression/DWARFExpression.h b/contrib/llvm-project/lldb/include/lldb/Expression/DWARFExpression.h index 1490ac2d614a..96a0e8e02da1 100644 --- a/contrib/llvm-project/lldb/include/lldb/Expression/DWARFExpression.h +++ b/contrib/llvm-project/lldb/include/lldb/Expression/DWARFExpression.h @@ -15,6 +15,7 @@ #include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-private.h" +#include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h" #include <functional> class DWARFUnit; @@ -55,18 +56,10 @@ public: /// \param[in] level /// The level of verbosity to use. /// - /// \param[in] location_list_base_addr - /// If this is a location list based expression, this is the - /// address of the object that owns it. NOTE: this value is - /// different from the DWARF version of the location list base - /// address which is compile unit relative. This base address - /// is the address of the object that owns the location list. - /// /// \param[in] abi /// An optional ABI plug-in that can be used to resolve register /// names. - void GetDescription(Stream *s, lldb::DescriptionLevel level, - lldb::addr_t location_list_base_addr, ABI *abi) const; + void GetDescription(Stream *s, lldb::DescriptionLevel level, ABI *abi) const; /// Return true if the location expression contains data bool IsValid() const; @@ -217,6 +210,13 @@ public: lldb::addr_t func_load_addr, lldb::addr_t address, ABI *abi); + bool DumpLocations(Stream *s, lldb::DescriptionLevel level, + lldb::addr_t func_load_addr, lldb::addr_t addr, ABI *abi); + + bool GetLocationExpressions( + lldb::addr_t load_function_start, + llvm::function_ref<bool(llvm::DWARFLocationExpression)> callback) const; + bool MatchesOperand(StackFrame &frame, const Instruction::Operand &op); llvm::Optional<DataExtractor> diff --git a/contrib/llvm-project/lldb/include/lldb/Host/Config.h.cmake b/contrib/llvm-project/lldb/include/lldb/Host/Config.h.cmake index ffe919aa9956..c24603f866d6 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/Config.h.cmake +++ b/contrib/llvm-project/lldb/include/lldb/Host/Config.h.cmake @@ -53,4 +53,6 @@ #define LLDB_LIBDIR_SUFFIX "${LLVM_LIBDIR_SUFFIX}" +#cmakedefine LLDB_GLOBAL_INIT_DIRECTORY R"(${LLDB_GLOBAL_INIT_DIRECTORY})" + #endif // #ifndef LLDB_HOST_CONFIG_H diff --git a/contrib/llvm-project/lldb/include/lldb/Host/Debug.h b/contrib/llvm-project/lldb/include/lldb/Host/Debug.h index e4e410474c02..56a6efd1b4d6 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/Debug.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/Debug.h @@ -32,7 +32,7 @@ struct ResumeAction { // send a signal to the thread when the action is run or step. class ResumeActionList { public: - ResumeActionList() {} + ResumeActionList() = default; ResumeActionList(lldb::StateType default_action, int signal) { SetDefaultThreadActionIfNeeded(default_action, signal); @@ -130,12 +130,8 @@ protected: struct ThreadStopInfo { lldb::StopReason reason; + uint32_t signo; union { - // eStopReasonSignal - struct { - uint32_t signo; - } signal; - // eStopReasonException struct { uint64_t type; diff --git a/contrib/llvm-project/lldb/include/lldb/Host/Editline.h b/contrib/llvm-project/lldb/include/lldb/Host/Editline.h index 876f6052311e..ffe2e3500aaa 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/Editline.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/Editline.h @@ -154,7 +154,8 @@ using namespace line_editor; class Editline { public: Editline(const char *editor_name, FILE *input_file, FILE *output_file, - FILE *error_file, bool color_prompts); + FILE *error_file, std::recursive_mutex &output_mutex, + bool color_prompts); ~Editline(); @@ -210,6 +211,14 @@ public: m_fix_indentation_callback_chars = indent_chars; } + void SetSuggestionAnsiPrefix(std::string prefix) { + m_suggestion_ansi_prefix = std::move(prefix); + } + + void SetSuggestionAnsiSuffix(std::string suffix) { + m_suggestion_ansi_suffix = std::move(suffix); + } + /// Prompts for and reads a single line of user input. bool GetLine(std::string &line, bool &interrupted); @@ -388,11 +397,13 @@ private: const char *m_fix_indentation_callback_chars = nullptr; CompleteCallbackType m_completion_callback; - SuggestionCallbackType m_suggestion_callback; + std::string m_suggestion_ansi_prefix; + std::string m_suggestion_ansi_suffix; + std::size_t m_previous_autosuggestion_size = 0; - std::mutex m_output_mutex; + std::recursive_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 d10ec1fe282a..85e8185ebc96 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/File.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/File.h @@ -410,7 +410,7 @@ public: llvm::Expected<OpenOptions> GetOptions() const override; static char ID; - virtual bool isA(const void *classID) const override { + bool isA(const void *classID) const override { return classID == &ID || File::isA(classID); } static bool classof(const File *file) { return file->isA(&ID); } @@ -458,7 +458,7 @@ public: Status Close() override; static char ID; - virtual bool isA(const void *classID) const override { + bool isA(const void *classID) const override { return classID == &ID || File::isA(classID); } static bool classof(const File *file) { return file->isA(&ID); } diff --git a/contrib/llvm-project/lldb/include/lldb/Host/FileSystem.h b/contrib/llvm-project/lldb/include/lldb/Host/FileSystem.h index 9f863e8a9d7e..8a4ee8470af2 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/FileSystem.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/FileSystem.h @@ -10,13 +10,12 @@ #define LLDB_HOST_FILESYSTEM_H #include "lldb/Host/File.h" -#include "lldb/Utility/DataBufferLLVM.h" +#include "lldb/Utility/DataBuffer.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Status.h" #include "llvm/ADT/Optional.h" #include "llvm/Support/Chrono.h" -#include "llvm/Support/FileCollector.h" #include "llvm/Support/VirtualFileSystem.h" #include "lldb/lldb-types.h" @@ -31,13 +30,9 @@ public: static const char *DEV_NULL; static const char *PATH_CONVERSION_ERROR; - FileSystem() : m_fs(llvm::vfs::getRealFileSystem()), m_collector(nullptr) {} - FileSystem(std::shared_ptr<llvm::FileCollectorBase> collector) - : m_fs(llvm::vfs::getRealFileSystem()), m_collector(std::move(collector)), - m_mapped(false) {} - FileSystem(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs, - bool mapped = false) - : m_fs(std::move(fs)), m_collector(nullptr), m_mapped(mapped) {} + FileSystem() : m_fs(llvm::vfs::getRealFileSystem()) {} + FileSystem(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs) + : m_fs(std::move(fs)) {} FileSystem(const FileSystem &fs) = delete; FileSystem &operator=(const FileSystem &fs) = delete; @@ -45,8 +40,6 @@ public: static FileSystem &Instance(); static void Initialize(); - static void Initialize(std::shared_ptr<llvm::FileCollectorBase> collector); - static llvm::Error Initialize(const FileSpec &mapping); static void Initialize(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs); static void Terminate(); @@ -149,12 +142,18 @@ public: //// Create memory buffer from path. /// \{ - std::shared_ptr<DataBufferLLVM> CreateDataBuffer(const llvm::Twine &path, - uint64_t size = 0, - uint64_t offset = 0); - std::shared_ptr<DataBufferLLVM> CreateDataBuffer(const FileSpec &file_spec, - uint64_t size = 0, - uint64_t offset = 0); + std::shared_ptr<DataBuffer> CreateDataBuffer(const llvm::Twine &path, + uint64_t size = 0, + uint64_t offset = 0); + std::shared_ptr<DataBuffer> CreateDataBuffer(const FileSpec &file_spec, + uint64_t size = 0, + uint64_t offset = 0); + std::shared_ptr<WritableDataBuffer> + CreateWritableDataBuffer(const llvm::Twine &path, uint64_t size = 0, + uint64_t offset = 0); + std::shared_ptr<WritableDataBuffer> + CreateWritableDataBuffer(const FileSpec &file_spec, uint64_t size = 0, + uint64_t offset = 0); /// \} /// Call into the Host to see if it can help find the file. @@ -189,24 +188,16 @@ public: std::error_code GetRealPath(const llvm::Twine &path, llvm::SmallVectorImpl<char> &output) const; - llvm::ErrorOr<std::string> GetExternalPath(const llvm::Twine &path); - llvm::ErrorOr<std::string> GetExternalPath(const FileSpec &file_spec); - llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> GetVirtualFileSystem() { return m_fs; } - void Collect(const FileSpec &file_spec); - void Collect(const llvm::Twine &file); - void SetHomeDirectory(std::string home_directory); private: static llvm::Optional<FileSystem> &InstanceImpl(); llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> m_fs; - std::shared_ptr<llvm::FileCollectorBase> m_collector; std::string m_home_directory; - 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 1fdf7eab7eb8..4fc2bd128b02 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/Host.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/Host.h @@ -13,6 +13,7 @@ #include "lldb/Host/HostThread.h" #include "lldb/Utility/Environment.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/Log.h" #include "lldb/Utility/Timeout.h" #include "lldb/lldb-private-forward.h" #include "lldb/lldb-private.h" @@ -61,54 +62,33 @@ inline bool operator!=(WaitStatus a, WaitStatus b) { return !(a == b); } /// Host is a class that answers information about the host operating system. class Host { public: - typedef std::function<bool( - lldb::pid_t pid, bool exited, - int signal, // Zero for no signal - int status)> // Exit value of process if signal is zero + typedef std::function<void(lldb::pid_t pid, + int signal, // Zero for no signal + int status)> // Exit value of process if signal is + // zero MonitorChildProcessCallback; /// Start monitoring a child process. /// /// Allows easy monitoring of child processes. \a callback will be called - /// when the child process exits or if it gets a signal. The callback will - /// only be called with signals if \a monitor_signals is \b true. \a - /// callback will usually be called from another thread so the callback - /// function must be thread safe. - /// - /// When the callback gets called, the return value indicates if monitoring - /// should stop. If \b true is returned from \a callback the information - /// will be removed. If \b false is returned then monitoring will continue. - /// If the child process exits, the monitoring will automatically stop after - /// the callback returned regardless of the callback return value. + /// when the child process exits or if it dies from a signal. /// /// \param[in] callback /// A function callback to call when a child receives a signal - /// (if \a monitor_signals is true) or a child exits. + /// or exits. /// /// \param[in] pid - /// The process ID of a child process to monitor, -1 for all - /// processes. - /// - /// \param[in] monitor_signals - /// If \b true the callback will get called when the child - /// process gets a signal. If \b false, the callback will only - /// get called if the child process exits. + /// The process ID of a child process to monitor. /// /// \return /// A thread handle that can be used to cancel the thread that /// was spawned to monitor \a pid. - /// - /// \see static void Host::StopMonitoringChildProcess (uint32_t) static llvm::Expected<HostThread> StartMonitoringChildProcess(const MonitorChildProcessCallback &callback, - lldb::pid_t pid, bool monitor_signals); - - enum SystemLogType { eSystemLogWarning, eSystemLogError }; + lldb::pid_t pid); - static void SystemLog(SystemLogType type, const char *format, ...) - __attribute__((format(printf, 2, 3))); - - static void SystemLog(SystemLogType type, const char *format, va_list args); + /// Emit the given message to the operating system log. + static void SystemLog(llvm::StringRef message); /// Get the process ID for the calling process. /// @@ -259,6 +239,13 @@ public: static bool OpenFileInExternalEditor(const FileSpec &file_spec, uint32_t line_no); + /// Check if we're running in an interactive graphical session. + /// + /// \return + /// True if we're running in an interactive graphical session. False if + /// we're not or don't know. + static bool IsInteractiveGraphicSession(); + static Environment GetEnvironment(); static std::unique_ptr<Connection> @@ -269,6 +256,19 @@ protected: ProcessInstanceInfoList &proc_infos); }; +/// Log handler that emits log messages to the operating system log. +class SystemLogHandler : public LogHandler { +public: + SystemLogHandler(); + void Emit(llvm::StringRef message) override; + + bool isA(const void *ClassID) const override { return ClassID == &ID; } + static bool classof(const LogHandler *obj) { return obj->isA(&ID); } + +private: + static char ID; +}; + } // namespace lldb_private namespace llvm { diff --git a/contrib/llvm-project/lldb/include/lldb/Host/HostNativeProcessBase.h b/contrib/llvm-project/lldb/include/lldb/Host/HostNativeProcessBase.h index 5469f8a50e26..fed29662fab8 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/HostNativeProcessBase.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/HostNativeProcessBase.h @@ -30,7 +30,6 @@ public: virtual ~HostNativeProcessBase() = default; virtual Status Terminate() = 0; - virtual Status GetMainModule(FileSpec &file_spec) const = 0; virtual lldb::pid_t GetProcessId() const = 0; virtual bool IsRunning() const = 0; @@ -38,8 +37,7 @@ public: lldb::process_t GetSystemHandle() const { return m_process; } virtual llvm::Expected<HostThread> - StartMonitoring(const Host::MonitorChildProcessCallback &callback, - bool monitor_signals) = 0; + StartMonitoring(const Host::MonitorChildProcessCallback &callback) = 0; protected: lldb::process_t m_process; diff --git a/contrib/llvm-project/lldb/include/lldb/Host/HostProcess.h b/contrib/llvm-project/lldb/include/lldb/Host/HostProcess.h index 0b7c30364223..2871b3ab16a7 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/HostProcess.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/HostProcess.h @@ -37,14 +37,12 @@ public: ~HostProcess(); Status Terminate(); - Status GetMainModule(FileSpec &file_spec) const; lldb::pid_t GetProcessId() const; bool IsRunning() const; llvm::Expected<HostThread> - StartMonitoring(const Host::MonitorChildProcessCallback &callback, - bool monitor_signals); + StartMonitoring(const Host::MonitorChildProcessCallback &callback); HostNativeProcessBase &GetNativeProcess(); const HostNativeProcessBase &GetNativeProcess() const; diff --git a/contrib/llvm-project/lldb/include/lldb/Host/MainLoop.h b/contrib/llvm-project/lldb/include/lldb/Host/MainLoop.h index 94499f583463..f04ac7359cc1 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/MainLoop.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/MainLoop.h @@ -14,6 +14,7 @@ #include "llvm/ADT/DenseMap.h" #include <csignal> #include <list> +#include <vector> #if !HAVE_PPOLL && !HAVE_SYS_EVENT_H && !defined(__ANDROID__) #define SIGNAL_POLLING_UNSUPPORTED 1 @@ -59,6 +60,11 @@ public: SignalHandleUP RegisterSignal(int signo, const Callback &callback, Status &error); + // Add a pending callback that will be executed once after all the pending + // events are processed. The callback will be executed even if termination + // was requested. + void AddPendingCallback(const Callback &callback) override; + Status Run() override; // This should only be performed from a callback. Do not attempt to terminate @@ -104,6 +110,7 @@ private: llvm::DenseMap<IOObject::WaitableHandle, Callback> m_read_fds; llvm::DenseMap<int, SignalInfo> m_signals; + std::vector<Callback> m_pending_callbacks; #if HAVE_SYS_EVENT_H int m_kqueue; #endif diff --git a/contrib/llvm-project/lldb/include/lldb/Host/MainLoopBase.h b/contrib/llvm-project/lldb/include/lldb/Host/MainLoopBase.h index 67857b26ac70..2a2899341a51 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/MainLoopBase.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/MainLoopBase.h @@ -46,6 +46,13 @@ public: llvm_unreachable("Not implemented"); } + // Add a pending callback that will be executed once after all the pending + // events are processed. The callback will be executed even if termination + // was requested. + virtual void AddPendingCallback(const Callback &callback) { + llvm_unreachable("Not implemented"); + } + // Waits for registered events and invoke the proper callbacks. Returns when // all callbacks deregister themselves or when someone requests termination. virtual Status Run() { llvm_unreachable("Not implemented"); } diff --git a/contrib/llvm-project/lldb/include/lldb/Host/ProcessLaunchInfo.h b/contrib/llvm-project/lldb/include/lldb/Host/ProcessLaunchInfo.h index 3ed21637de7f..8f8f9333fd1f 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/ProcessLaunchInfo.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/ProcessLaunchInfo.h @@ -99,21 +99,18 @@ public: bool first_arg_is_full_shell_command, uint32_t num_resumes); - void - SetMonitorProcessCallback(const Host::MonitorChildProcessCallback &callback, - bool monitor_signals); + void SetMonitorProcessCallback(Host::MonitorChildProcessCallback callback) { + m_monitor_callback = std::move(callback); + } - Host::MonitorChildProcessCallback GetMonitorProcessCallback() const { + const Host::MonitorChildProcessCallback &GetMonitorProcessCallback() const { return m_monitor_callback; } /// A Monitor callback which does not take any action on process events. Use /// this if you don't need to take any particular action when the process /// terminates, but you still need to reap it. - static bool NoOpMonitorCallback(lldb::pid_t pid, bool exited, int signal, - int status); - - bool GetMonitorSignals() const { return m_monitor_signals; } + static void NoOpMonitorCallback(lldb::pid_t pid, int signal, int status); // If the LaunchInfo has a monitor callback, then arrange to monitor the // process. Return true if the LaunchInfo has taken care of monitoring the @@ -178,8 +175,6 @@ protected: std::shared_ptr<PseudoTerminal> m_pty; uint32_t m_resume_count = 0; // How many times do we resume after launching Host::MonitorChildProcessCallback m_monitor_callback; - 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; diff --git a/contrib/llvm-project/lldb/include/lldb/Host/ThreadLauncher.h b/contrib/llvm-project/lldb/include/lldb/Host/ThreadLauncher.h index 00b42fa6a11d..8bb6c79466a7 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/ThreadLauncher.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/ThreadLauncher.h @@ -20,8 +20,8 @@ namespace lldb_private { class ThreadLauncher { public: static llvm::Expected<HostThread> - LaunchThread(llvm::StringRef name, lldb::thread_func_t thread_function, - lldb::thread_arg_t thread_arg, + LaunchThread(llvm::StringRef name, + std::function<lldb::thread_result_t()> thread_function, size_t min_stack_byte_size = 0); // Minimum stack size in bytes, // set stack size to zero for // default platform thread stack @@ -29,12 +29,11 @@ public: struct HostThreadCreateInfo { std::string thread_name; - lldb::thread_func_t thread_fptr; - lldb::thread_arg_t thread_arg; + std::function<lldb::thread_result_t()> impl; - HostThreadCreateInfo(const char *name, lldb::thread_func_t fptr, - lldb::thread_arg_t arg) - : thread_name(name ? name : ""), thread_fptr(fptr), thread_arg(arg) {} + HostThreadCreateInfo(std::string thread_name, + std::function<lldb::thread_result_t()> impl) + : thread_name(std::move(thread_name)), impl(std::move(impl)) {} }; }; } 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 c7494ba6b195..37dacca6ff81 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/common/NativeProcessProtocol.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/common/NativeProcessProtocol.h @@ -15,6 +15,7 @@ #include "lldb/Host/Host.h" #include "lldb/Host/MainLoop.h" #include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/Iterable.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/TraceGDBRemotePackets.h" #include "lldb/Utility/UnimplementedError.h" @@ -48,6 +49,16 @@ class NativeProcessProtocol { public: virtual ~NativeProcessProtocol() = default; + typedef std::vector<std::unique_ptr<NativeThreadProtocol>> thread_collection; + template <typename I> + static NativeThreadProtocol &thread_list_adapter(I &iter) { + assert(*iter); + return **iter; + } + typedef LockingAdaptedIterable<thread_collection, NativeThreadProtocol &, + thread_list_adapter, std::recursive_mutex> + ThreadIterable; + virtual Status Resume(const ResumeActionList &resume_actions) = 0; virtual Status Halt() = 0; @@ -210,6 +221,10 @@ public: return GetThreadByID(m_current_thread_id); } + ThreadIterable Threads() const { + return ThreadIterable(m_threads, m_threads_mutex); + } + // Access to inferior stdio virtual int GetTerminalFileDescriptor() { return m_terminal_fd; } @@ -310,6 +325,12 @@ public: virtual Extension GetSupportedExtensions() const { return {}; } }; + /// Notify tracers that the target process will resume + virtual void NotifyTracersProcessWillResume() {} + + /// Notify tracers that the target process just stopped + virtual void NotifyTracersProcessDidStop() {} + /// Start tracing a process or its threads. /// /// \param[in] json_params @@ -457,7 +478,7 @@ protected: /// /// Provide a mechanism for a delegate to clear out any exec- /// sensitive data. - void NotifyDidExec(); + virtual void NotifyDidExec(); NativeThreadProtocol *GetThreadByIDUnlocked(lldb::tid_t tid); diff --git a/contrib/llvm-project/lldb/include/lldb/Host/common/NativeRegisterContext.h b/contrib/llvm-project/lldb/include/lldb/Host/common/NativeRegisterContext.h index f7568fe31b80..0a7647d78080 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/common/NativeRegisterContext.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/common/NativeRegisterContext.h @@ -51,7 +51,7 @@ public: virtual Status WriteRegister(const RegisterInfo *reg_info, const RegisterValue ®_value) = 0; - virtual Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) = 0; + virtual Status ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) = 0; virtual Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) = 0; diff --git a/contrib/llvm-project/lldb/include/lldb/Host/posix/HostProcessPosix.h b/contrib/llvm-project/lldb/include/lldb/Host/posix/HostProcessPosix.h index 5def1b77eefe..6d3d8d94a877 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/posix/HostProcessPosix.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/posix/HostProcessPosix.h @@ -27,14 +27,12 @@ public: static Status Signal(lldb::process_t process, int signo); Status Terminate() override; - Status GetMainModule(FileSpec &file_spec) const override; lldb::pid_t GetProcessId() const override; bool IsRunning() const override; llvm::Expected<HostThread> - StartMonitoring(const Host::MonitorChildProcessCallback &callback, - bool monitor_signals) override; + StartMonitoring(const Host::MonitorChildProcessCallback &callback) override; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandInterpreter.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandInterpreter.h index 3efb59fc0564..55971136b63b 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandInterpreter.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandInterpreter.h @@ -223,11 +223,11 @@ public: eBroadcastBitAsynchronousErrorData = (1 << 4) }; - enum ChildrenTruncatedWarningStatus // tristate boolean to manage children - // truncation warning - { eNoTruncation = 0, // never truncated - eUnwarnedTruncation = 1, // truncated but did not notify - eWarnedTruncation = 2 // truncated and notified + /// Tristate boolean to manage children omission warnings. + enum ChildrenOmissionWarningStatus { + eNoOmission = 0, ///< No children were omitted. + eUnwarnedOmission = 1, ///< Children omitted, and not yet notified. + eWarnedOmission = 2 ///< Children omitted and notified. }; enum CommandTypes { @@ -252,7 +252,8 @@ public: } void SourceInitFileCwd(CommandReturnObject &result); - void SourceInitFileHome(CommandReturnObject &result, bool is_repl = false); + void SourceInitFileHome(CommandReturnObject &result, bool is_repl); + void SourceInitFileGlobal(CommandReturnObject &result); bool AddCommand(llvm::StringRef name, const lldb::CommandObjectSP &cmd_sp, bool can_replace); @@ -495,21 +496,33 @@ public: } void ChildrenTruncated() { - if (m_truncation_warning == eNoTruncation) - m_truncation_warning = eUnwarnedTruncation; + if (m_truncation_warning == eNoOmission) + m_truncation_warning = eUnwarnedOmission; } - bool TruncationWarningNecessary() { - return (m_truncation_warning == eUnwarnedTruncation); + void SetReachedMaximumDepth() { + if (m_max_depth_warning == eNoOmission) + m_max_depth_warning = eUnwarnedOmission; } - void TruncationWarningGiven() { m_truncation_warning = eWarnedTruncation; } + void PrintWarningsIfNecessary(Stream &s, const std::string &cmd_name) { + if (m_truncation_warning == eUnwarnedOmission) { + s.Printf("*** Some of the displayed variables have more members than the " + "debugger will show by default. To show all of them, you can " + "either use the --show-all-children option to %s or raise the " + "limit by changing the target.max-children-count setting.\n", + cmd_name.c_str()); + m_truncation_warning = eWarnedOmission; + } - const char *TruncationWarningText() { - return "*** Some of your variables have more members than the debugger " - "will show by default. To show all of them, you can either use the " - "--show-all-children option to %s or raise the limit by changing " - "the target.max-children-count setting.\n"; + if (m_max_depth_warning == eUnwarnedOmission) { + s.Printf("*** Some of the displayed variables have a greater depth of " + "members than the debugger will show by default. To increase " + "the limit, use the --depth option to %s, or raise the limit by " + "changing the target.max-children-depth setting.\n", + cmd_name.c_str()); + m_max_depth_warning = eWarnedOmission; + } } CommandHistory &GetCommandHistory() { return m_command_history; } @@ -548,6 +561,8 @@ public: void SetEchoCommentCommands(bool enable); bool GetRepeatPreviousCommand() const; + + bool GetRequireCommandOverwrite() const; const CommandObject::CommandMap &GetUserCommands() const { return m_user_dict; @@ -605,6 +620,10 @@ public: FileSpec GetCurrentSourceDir(); + bool IsInteractive(); + + bool IOHandlerInterrupt(IOHandler &io_handler) override; + protected: friend class Debugger; @@ -618,8 +637,6 @@ protected: return ConstString(); } - bool IOHandlerInterrupt(IOHandler &io_handler) override; - void GetProcessOutput(); bool DidProcessStopAbnormally() const; @@ -652,7 +669,8 @@ private: const CommandObject::CommandMap &command_map); // An interruptible wrapper around the stream output - void PrintCommandOutput(Stream &stream, llvm::StringRef str); + void PrintCommandOutput(IOHandler &io_handler, llvm::StringRef str, + bool is_stdout); bool EchoCommandNonInteractive(llvm::StringRef line, const Flags &io_handler_flags) const; @@ -695,9 +713,12 @@ private: lldb::IOHandlerSP m_command_io_handler_sp; char m_comment_char; bool m_batch_command_mode; - ChildrenTruncatedWarningStatus m_truncation_warning; // Whether we truncated - // children and whether - // the user has been told + /// Whether we truncated a value's list of children and whether the user has + /// been told. + ChildrenOmissionWarningStatus m_truncation_warning; + /// Whether we reached the maximum child nesting depth and whether the user + /// has been told. + ChildrenOmissionWarningStatus m_max_depth_warning; // FIXME: Stop using this to control adding to the history and then replace // this with m_command_source_dirs.size(). diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObject.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObject.h index bfddf559e5fe..45fc47b02c04 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObject.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObject.h @@ -276,14 +276,13 @@ public: /// The command arguments. /// /// \return - /// nullptr if there is no special repeat command - it will use the + /// llvm::None if there is no special repeat command - it will use the /// current command line. - /// Otherwise a pointer to the command to be repeated. - /// If the returned string is the empty string, the command won't be - /// repeated. - virtual const char *GetRepeatCommand(Args ¤t_command_args, - uint32_t index) { - return nullptr; + /// Otherwise a std::string containing the command to be repeated. + /// If the string is empty, the command won't be allow repeating. + virtual llvm::Optional<std::string> + GetRepeatCommand(Args ¤t_command_args, uint32_t index) { + return llvm::None; } bool HasOverrideCallback() const { @@ -327,15 +326,20 @@ protected: } virtual const char *GetInvalidProcessDescription() { - return "invalid process"; + return "Command requires a current process."; } - virtual const char *GetInvalidThreadDescription() { return "invalid thread"; } + virtual const char *GetInvalidThreadDescription() { + return "Command requires a process which is currently stopped."; + } - virtual const char *GetInvalidFrameDescription() { return "invalid frame"; } + virtual const char *GetInvalidFrameDescription() { + return "Command requires a process, which is currently stopped."; + } virtual const char *GetInvalidRegContextDescription() { - return "invalid frame, no registers"; + return "invalid frame, no registers, command requires a process which is " + "currently stopped."; } // This is for use in the command interpreter, when you either want the diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObjectMultiword.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObjectMultiword.h index ab580c11eb4f..a8ab6e44954e 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObjectMultiword.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObjectMultiword.h @@ -55,8 +55,8 @@ public: void HandleCompletion(CompletionRequest &request) override; - const char *GetRepeatCommand(Args ¤t_command_args, - uint32_t index) override; + llvm::Optional<std::string> GetRepeatCommand(Args ¤t_command_args, + uint32_t index) override; bool Execute(const char *args_string, CommandReturnObject &result) override; @@ -120,8 +120,8 @@ public: HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override; - const char *GetRepeatCommand(Args ¤t_command_args, - uint32_t index) override; + llvm::Optional<std::string> GetRepeatCommand(Args ¤t_command_args, + uint32_t index) override; /// \return /// An error message to be displayed when the command is executed (i.e. diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandReturnObject.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandReturnObject.h index 72518a902144..2177e721f9a4 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandReturnObject.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandReturnObject.h @@ -15,6 +15,7 @@ #include "lldb/lldb-private.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/WithColor.h" @@ -132,6 +133,8 @@ public: void SetError(const Status &error, const char *fallback_error_cstr = nullptr); + void SetError(llvm::Error error); + lldb::ReturnStatus GetStatus() const; void SetStatus(lldb::ReturnStatus status); diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupMemoryTag.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupMemoryTag.h new file mode 100644 index 000000000000..918ea3ad96df --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupMemoryTag.h @@ -0,0 +1,44 @@ +//===-- OptionGroupMemoryTag.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_OPTIONGROUPMEMORYTAG_H +#define LLDB_INTERPRETER_OPTIONGROUPMEMORYTAG_H + +#include "lldb/Interpreter/OptionValueBoolean.h" +#include "lldb/Interpreter/Options.h" + +namespace lldb_private { + +class OptionGroupMemoryTag : public OptionGroup { +public: + OptionGroupMemoryTag( + // Whether to note that --show-tags does not apply to binary output. + // "memory read" wants this but "memory find" does not. + bool note_binary = false); + + ~OptionGroupMemoryTag() override = default; + + llvm::ArrayRef<OptionDefinition> GetDefinitions() override; + + Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, + ExecutionContext *execution_context) override; + + void OptionParsingStarting(ExecutionContext *execution_context) override; + + bool AnyOptionWasSet() const { return m_show_tags.OptionWasSet(); } + + OptionValueBoolean GetShowTags() { return m_show_tags; }; + +protected: + OptionValueBoolean m_show_tags; + OptionDefinition m_option_definition; +}; + +} // namespace lldb_private + +#endif // LLDB_INTERPRETER_OPTIONGROUPMEMORYTAG_H diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h index 56452f4956f2..9b545c46fba4 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h @@ -43,7 +43,8 @@ public: lldb::TypeSummaryImplSP summary_sp = lldb::TypeSummaryImplSP()); bool show_types : 1, show_location : 1, flat_output : 1, use_objc : 1, - use_synth : 1, be_raw : 1, ignore_cap : 1, run_validator : 1; + use_synth : 1, be_raw : 1, ignore_cap : 1, run_validator : 1, + max_depth_is_default : 1; uint32_t no_summary_depth; uint32_t max_depth; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValue.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValue.h index 99f52b0411b9..277a5c9d30f0 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValue.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValue.h @@ -311,7 +311,6 @@ public: lldb::OptionValueSP GetParent() const { return m_parent_wp.lock(); } void SetValueChangedCallback(std::function<void()> callback) { - assert(!m_callback); m_callback = std::move(callback); } diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueDictionary.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueDictionary.h index f96cbc9fe9e7..4c6bcaecd4c7 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueDictionary.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueDictionary.h @@ -12,6 +12,7 @@ #include <map> #include "lldb/Interpreter/OptionValue.h" +#include "lldb/lldb-private-types.h" namespace lldb_private { @@ -19,8 +20,10 @@ class OptionValueDictionary : public Cloneable<OptionValueDictionary, OptionValue> { public: OptionValueDictionary(uint32_t type_mask = UINT32_MAX, + OptionEnumValues enum_values = OptionEnumValues(), bool raw_value_dump = true) - : m_type_mask(type_mask), m_raw_value_dump(raw_value_dump) {} + : m_type_mask(type_mask), m_enum_values(enum_values), + m_raw_value_dump(raw_value_dump) {} ~OptionValueDictionary() override = default; @@ -75,6 +78,7 @@ public: protected: typedef std::map<ConstString, lldb::OptionValueSP> collection; uint32_t m_type_mask; + OptionEnumValues m_enum_values; collection m_values; bool m_raw_value_dump; }; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueProperties.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueProperties.h index 3e5685b7f0bf..14f496bca6cd 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueProperties.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueProperties.h @@ -152,6 +152,10 @@ public: GetPropertyAtIndexAsOptionValueSInt64(const ExecutionContext *exe_ctx, uint32_t idx) const; + OptionValueUInt64 * + GetPropertyAtIndexAsOptionValueUInt64(const ExecutionContext *exe_ctx, + uint32_t idx) const; + int64_t GetPropertyAtIndexAsSInt64(const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueString.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueString.h index be42deb80da7..820656d19e2c 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueString.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueString.h @@ -109,6 +109,11 @@ public: bool IsCurrentValueEmpty() const { return m_current_value.empty(); } bool IsDefaultValueEmpty() const { return m_default_value.empty(); } + + void SetValidator(ValidatorCallback validator, void *baton = nullptr) { + m_validator = validator; + m_validator_baton = baton; + } protected: std::string m_current_value; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/Options.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/Options.h index 5899a9edc47f..a952d5f78df9 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/Options.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/Options.h @@ -86,7 +86,7 @@ public: const OptionDefinition &option_def, uint32_t output_max_columns); - void GenerateOptionUsage(Stream &strm, CommandObject *cmd, + void GenerateOptionUsage(Stream &strm, CommandObject &cmd, uint32_t screen_width); bool SupportsLongOption(const char *long_option); diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptedInterface.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptedInterface.h index 9de5e60cfea3..da4977af123d 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptedInterface.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptedInterface.h @@ -11,8 +11,8 @@ #include "lldb/Core/StructuredDataImpl.h" #include "lldb/Target/ExecutionContext.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" #include "lldb/lldb-private.h" #include "llvm/Support/Compiler.h" @@ -34,8 +34,8 @@ public: static Ret ErrorWithMessage(llvm::StringRef caller_name, llvm::StringRef error_msg, Status &error, LLDBLog log_caterogy = LLDBLog::Process) { - LLDB_LOGF(GetLogIfAllCategoriesSet(log_caterogy), "%s ERROR = %s", - caller_name.data(), error_msg.data()); + LLDB_LOGF(GetLog(log_caterogy), "%s ERROR = %s", caller_name.data(), + error_msg.data()); error.SetErrorString(llvm::Twine(caller_name + llvm::Twine(" ERROR = ") + llvm::Twine(error_msg)) .str()); diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h index 0712b3bf4a3e..905623e575f7 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h @@ -10,7 +10,6 @@ #define LLDB_INTERPRETER_SCRIPTEDPROCESSINTERFACE_H #include "lldb/Core/StructuredDataImpl.h" -#include "lldb/Interpreter/ScriptInterpreter.h" #include "lldb/Interpreter/ScriptedInterface.h" #include "lldb/Target/MemoryRegionInfo.h" @@ -57,7 +56,7 @@ public: return nullptr; } - virtual StructuredData::DictionarySP GetLoadedImages() { return nullptr; } + virtual StructuredData::ArraySP GetLoadedImages() { return nullptr; } virtual lldb::pid_t GetProcessID() { return LLDB_INVALID_PROCESS_ID; } diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/CompactUnwindInfo.h b/contrib/llvm-project/lldb/include/lldb/Symbol/CompactUnwindInfo.h index 402155cbe08d..e38d0123ea7c 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/CompactUnwindInfo.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/CompactUnwindInfo.h @@ -86,7 +86,7 @@ private: // valid for (start of the function) uint32_t valid_range_offset_end = 0; // the offset of the start of the next function - FunctionInfo() {} + FunctionInfo() = default; }; struct UnwindHeader { @@ -138,9 +138,10 @@ private: ObjectFile &m_objfile; lldb::SectionSP m_section_sp; - lldb::DataBufferSP m_section_contents_if_encrypted; // if the binary is - // encrypted, read the - // sect contents + lldb::WritableDataBufferSP + m_section_contents_if_encrypted; // if the binary is + // encrypted, read the + // sect contents // out of live memory and cache them here std::mutex m_mutex; std::vector<UnwindIndex> m_indexes; diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/DWARFCallFrameInfo.h b/contrib/llvm-project/lldb/include/lldb/Symbol/DWARFCallFrameInfo.h index 43baf4dd39a1..199d23eff9b6 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/DWARFCallFrameInfo.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/DWARFCallFrameInfo.h @@ -106,7 +106,8 @@ private: CIE(dw_offset_t offset) : cie_offset(offset), version(-1), code_align(0), data_align(0), return_addr_reg_num(LLDB_INVALID_REGNUM), inst_offset(0), - inst_length(0), ptr_encoding(0), lsda_addr_encoding(DW_EH_PE_omit), + inst_length(0), ptr_encoding(0), + lsda_addr_encoding(llvm::dwarf::DW_EH_PE_omit), personality_loc(LLDB_INVALID_ADDRESS) {} }; diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/LineTable.h b/contrib/llvm-project/lldb/include/lldb/Symbol/LineTable.h index b5121b29fe02..7fca44b5930b 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/LineTable.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/LineTable.h @@ -350,9 +350,9 @@ private: if (!line_entry_ptr) return best_match; - const uint32_t line = src_location_spec.GetLine().getValueOr(0); + const uint32_t line = src_location_spec.GetLine().value_or(0); const uint16_t column = - src_location_spec.GetColumn().getValueOr(LLDB_INVALID_COLUMN_NUMBER); + src_location_spec.GetColumn().value_or(LLDB_INVALID_COLUMN_NUMBER); const bool exact_match = src_location_spec.GetExactMatch(); for (size_t idx = start_idx; idx < count; ++idx) { diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/LocateSymbolFile.h b/contrib/llvm-project/lldb/include/lldb/Symbol/LocateSymbolFile.h index 2c3f6a7b7b59..f3d0feea4ecc 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/LocateSymbolFile.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/LocateSymbolFile.h @@ -13,6 +13,7 @@ #include "lldb/Core/FileSpecList.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/Status.h" namespace lldb_private { @@ -50,6 +51,7 @@ public: // enabled the external program before calling. // static bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec, + Status &error, bool force_lookup = true); }; diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/ObjectFile.h b/contrib/llvm-project/lldb/include/lldb/Symbol/ObjectFile.h index 8bf047cd4514..c61e3c138944 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/ObjectFile.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/ObjectFile.h @@ -116,10 +116,10 @@ public: /// more than one architecture or object. ObjectFile(const lldb::ModuleSP &module_sp, const FileSpec *file_spec_ptr, lldb::offset_t file_offset, lldb::offset_t length, - const lldb::DataBufferSP &data_sp, lldb::offset_t data_offset); + lldb::DataBufferSP data_sp, lldb::offset_t data_offset); ObjectFile(const lldb::ModuleSP &module_sp, const lldb::ProcessSP &process_sp, - lldb::addr_t header_addr, lldb::DataBufferSP &data_sp); + lldb::addr_t header_addr, lldb::DataBufferSP data_sp); /// Destructor. /// @@ -183,7 +183,7 @@ public: static lldb::ObjectFileSP FindPlugin(const lldb::ModuleSP &module_sp, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr, - lldb::DataBufferSP &file_data_sp); + lldb::WritableDataBufferSP file_data_sp); static size_t GetModuleSpecifications(const FileSpec &file, lldb::offset_t file_offset, @@ -759,6 +759,9 @@ protected: /// false otherwise. bool SetModulesArchitecture(const ArchSpec &new_arch); + /// The number of bytes to read when going through the plugins. + static size_t g_initial_bytes_to_read; + static lldb::DataBufferSP MapFileData(const FileSpec &file, uint64_t Size, uint64_t Offset); diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolFile.h b/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolFile.h index 6cdb2bfb686b..1470b96f2491 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolFile.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolFile.h @@ -9,6 +9,7 @@ #ifndef LLDB_SYMBOL_SYMBOLFILE_H #define LLDB_SYMBOL_SYMBOLFILE_H +#include "lldb/Core/ModuleList.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Core/SourceLocationSpec.h" #include "lldb/Symbol/CompilerDecl.h" @@ -35,6 +36,12 @@ namespace lldb_private { +/// Provides public interface for all SymbolFiles. Any protected +/// virtual members should go into SymbolFileCommon; most SymbolFile +/// implementations should inherit from SymbolFileCommon to override +/// the behaviors except SymbolFileOnDemand which inherits +/// public interfaces from SymbolFile and forward to underlying concrete +/// SymbolFile implementation. class SymbolFile : public PluginInterface { /// LLVM RTTI support. static char ID; @@ -66,11 +73,14 @@ public: static SymbolFile *FindPlugin(lldb::ObjectFileSP objfile_sp); // Constructors and Destructors - SymbolFile(lldb::ObjectFileSP objfile_sp) - : m_objfile_sp(std::move(objfile_sp)) {} + SymbolFile() = default; ~SymbolFile() override = default; + /// SymbolFileOnDemand class overrides this to return the underlying + /// backing SymbolFile implementation that loads on-demand. + virtual SymbolFile *GetBackingSymbolFile() { return this; } + /// Get a mask of what this symbol file supports for the object file /// that it was constructed with. /// @@ -98,15 +108,7 @@ public: /// A uint32_t mask containing bits from the SymbolFile::Abilities /// enumeration. Any bits that are set represent an ability that /// this symbol plug-in can parse from the object file. - uint32_t GetAbilities() { - if (!m_calculated_abilities) { - m_abilities = CalculateAbilities(); - m_calculated_abilities = true; - } - - return m_abilities; - } - + virtual uint32_t GetAbilities() = 0; virtual uint32_t CalculateAbilities() = 0; /// Symbols file subclasses should override this to return the Module that @@ -122,12 +124,22 @@ public: /// prior to any other functions in the SymbolFile protocol. virtual void InitializeObject() {} + /// Whether debug info will be loaded or not. + /// + /// It will be true for most implementations except SymbolFileOnDemand. + virtual bool GetLoadDebugInfoEnabled() { return true; } + + /// Specify debug info should be loaded. + /// + /// It will be no-op for most implementations except SymbolFileOnDemand. + virtual void SetLoadDebugInfoEnabled() { return; } + // Compile Unit function calls // Approach 1 - iterator - uint32_t GetNumCompileUnits(); - lldb::CompUnitSP GetCompileUnitAtIndex(uint32_t idx); + virtual uint32_t GetNumCompileUnits() = 0; + virtual lldb::CompUnitSP GetCompileUnitAtIndex(uint32_t idx) = 0; - Symtab *GetSymtab(); + virtual Symtab *GetSymtab() = 0; virtual lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) = 0; /// Return the Xcode SDK comp_unit was compiled against. @@ -255,16 +267,16 @@ public: virtual void PreloadSymbols(); virtual llvm::Expected<lldb_private::TypeSystem &> - GetTypeSystemForLanguage(lldb::LanguageType language); + GetTypeSystemForLanguage(lldb::LanguageType language) = 0; virtual CompilerDeclContext FindNamespace(ConstString name, const CompilerDeclContext &parent_decl_ctx) { return CompilerDeclContext(); } - ObjectFile *GetObjectFile() { return m_objfile_sp.get(); } - const ObjectFile *GetObjectFile() const { return m_objfile_sp.get(); } - ObjectFile *GetMainObjectFile(); + virtual ObjectFile *GetObjectFile() = 0; + virtual const ObjectFile *GetObjectFile() const = 0; + virtual ObjectFile *GetMainObjectFile() = 0; virtual std::vector<std::unique_ptr<CallEdge>> ParseCallEdgesInFunction(UserID func_id) { @@ -275,7 +287,7 @@ public: /// Notify the SymbolFile that the file addresses in the Sections /// for this module have been changed. - virtual void SectionFileAddressesChanged(); + virtual void SectionFileAddressesChanged() = 0; struct RegisterInfoResolver { virtual ~RegisterInfoResolver(); // anchor @@ -296,7 +308,7 @@ public: "Operation not supported."); } - virtual void Dump(Stream &s); + virtual void Dump(Stream &s) = 0; /// Metrics gathering functions @@ -310,7 +322,7 @@ public: /// entire file should be returned. The default implementation of this /// function will iterate over all sections in a module and add up their /// debug info only section byte sizes. - virtual uint64_t GetDebugInfoSize(); + virtual uint64_t GetDebugInfoSize() = 0; /// Return the time taken to parse the debug information. /// @@ -325,6 +337,15 @@ public: /// hasn't been indexed yet, or a valid duration if it has. virtual StatsDuration::Duration GetDebugInfoIndexTime() { return {}; } + /// Get the additional modules that this symbol file uses to parse debug info. + /// + /// Some debug info is stored in stand alone object files that are represented + /// by unique modules that will show up in the statistics module list. Return + /// a list of modules that are not in the target module list that this symbol + /// file is currently using so that they can be tracked and assoicated with + /// the module in the statistics. + virtual ModuleList GetDebugInfoModules() { return ModuleList(); } + /// Accessors for the bool that indicates if the debug info index was loaded /// from, or saved to the module index cache. /// @@ -334,26 +355,90 @@ public: /// index is saved to the cache, debug sessions can be slower. These accessors /// can be accessed by the statistics and emitted to help track these costs. /// \{ - bool GetDebugInfoIndexWasLoadedFromCache() const { + virtual bool GetDebugInfoIndexWasLoadedFromCache() const = 0; + virtual void SetDebugInfoIndexWasLoadedFromCache() = 0; + virtual bool GetDebugInfoIndexWasSavedToCache() const = 0; + virtual void SetDebugInfoIndexWasSavedToCache() = 0; + /// \} + +protected: + void AssertModuleLock(); + +private: + SymbolFile(const SymbolFile &) = delete; + const SymbolFile &operator=(const SymbolFile &) = delete; +}; + +/// Containing protected virtual methods for child classes to override. +/// Most actual SymbolFile implementations should inherit from this class. +class SymbolFileCommon : public SymbolFile { + /// LLVM RTTI support. + static char ID; + +public: + /// LLVM RTTI support. + /// \{ + bool isA(const void *ClassID) const override { + return ClassID == &ID || SymbolFile::isA(ClassID); + } + static bool classof(const SymbolFileCommon *obj) { return obj->isA(&ID); } + /// \} + + // Constructors and Destructors + SymbolFileCommon(lldb::ObjectFileSP objfile_sp) + : m_objfile_sp(std::move(objfile_sp)) {} + + ~SymbolFileCommon() override = default; + + uint32_t GetAbilities() override { + if (!m_calculated_abilities) { + m_abilities = CalculateAbilities(); + m_calculated_abilities = true; + } + return m_abilities; + } + + Symtab *GetSymtab() override; + + ObjectFile *GetObjectFile() override { return m_objfile_sp.get(); } + const ObjectFile *GetObjectFile() const override { + return m_objfile_sp.get(); + } + ObjectFile *GetMainObjectFile() override; + + /// Notify the SymbolFile that the file addresses in the Sections + /// for this module have been changed. + void SectionFileAddressesChanged() override; + + // Compile Unit function calls + // Approach 1 - iterator + uint32_t GetNumCompileUnits() override; + lldb::CompUnitSP GetCompileUnitAtIndex(uint32_t idx) override; + + llvm::Expected<lldb_private::TypeSystem &> + GetTypeSystemForLanguage(lldb::LanguageType language) override; + + void Dump(Stream &s) override; + + uint64_t GetDebugInfoSize() override; + + bool GetDebugInfoIndexWasLoadedFromCache() const override { return m_index_was_loaded_from_cache; } - void SetDebugInfoIndexWasLoadedFromCache() { + void SetDebugInfoIndexWasLoadedFromCache() override { m_index_was_loaded_from_cache = true; } - bool GetDebugInfoIndexWasSavedToCache() const { + bool GetDebugInfoIndexWasSavedToCache() const override { return m_index_was_saved_to_cache; } - void SetDebugInfoIndexWasSavedToCache() { + void SetDebugInfoIndexWasSavedToCache() override { m_index_was_saved_to_cache = true; } - /// \} protected: - void AssertModuleLock(); virtual uint32_t CalculateNumCompileUnits() = 0; virtual lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t idx) = 0; virtual TypeList &GetTypeList() { return m_type_list; } - void SetCompileUnitAtIndex(uint32_t idx, const lldb::CompUnitSP &cu_sp); lldb::ObjectFileSP m_objfile_sp; // Keep a reference to the object file in @@ -369,8 +454,8 @@ protected: bool m_index_was_saved_to_cache = false; private: - SymbolFile(const SymbolFile &) = delete; - const SymbolFile &operator=(const SymbolFile &) = delete; + SymbolFileCommon(const SymbolFileCommon &) = delete; + const SymbolFileCommon &operator=(const SymbolFileCommon &) = delete; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolFileOnDemand.h b/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolFileOnDemand.h new file mode 100644 index 000000000000..e47872c9761c --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolFileOnDemand.h @@ -0,0 +1,235 @@ +//===-- SymbolFileOnDemand.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_SYMBOL_SYMBOLFILEONDEMAND_H +#define LLDB_SYMBOL_SYMBOLFILEONDEMAND_H + +#include <mutex> +#include <vector> + +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/SymbolFile.h" +#include "lldb/Target/Statistics.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/Flags.h" +#include "lldb/Utility/LLDBLog.h" +#include "lldb/Utility/Log.h" +#include "lldb/lldb-private.h" + +namespace lldb_private { + +/// SymbolFileOnDemand wraps an actual SymbolFile by providing +/// on demand symbol parsing/indexing to improve performance. +/// By default SymbolFileOnDemand will skip load the underlying +/// symbols. Any client can on demand hydrate the underlying +/// SymbolFile via SymbolFile::SetLoadDebugInfoEnabled(). +class SymbolFileOnDemand : public lldb_private::SymbolFile { + /// LLVM RTTI support. + static char ID; + +public: + /// LLVM RTTI support. + /// \{ + bool isA(const void *ClassID) const override { + return ClassID == &ID || SymbolFile::isA(ClassID); + } + static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } + /// \} + + SymbolFileOnDemand(std::unique_ptr<SymbolFile> &&symbol_file); + ~SymbolFileOnDemand() override; + + // PluginInterface protocol + llvm::StringRef GetPluginName() override { return "ondemand"; } + + bool GetLoadDebugInfoEnabled() override { return m_debug_info_enabled; } + + void SetLoadDebugInfoEnabled() override; + + uint32_t GetNumCompileUnits() override; + lldb::CompUnitSP GetCompileUnitAtIndex(uint32_t idx) override; + + SymbolFile *GetBackingSymbolFile() override { return m_sym_file_impl.get(); } + + uint32_t CalculateAbilities() override; + + std::recursive_mutex &GetModuleMutex() const override; + + lldb::LanguageType + ParseLanguage(lldb_private::CompileUnit &comp_unit) override; + + lldb_private::XcodeSDK + ParseXcodeSDK(lldb_private::CompileUnit &comp_unit) override; + + void InitializeObject() override; + + size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override; + + bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override; + + bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override; + + bool ForEachExternalModule( + lldb_private::CompileUnit &, llvm::DenseSet<lldb_private::SymbolFile *> &, + llvm::function_ref<bool(lldb_private::Module &)>) override; + + bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit, + lldb_private::FileSpecList &support_files) override; + + bool ParseIsOptimized(lldb_private::CompileUnit &comp_unit) override; + + size_t ParseTypes(lldb_private::CompileUnit &comp_unit) override; + + bool ParseImportedModules( + const lldb_private::SymbolContext &sc, + std::vector<lldb_private::SourceModule> &imported_modules) override; + + size_t ParseBlocksRecursive(lldb_private::Function &func) override; + + size_t + ParseVariablesForContext(const lldb_private::SymbolContext &sc) override; + + lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override; + llvm::Optional<ArrayInfo> GetDynamicArrayInfoForUID( + lldb::user_id_t type_uid, + const lldb_private::ExecutionContext *exe_ctx) override; + + bool CompleteType(lldb_private::CompilerType &compiler_type) override; + + lldb_private::CompilerDecl GetDeclForUID(lldb::user_id_t uid) override; + + lldb_private::CompilerDeclContext + GetDeclContextForUID(lldb::user_id_t uid) override; + + lldb_private::CompilerDeclContext + GetDeclContextContainingUID(lldb::user_id_t uid) override; + + void + ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override; + + uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr, + lldb::SymbolContextItem resolve_scope, + lldb_private::SymbolContext &sc) override; + + uint32_t ResolveSymbolContext( + const lldb_private::SourceLocationSpec &src_location_spec, + lldb::SymbolContextItem resolve_scope, + lldb_private::SymbolContextList &sc_list) override; + + void Dump(lldb_private::Stream &s) override; + void DumpClangAST(lldb_private::Stream &s) override; + + void + FindGlobalVariables(lldb_private::ConstString name, + const lldb_private::CompilerDeclContext &parent_decl_ctx, + uint32_t max_matches, + lldb_private::VariableList &variables) override; + + void FindGlobalVariables(const lldb_private::RegularExpression ®ex, + uint32_t max_matches, + lldb_private::VariableList &variables) override; + + void FindFunctions(lldb_private::ConstString name, + const lldb_private::CompilerDeclContext &parent_decl_ctx, + lldb::FunctionNameType name_type_mask, + bool include_inlines, + lldb_private::SymbolContextList &sc_list) override; + + void FindFunctions(const lldb_private::RegularExpression ®ex, + bool include_inlines, + lldb_private::SymbolContextList &sc_list) override; + + void GetMangledNamesForFunction( + const std::string &scope_qualified_name, + std::vector<lldb_private::ConstString> &mangled_names) override; + + void + FindTypes(lldb_private::ConstString name, + const lldb_private::CompilerDeclContext &parent_decl_ctx, + uint32_t max_matches, + llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, + lldb_private::TypeMap &types) override; + + void FindTypes(llvm::ArrayRef<lldb_private::CompilerContext> pattern, + lldb_private::LanguageSet languages, + llvm::DenseSet<SymbolFile *> &searched_symbol_files, + lldb_private::TypeMap &types) override; + + void GetTypes(lldb_private::SymbolContextScope *sc_scope, + lldb::TypeClass type_mask, + lldb_private::TypeList &type_list) override; + + llvm::Expected<lldb_private::TypeSystem &> + GetTypeSystemForLanguage(lldb::LanguageType language) override; + + lldb_private::CompilerDeclContext FindNamespace( + lldb_private::ConstString name, + const lldb_private::CompilerDeclContext &parent_decl_ctx) override; + + std::vector<std::unique_ptr<lldb_private::CallEdge>> + ParseCallEdgesInFunction(UserID func_id) override; + + lldb::UnwindPlanSP + GetUnwindPlan(const Address &address, + const RegisterInfoResolver &resolver) override; + + llvm::Expected<lldb::addr_t> GetParameterStackSize(Symbol &symbol) override; + + void PreloadSymbols() override; + + uint64_t GetDebugInfoSize() override; + lldb_private::StatsDuration::Duration GetDebugInfoParseTime() override; + lldb_private::StatsDuration::Duration GetDebugInfoIndexTime() override; + + uint32_t GetAbilities() override; + + Symtab *GetSymtab() override { return m_sym_file_impl->GetSymtab(); } + + ObjectFile *GetObjectFile() override { + return m_sym_file_impl->GetObjectFile(); + } + const ObjectFile *GetObjectFile() const override { + return m_sym_file_impl->GetObjectFile(); + } + ObjectFile *GetMainObjectFile() override { + return m_sym_file_impl->GetMainObjectFile(); + } + + void SectionFileAddressesChanged() override { + return m_sym_file_impl->SectionFileAddressesChanged(); + } + + bool GetDebugInfoIndexWasLoadedFromCache() const override { + return m_sym_file_impl->GetDebugInfoIndexWasLoadedFromCache(); + } + void SetDebugInfoIndexWasLoadedFromCache() override { + m_sym_file_impl->SetDebugInfoIndexWasLoadedFromCache(); + } + bool GetDebugInfoIndexWasSavedToCache() const override { + return m_sym_file_impl->GetDebugInfoIndexWasSavedToCache(); + } + void SetDebugInfoIndexWasSavedToCache() override { + m_sym_file_impl->SetDebugInfoIndexWasSavedToCache(); + } + +private: + Log *GetLog() const { return ::lldb_private::GetLog(LLDBLog::OnDemand); } + + ConstString GetSymbolFileName() { + return GetObjectFile()->GetFileSpec().GetFilename(); + } + +private: + bool m_debug_info_enabled = false; + bool m_preload_symbols = false; + std::unique_ptr<SymbolFile> m_sym_file_impl; +}; +} // namespace lldb_private + +#endif // LLDB_SYMBOL_SYMBOLFILEONDEMAND_H diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/Type.h b/contrib/llvm-project/lldb/include/lldb/Symbol/Type.h index 24b94921df94..4b512de0fabf 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/Type.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/Type.h @@ -314,7 +314,7 @@ private: class TypeListImpl { public: - TypeListImpl() {} + TypeListImpl() = default; void Append(const lldb::TypeImplSP &type) { m_content.push_back(type); } @@ -345,7 +345,7 @@ private: class TypeMemberImpl { public: - TypeMemberImpl() {} + TypeMemberImpl() = default; TypeMemberImpl(const lldb::TypeImplSP &type_impl_sp, uint64_t bit_offset, ConstString name, uint32_t bitfield_bit_size = 0, @@ -437,7 +437,7 @@ private: class TypeMemberFunctionImpl { public: - TypeMemberFunctionImpl() {} + TypeMemberFunctionImpl() = default; TypeMemberFunctionImpl(const CompilerType &type, const CompilerDecl &decl, const std::string &name, @@ -502,7 +502,7 @@ protected: class TypeEnumMemberListImpl { public: - TypeEnumMemberListImpl() {} + TypeEnumMemberListImpl() = default; void Append(const lldb::TypeEnumMemberImplSP &type) { m_content.push_back(type); diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/Variable.h b/contrib/llvm-project/lldb/include/lldb/Symbol/Variable.h index ccd5072c3d23..88a975df3992 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/Variable.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/Variable.h @@ -77,7 +77,9 @@ public: const DWARFExpression &LocationExpression() const { return m_location; } - bool DumpLocationForAddress(Stream *s, const Address &address); + // When given invalid address, it dumps all locations. Otherwise it only dumps + // the location that contains this address. + bool DumpLocations(Stream *s, const Address &address); size_t MemorySize() const; diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ABI.h b/contrib/llvm-project/lldb/include/lldb/Target/ABI.h index 8ac6003554d5..f0753172d3e7 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/ABI.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/ABI.h @@ -126,6 +126,20 @@ public: virtual lldb::addr_t FixDataAddress(lldb::addr_t pc) { return pc; } /// @} + /// Use this method when you do not know, or do not care what kind of address + /// you are fixing. On platforms where there would be a difference between the + /// two types, it will pick the safest option. + /// + /// Its purpose is to signal that no specific choice was made and provide an + /// alternative to randomly picking FixCode/FixData address. Which could break + /// platforms where there is a difference (only Arm Thumb at this time). + virtual lldb::addr_t FixAnyAddress(lldb::addr_t pc) { + // On Arm Thumb fixing a code address zeroes the bottom bit, so FixData is + // the safe choice. On any other platform (so far) code and data addresses + // are fixed in the same way. + return FixDataAddress(pc); + } + llvm::MCRegisterInfo &GetMCRegisterInfo() { return *m_mc_register_info_up; } virtual void diff --git a/contrib/llvm-project/lldb/include/lldb/Target/DynamicLoader.h b/contrib/llvm-project/lldb/include/lldb/Target/DynamicLoader.h index 84ad0f11fabb..397b4aa30344 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/DynamicLoader.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/DynamicLoader.h @@ -203,6 +203,8 @@ public: /// Locates or creates a module given by \p file and updates/loads the /// resulting module at the virtual base address \p base_addr. + /// Note that this calls Target::GetOrCreateModule with notify being false, + /// so it is necessary to call Target::ModulesDidLoad afterwards. virtual lldb::ModuleSP LoadModuleAtAddress(const lldb_private::FileSpec &file, lldb::addr_t link_map_addr, lldb::addr_t base_addr, @@ -263,6 +265,8 @@ public: protected: // Utility methods for derived classes + lldb::ModuleSP FindModuleViaTarget(const FileSpec &file); + /// Checks to see if the target module has changed, updates the target /// accordingly and returns the target executable module. lldb::ModuleSP GetTargetExecutable(); diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Language.h b/contrib/llvm-project/lldb/include/lldb/Target/Language.h index ce2d273a8277..fa79aaee0574 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/Language.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/Language.h @@ -217,6 +217,17 @@ public: std::string &prefix, std::string &suffix); + // When looking up functions, we take a user provided string which may be a + // partial match to the full demangled name and compare it to the actual + // demangled name to see if it matches as much as the user specified. An + // example of this is if the user provided A::my_function, but the + // symbol was really B::A::my_function. We want that to be + // a match. But we wouldn't want this to match AnotherA::my_function. The + // user is specifying a truncated path, not a truncated set of characters. + // This function does a language-aware comparison for those purposes. + virtual bool DemangledNameContainsPath(llvm::StringRef path, + ConstString demangled) const; + // if a language has a custom format for printing variable declarations that // it wants LLDB to honor it should return an appropriate closure here virtual DumpValueObjectOptions::DeclPrintingHelper GetDeclPrintingHelper(); diff --git a/contrib/llvm-project/lldb/include/lldb/Target/LanguageRuntime.h b/contrib/llvm-project/lldb/include/lldb/Target/LanguageRuntime.h index ba96d080f908..0cdb02a44901 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/LanguageRuntime.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/LanguageRuntime.h @@ -154,7 +154,7 @@ public: return llvm::None; } - virtual void ModulesDidLoad(const ModuleList &module_list) override {} + void ModulesDidLoad(const ModuleList &module_list) override {} // Called by ClangExpressionParser::PrepareForExecution to query for any // custom LLVM IR passes that need to be run before an expression is diff --git a/contrib/llvm-project/lldb/include/lldb/Target/MemoryRegionInfo.h b/contrib/llvm-project/lldb/include/lldb/Target/MemoryRegionInfo.h index eb56ca0ea131..3ef66b403e14 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/MemoryRegionInfo.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/MemoryRegionInfo.h @@ -26,12 +26,14 @@ public: MemoryRegionInfo() = default; MemoryRegionInfo(RangeType range, OptionalBool read, OptionalBool write, - OptionalBool execute, OptionalBool mapped, ConstString name, + OptionalBool execute, OptionalBool shared, + OptionalBool mapped, ConstString name, OptionalBool flash, lldb::offset_t blocksize, OptionalBool memory_tagged, OptionalBool stack_memory) : m_range(range), m_read(read), m_write(write), m_execute(execute), - m_mapped(mapped), m_name(name), m_flash(flash), m_blocksize(blocksize), - m_memory_tagged(memory_tagged), m_is_stack_memory(stack_memory) {} + m_shared(shared), m_mapped(mapped), m_name(name), m_flash(flash), + m_blocksize(blocksize), m_memory_tagged(memory_tagged), + m_is_stack_memory(stack_memory) {} RangeType &GetRange() { return m_range; } @@ -45,6 +47,8 @@ public: OptionalBool GetExecutable() const { return m_execute; } + OptionalBool GetShared() const { return m_shared; } + OptionalBool GetMapped() const { return m_mapped; } ConstString GetName() const { return m_name; } @@ -57,6 +61,8 @@ public: void SetExecutable(OptionalBool val) { m_execute = val; } + void SetShared(OptionalBool val) { m_shared = val; } + void SetMapped(OptionalBool val) { m_mapped = val; } void SetName(const char *name) { m_name = ConstString(name); } @@ -95,6 +101,7 @@ public: bool operator==(const MemoryRegionInfo &rhs) const { return m_range == rhs.m_range && m_read == rhs.m_read && m_write == rhs.m_write && m_execute == rhs.m_execute && + m_shared == rhs.m_shared && 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 && @@ -107,13 +114,13 @@ public: /// Get the target system's VM page size in bytes. /// \return /// 0 is returned if this information is unavailable. - int GetPageSize() { return m_pagesize; } + int GetPageSize() const { 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() { + const llvm::Optional<std::vector<lldb::addr_t>> &GetDirtyPageList() const { return m_dirty_pages; } @@ -124,7 +131,7 @@ public: void SetPageSize(int pagesize) { m_pagesize = pagesize; } void SetDirtyPageList(std::vector<lldb::addr_t> pagelist) { - if (m_dirty_pages.hasValue()) + if (m_dirty_pages) m_dirty_pages.getValue().clear(); m_dirty_pages = std::move(pagelist); } @@ -134,6 +141,7 @@ protected: OptionalBool m_read = eDontKnow; OptionalBool m_write = eDontKnow; OptionalBool m_execute = eDontKnow; + OptionalBool m_shared = eDontKnow; OptionalBool m_mapped = eDontKnow; ConstString m_name; OptionalBool m_flash = eDontKnow; @@ -163,7 +171,7 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, // Forward-declarable wrapper. class MemoryRegionInfos : public std::vector<lldb_private::MemoryRegionInfo> { public: - //using std::vector<lldb_private::MemoryRegionInfo>::vector; + using std::vector<lldb_private::MemoryRegionInfo>::vector; }; } diff --git a/contrib/llvm-project/lldb/include/lldb/Target/MemoryTagManager.h b/contrib/llvm-project/lldb/include/lldb/Target/MemoryTagManager.h index 859c43cb437a..28a8acc34632 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/MemoryTagManager.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/MemoryTagManager.h @@ -144,7 +144,7 @@ public: RepeatTagsForRange(const std::vector<lldb::addr_t> &tags, TagRange range) const = 0; - virtual ~MemoryTagManager() {} + virtual ~MemoryTagManager() = default; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Platform.h b/contrib/llvm-project/lldb/include/lldb/Target/Platform.h index 4ef6c9d82b1a..aa09b345e4e1 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/Platform.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/Platform.h @@ -94,20 +94,11 @@ public: /// attaching to processes unless another platform is specified. static lldb::PlatformSP GetHostPlatform(); - static lldb::PlatformSP - GetPlatformForArchitecture(const ArchSpec &arch, ArchSpec *platform_arch_ptr); - static const char *GetHostPlatformName(); static void SetHostPlatform(const lldb::PlatformSP &platform_sp); - // Find an existing platform plug-in by name - static lldb::PlatformSP Find(ConstString name); - - static lldb::PlatformSP Create(ConstString name, Status &error); - - static lldb::PlatformSP Create(const ArchSpec &arch, - ArchSpec *platform_arch_ptr, Status &error); + static lldb::PlatformSP Create(llvm::StringRef name); /// Augments the triple either with information from platform or the host /// system (if platform is null). @@ -217,7 +208,7 @@ public: llvm::Optional<std::string> GetOSKernelDescription(); // Returns the name of the platform - ConstString GetName(); + llvm::StringRef GetName() { return GetPluginName(); } virtual const char *GetHostname(); @@ -257,7 +248,7 @@ public: virtual bool SetRemoteWorkingDirectory(const FileSpec &working_dir); - virtual UserIDResolver &GetUserIDResolver() = 0; + virtual UserIDResolver &GetUserIDResolver(); /// Locate a file for a platform. /// @@ -310,7 +301,12 @@ public: /// Get the platform's supported architectures in the order in which they /// should be searched. - virtual std::vector<ArchSpec> GetSupportedArchitectures() = 0; + /// + /// \param[in] process_host_arch + /// The process host architecture if it's known. An invalid ArchSpec + /// represents that the process host architecture is unknown. + virtual std::vector<ArchSpec> + GetSupportedArchitectures(const ArchSpec &process_host_arch) = 0; virtual size_t GetSoftwareBreakpointTrapOpcode(Target &target, BreakpointSite *bp_site); @@ -332,6 +328,7 @@ public: /// Lets a platform answer if it is compatible with a given architecture and /// the target triple contained within. virtual bool IsCompatibleArchitecture(const ArchSpec &arch, + const ArchSpec &process_host_arch, bool exact_arch_match, ArchSpec *compatible_arch_ptr); @@ -493,34 +490,20 @@ public: virtual lldb::user_id_t OpenFile(const FileSpec &file_spec, File::OpenOptions flags, uint32_t mode, - Status &error) { - return UINT64_MAX; - } + Status &error); - virtual bool CloseFile(lldb::user_id_t fd, Status &error) { return false; } + virtual bool CloseFile(lldb::user_id_t fd, Status &error); - virtual lldb::user_id_t GetFileSize(const FileSpec &file_spec) { - return UINT64_MAX; - } + virtual lldb::user_id_t GetFileSize(const FileSpec &file_spec); virtual void AutoCompleteDiskFileOrDirectory(CompletionRequest &request, bool only_dir) {} virtual uint64_t ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst, - uint64_t dst_len, Status &error) { - error.SetErrorStringWithFormat( - "Platform::ReadFile() is not supported in the %s platform", - GetName().GetCString()); - return -1; - } + uint64_t dst_len, Status &error); virtual uint64_t WriteFile(lldb::user_id_t fd, uint64_t offset, - const void *src, uint64_t src_len, Status &error) { - error.SetErrorStringWithFormat( - "Platform::WriteFile() is not supported in the %s platform", - GetName().GetCString()); - return -1; - } + const void *src, uint64_t src_len, Status &error); virtual Status GetFile(const FileSpec &source, const FileSpec &destination); @@ -864,6 +847,8 @@ public: } virtual CompilerType GetSiginfoType(const llvm::Triple &triple); + + virtual Args GetExtraStartupCommands(); protected: /// Create a list of ArchSpecs with the given OS and a architectures. The @@ -892,7 +877,7 @@ protected: FileSpec m_working_dir; // The working directory which is used when installing // modules that have no install path set std::string m_remote_url; - std::string m_name; + std::string m_hostname; llvm::VersionTuple m_os_version; ArchSpec m_system_arch; // The architecture of the kernel or the remote platform @@ -960,7 +945,7 @@ private: class PlatformList { public: - PlatformList() {} + PlatformList() = default; ~PlatformList() = default; @@ -1015,6 +1000,32 @@ public: } } + lldb::PlatformSP GetOrCreate(llvm::StringRef name); + lldb::PlatformSP GetOrCreate(const ArchSpec &arch, + const ArchSpec &process_host_arch, + ArchSpec *platform_arch_ptr, Status &error); + lldb::PlatformSP GetOrCreate(const ArchSpec &arch, + const ArchSpec &process_host_arch, + ArchSpec *platform_arch_ptr); + + /// Get the platform for the given list of architectures. + /// + /// The algorithm works a follows: + /// + /// 1. Returns the selected platform if it matches any of the architectures. + /// 2. Returns the host platform if it matches any of the architectures. + /// 3. Returns the platform that matches all the architectures. + /// + /// If none of the above apply, this function returns a default platform. The + /// candidates output argument differentiates between either no platforms + /// supporting the given architecture or multiple platforms supporting the + /// given architecture. + lldb::PlatformSP GetOrCreate(llvm::ArrayRef<ArchSpec> archs, + const ArchSpec &process_host_arch, + std::vector<lldb::PlatformSP> &candidates); + + lldb::PlatformSP Create(llvm::StringRef name); + protected: typedef std::vector<lldb::PlatformSP> collection; mutable std::recursive_mutex m_mutex; diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Process.h b/contrib/llvm-project/lldb/include/lldb/Target/Process.h index 7911dac40b70..a55659225ef1 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/Process.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/Process.h @@ -112,7 +112,7 @@ protected: class ProcessAttachInfo : public ProcessInstanceInfo { public: - ProcessAttachInfo() {} + ProcessAttachInfo() = default; ProcessAttachInfo(const ProcessLaunchInfo &launch_info) : m_resume_count(0), m_wait_for_launch(false), m_ignore_existing(true), @@ -365,9 +365,6 @@ public: eBroadcastInternalStateControlResume = (1 << 2) }; - /// Process warning types. - enum Warnings { eWarningsOptimization = 1, eWarningsUnsupportedLanguage = 2 }; - typedef Range<lldb::addr_t, lldb::addr_t> LoadRange; // We use a read/write lock to allow on or more clients to access the process // state while the process is stopped (reader). We lock the write lock to @@ -696,6 +693,9 @@ protected: virtual JITLoaderList &GetJITLoaders(); public: + /// Get the system architecture for this process. + virtual ArchSpec GetSystemArchitecture() { return {}; } + /// Get the system runtime plug-in for this process. /// /// \return @@ -2634,35 +2634,6 @@ protected: // Called internally void CompleteAttach(); - /// Print a user-visible warning one time per Process - /// - /// A facility for printing a warning to the user once per repeat_key. - /// - /// warning_type is from the Process::Warnings enums. repeat_key is a - /// pointer value that will be used to ensure that the warning message is - /// not printed multiple times. For instance, with a warning about a - /// function being optimized, you can pass the CompileUnit pointer to have - /// the warning issued for only the first function in a CU, or the Function - /// pointer to have it issued once for every function, or a Module pointer - /// to have it issued once per Module. - /// - /// Classes outside Process should call a specific PrintWarning method so - /// that the warning strings are all centralized in Process, instead of - /// calling PrintWarning() directly. - /// - /// \param [in] warning_type - /// One of the types defined in Process::Warnings. - /// - /// \param [in] repeat_key - /// A pointer value used to ensure that the warning is only printed once. - /// May be nullptr, indicating that the warning is printed unconditionally - /// every time. - /// - /// \param [in] fmt - /// printf style format string - void PrintWarning(uint64_t warning_type, const void *repeat_key, - const char *fmt, ...) __attribute__((format(printf, 4, 5))); - // NextEventAction provides a way to register an action on the next event // that is delivered to this process. There is currently only one next event // action allowed in the process at one time. If a new "NextEventAction" is @@ -2827,8 +2798,6 @@ protected: // Type definitions typedef std::map<lldb::LanguageType, lldb::LanguageRuntimeSP> LanguageRuntimeCollection; - typedef std::unordered_set<const void *> WarningsPointerSet; - typedef std::map<uint64_t, WarningsPointerSet> WarningsCollection; struct PreResumeCallbackAndBaton { bool (*callback)(void *); @@ -2958,11 +2927,9 @@ protected: /// ShouldBroadcastEvent. std::map<lldb::addr_t, lldb::addr_t> m_resolved_indirect_addresses; bool m_destroy_in_process; - bool m_can_interpret_function_calls; // Some targets, e.g the OSX kernel, - // don't support the ability to modify - // the stack. - WarningsCollection m_warnings_issued; // A set of object pointers which have - // already had warnings printed + bool m_can_interpret_function_calls; // Some targets, e.g the OSX kernel, + // don't support the ability to modify + // the stack. std::mutex m_run_thread_plan_lock; StructuredDataPluginMap m_structured_data_plugin_map; @@ -2989,17 +2956,6 @@ protected: void ResumePrivateStateThread(); private: - struct PrivateStateThreadArgs { - PrivateStateThreadArgs(Process *p, bool s) - : process(p), is_secondary_thread(s){}; - Process *process; - bool is_secondary_thread; - }; - - // arg is a pointer to a new'ed PrivateStateThreadArgs structure. - // PrivateStateThread will free it for you. - static lldb::thread_result_t PrivateStateThread(void *arg); - // The starts up the private state thread that will watch for events from the // debugee. Pass true for is_secondary_thread in the case where you have to // temporarily spin up a secondary state thread to handle events from a hand- @@ -3073,6 +3029,9 @@ private: void ControlPrivateStateThread(uint32_t signal); + Status LaunchPrivate(ProcessLaunchInfo &launch_info, lldb::StateType &state, + lldb::EventSP &event_sp); + Process(const Process &) = delete; const Process &operator=(const Process &) = delete; }; diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ProcessStructReader.h b/contrib/llvm-project/lldb/include/lldb/Target/ProcessStructReader.h index 0a91bef8048b..8046ef4958bb 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/ProcessStructReader.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/ProcessStructReader.h @@ -69,7 +69,7 @@ public: auto total_size = struct_type.GetByteSize(nullptr); if (!total_size) return; - lldb::DataBufferSP buffer_sp(new DataBufferHeap(*total_size, 0)); + lldb::WritableDataBufferSP buffer_sp(new DataBufferHeap(*total_size, 0)); Status error; process->ReadMemoryFromInferior(base_addr, buffer_sp->GetBytes(), *total_size, error); diff --git a/contrib/llvm-project/lldb/include/lldb/Target/RegisterCheckpoint.h b/contrib/llvm-project/lldb/include/lldb/Target/RegisterCheckpoint.h index 8681fb962801..bc92b239a517 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/RegisterCheckpoint.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/RegisterCheckpoint.h @@ -35,12 +35,12 @@ public: ~RegisterCheckpoint() = default; - lldb::DataBufferSP &GetData() { return m_data_sp; } + lldb::WritableDataBufferSP &GetData() { return m_data_sp; } - const lldb::DataBufferSP &GetData() const { return m_data_sp; } + const lldb::WritableDataBufferSP &GetData() const { return m_data_sp; } protected: - lldb::DataBufferSP m_data_sp; + lldb::WritableDataBufferSP m_data_sp; Reason m_reason; // Make RegisterCheckpointSP if you wish to share the data in this class. diff --git a/contrib/llvm-project/lldb/include/lldb/Target/RegisterContext.h b/contrib/llvm-project/lldb/include/lldb/Target/RegisterContext.h index 392b462ecf07..de0efd982daa 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/RegisterContext.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/RegisterContext.h @@ -43,7 +43,7 @@ public: virtual bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue ®_value) = 0; - virtual bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) { + virtual bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) { return false; } diff --git a/contrib/llvm-project/lldb/include/lldb/Target/RegisterContextUnwind.h b/contrib/llvm-project/lldb/include/lldb/Target/RegisterContextUnwind.h index edda281d5aa7..ef8ae8840386 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/RegisterContextUnwind.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/RegisterContextUnwind.h @@ -50,7 +50,7 @@ public: bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value) override; - bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; @@ -203,8 +203,7 @@ private: void UnwindLogMsgVerbose(const char *fmt, ...) __attribute__((format(printf, 2, 3))); - bool IsUnwindPlanValidForCurrentPC(lldb::UnwindPlanSP unwind_plan_sp, - int &valid_pc_offset); + bool IsUnwindPlanValidForCurrentPC(lldb::UnwindPlanSP unwind_plan_sp); lldb::addr_t GetReturnAddressHint(int32_t plan_offset); diff --git a/contrib/llvm-project/lldb/include/lldb/Target/SectionLoadHistory.h b/contrib/llvm-project/lldb/include/lldb/Target/SectionLoadHistory.h index 0240cebda85f..64bb828d4254 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/SectionLoadHistory.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/SectionLoadHistory.h @@ -24,7 +24,7 @@ public: eStopIDNow = UINT32_MAX }; // Constructors and Destructors - SectionLoadHistory() {} + SectionLoadHistory() = default; ~SectionLoadHistory() { // Call clear since this takes a lock and clears the section load list in diff --git a/contrib/llvm-project/lldb/include/lldb/Target/SectionLoadList.h b/contrib/llvm-project/lldb/include/lldb/Target/SectionLoadList.h index 548d44a181a7..ac86e6318155 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/SectionLoadList.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/SectionLoadList.h @@ -22,7 +22,7 @@ namespace lldb_private { class SectionLoadList { public: // Constructors and Destructors - SectionLoadList() {} + SectionLoadList() = default; SectionLoadList(const SectionLoadList &rhs); diff --git a/contrib/llvm-project/lldb/include/lldb/Target/StackFrameList.h b/contrib/llvm-project/lldb/include/lldb/Target/StackFrameList.h index c98995cad36f..e05a398e3c0b 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/StackFrameList.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/StackFrameList.h @@ -17,6 +17,8 @@ namespace lldb_private { +class ScriptedThread; + class StackFrameList { public: // Constructors and Destructors @@ -86,6 +88,7 @@ public: protected: friend class Thread; + friend class ScriptedThread; bool SetFrameAtIndex(uint32_t idx, lldb::StackFrameSP &frame_sp); diff --git a/contrib/llvm-project/lldb/include/lldb/Target/StackID.h b/contrib/llvm-project/lldb/include/lldb/Target/StackID.h index 95d12df6742c..09392792cb50 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/StackID.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/StackID.h @@ -17,9 +17,7 @@ namespace lldb_private { class StackID { public: // Constructors and Destructors - StackID() - - {} + StackID() = default; explicit StackID(lldb::addr_t pc, lldb::addr_t cfa, SymbolContextScope *symbol_scope) diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Statistics.h b/contrib/llvm-project/lldb/include/lldb/Target/Statistics.h index d2b8f746a38c..9c0b3ea5ec05 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/Statistics.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/Statistics.h @@ -100,6 +100,13 @@ struct ModuleStats { std::string path; std::string uuid; std::string triple; + // Path separate debug info file, or empty if none. + std::string symfile_path; + // If the debug info is contained in multiple files where each one is + // represented as a separate lldb_private::Module, then these are the + // identifiers of these modules in the global module list. This allows us to + // track down all of the stats that contribute to this module. + std::vector<intptr_t> symfile_modules; double symtab_parse_time = 0.0; double symtab_index_time = 0.0; double debug_parse_time = 0.0; @@ -109,6 +116,8 @@ struct ModuleStats { bool symtab_saved_to_cache = false; bool debug_info_index_loaded_from_cache = false; bool debug_info_index_saved_to_cache = false; + bool debug_info_enabled = true; + bool symtab_stripped = false; }; struct ConstStringStats { diff --git a/contrib/llvm-project/lldb/include/lldb/Target/SystemRuntime.h b/contrib/llvm-project/lldb/include/lldb/Target/SystemRuntime.h index 0ec0793e95f9..66868e474c6f 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/SystemRuntime.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/SystemRuntime.h @@ -77,7 +77,7 @@ public: /// /// Allow the SystemRuntime plugin to enable logging features in the system /// runtime libraries. - virtual void ModulesDidLoad(const ModuleList &module_list) override; + void ModulesDidLoad(const ModuleList &module_list) override; /// Called before detaching from a process. /// diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Target.h b/contrib/llvm-project/lldb/include/lldb/Target/Target.h index 42a641f6d52a..93ea8504f8ba 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/Target.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/Target.h @@ -71,6 +71,13 @@ enum ImportStdModule { eImportStdModuleTrue, }; +enum DynamicClassInfoHelper { + eDynamicClassInfoHelperAuto, + eDynamicClassInfoHelperRealizedClassesStruct, + eDynamicClassInfoHelperCopyRealizedClassList, + eDynamicClassInfoHelperGetRealizedClassList, +}; + class TargetExperimentalProperties : public Properties { public: TargetExperimentalProperties(); @@ -152,20 +159,31 @@ public: ImportStdModule GetImportStdModule() const; + DynamicClassInfoHelper GetDynamicClassInfoHelper() const; + bool GetEnableAutoApplyFixIts() const; uint64_t GetNumberOfRetriesWithFixits() const; bool GetEnableNotifyAboutFixIts() const; - bool GetEnableSaveObjects() const; - + FileSpec GetSaveJITObjectsDir() const; + bool GetEnableSyntheticValue() const; uint32_t GetMaxZeroPaddingInFloatFormat() const; uint32_t GetMaximumNumberOfChildrenToDisplay() const; + /// Get the max depth value, augmented with a bool to indicate whether the + /// depth is the default. + /// + /// When the user has customized the max depth, the bool will be false. + /// + /// \returns the max depth, and true if the max depth is the system default, + /// otherwise false. + std::pair<uint32_t, bool> GetMaximumDepthOfChildrenToDisplay() const; + uint32_t GetMaximumSizeOfStringSummary() const; uint32_t GetMaximumMemReadSize() const; @@ -248,6 +266,9 @@ private: void DisableASLRValueChangedCallback(); void InheritTCCValueChangedCallback(); void DisableSTDIOValueChangedCallback(); + + // Settings checker for target.jit-save-objects-dir: + void CheckJITObjectsDir(); Environment ComputeEnvironment() const; @@ -445,7 +466,7 @@ private: // #line %u "%s" before the expression content to remap where the source // originates mutable std::string m_pound_line_file; - mutable uint32_t m_pound_line_line; + mutable uint32_t m_pound_line_line = 0; }; // Target @@ -966,6 +987,9 @@ public: ModuleIsExcludedForUnconstrainedSearches(const lldb::ModuleSP &module_sp); const ArchSpec &GetArchitecture() const { return m_arch.GetSpec(); } + + /// Returns the name of the target's ABI plugin. + llvm::StringRef GetABIName() const; /// Set the architecture for this target. /// @@ -1274,7 +1298,7 @@ public: class StopHookCommandLine : public StopHook { public: - virtual ~StopHookCommandLine() = default; + ~StopHookCommandLine() override = default; StringList &GetCommands() { return m_commands; } void SetActionFromString(const std::string &strings); @@ -1297,7 +1321,7 @@ public: class StopHookScripted : public StopHook { public: - virtual ~StopHookScripted() = default; + ~StopHookScripted() override = default; StopHookResult HandleStop(ExecutionContext &exc_ctx, lldb::StreamSP output) override; @@ -1399,6 +1423,42 @@ public: return *m_frame_recognizer_manager_up; } + /// Add a signal for the target. This will get copied over to the process + /// if the signal exists on that target. Only the values with Yes and No are + /// set, Calculate values will be ignored. +protected: + struct DummySignalValues { + LazyBool pass = eLazyBoolCalculate; + LazyBool notify = eLazyBoolCalculate; + LazyBool stop = eLazyBoolCalculate; + DummySignalValues(LazyBool pass, LazyBool notify, LazyBool stop) : + pass(pass), notify(notify), stop(stop) {} + DummySignalValues() = default; + }; + using DummySignalElement = llvm::StringMapEntry<DummySignalValues>; + static bool UpdateSignalFromDummy(lldb::UnixSignalsSP signals_sp, + const DummySignalElement &element); + static bool ResetSignalFromDummy(lldb::UnixSignalsSP signals_sp, + const DummySignalElement &element); + +public: + /// Add a signal to the Target's list of stored signals/actions. These + /// values will get copied into any processes launched from + /// this target. + void AddDummySignal(llvm::StringRef name, LazyBool pass, LazyBool print, + LazyBool stop); + /// Updates the signals in signals_sp using the stored dummy signals. + /// If warning_stream_sp is not null, if any stored signals are not found in + /// the current process, a warning will be emitted here. + void UpdateSignalsFromDummy(lldb::UnixSignalsSP signals_sp, + lldb::StreamSP warning_stream_sp); + /// Clear the dummy signals in signal_names from the target, or all signals + /// if signal_names is empty. Also remove the behaviors they set from the + /// process's signals if it exists. + void ClearDummySignals(Args &signal_names); + /// Print all the signals set in this target. + void PrintDummySignals(Stream &strm, Args &signals); + protected: /// Implementing of ModuleList::Notifier. @@ -1428,6 +1488,7 @@ protected: ArchSpec m_spec; std::unique_ptr<Architecture> m_plugin_up; }; + // Member variables. Debugger &m_debugger; lldb::PlatformSP m_platform_sp; ///< The platform for this target. @@ -1478,6 +1539,10 @@ protected: lldb::TraceSP m_trace_sp; /// Stores the frame recognizers of this target. lldb::StackFrameRecognizerManagerUP m_frame_recognizer_manager_up; + /// These are used to set the signal state when you don't have a process and + /// more usefully in the Dummy target where you can't know exactly what + /// signals you will have. + llvm::StringMap<DummySignalValues> m_dummy_signals; static void ImageSearchPathsChanged(const PathMappingList &path_list, void *baton); diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Thread.h b/contrib/llvm-project/lldb/include/lldb/Target/Thread.h index 2fd7d8859f52..f5f024434c8e 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/Thread.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/Thread.h @@ -539,9 +539,12 @@ public: /// This function is designed to be used by commands where the /// process is publicly stopped. /// + /// \param[in] frame_idx + /// The frame index to step out of. + /// /// \return /// An error that describes anything that went wrong - virtual Status StepOut(); + virtual Status StepOut(uint32_t frame_idx = 0); /// Retrieves the per-thread data area. /// Most OSs maintain a per-thread pointer (e.g. the FS register on @@ -836,7 +839,7 @@ public: /// See standard meanings for the stop & run votes in ThreadPlan.h. /// /// \param[in] frame_idx - /// The fame index. + /// The frame index. /// /// \param[out] status /// A status with an error if queuing failed. diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStack.h b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStack.h index 90f1ea3a284b..e6a560a50926 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStack.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStack.h @@ -123,11 +123,13 @@ public: bool check_for_new = true); void AddThread(Thread &thread) { + std::lock_guard<std::recursive_mutex> guard(m_stack_map_mutex); lldb::tid_t tid = thread.GetID(); m_plans_list.emplace(tid, thread); } bool RemoveTID(lldb::tid_t tid) { + std::lock_guard<std::recursive_mutex> guard(m_stack_map_mutex); auto result = m_plans_list.find(tid); if (result == m_plans_list.end()) return false; @@ -137,6 +139,7 @@ public: } ThreadPlanStack *Find(lldb::tid_t tid) { + std::lock_guard<std::recursive_mutex> guard(m_stack_map_mutex); auto result = m_plans_list.find(tid); if (result == m_plans_list.end()) return nullptr; @@ -154,6 +157,7 @@ public: } void Clear() { + std::lock_guard<std::recursive_mutex> guard(m_stack_map_mutex); for (auto &plan : m_plans_list) plan.second.ThreadDestroyed(nullptr); m_plans_list.clear(); @@ -172,8 +176,10 @@ public: private: Process &m_process; + mutable std::recursive_mutex m_stack_map_mutex; using PlansList = std::unordered_map<lldb::tid_t, ThreadPlanStack>; PlansList m_plans_list; + }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Trace.h b/contrib/llvm-project/lldb/include/lldb/Target/Trace.h index 643b761cdb89..f4d7dee684c3 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/Trace.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/Trace.h @@ -82,7 +82,7 @@ public: /// - The plug-in name (this allows a specific plug-in to be selected) /// - Architecture or target triple /// - one or more paths to the trace data file on disk - /// - core trace data + /// - cpu trace data /// - thread events or related information /// - shared library load information to use for this trace data that /// allows a target to be created so the trace information can be @@ -102,17 +102,14 @@ public: /// The debugger instance where new Targets will be created as part of the /// JSON data parsing. /// - /// \param[in] trace_session_file - /// The contents of the trace session file describing the trace session. - /// See \a TraceSessionFileParser::BuildSchema for more information about - /// the schema of this JSON file. + /// \param[in] bundle_description + /// The trace bundle description object describing the trace session. /// - /// \param[in] session_file_dir - /// The path to the directory that contains the session file. It's used to - /// resolved relative paths in the session file. + /// \param[in] bundle_dir + /// The path to the directory that contains the trace bundle. static llvm::Expected<lldb::TraceSP> FindPluginForPostMortemProcess(Debugger &debugger, - const llvm::json::Value &trace_session_file, + const llvm::json::Value &bundle_description, llvm::StringRef session_file_dir); /// Find a trace plug-in to trace a live process. @@ -137,6 +134,23 @@ public: static llvm::Expected<llvm::StringRef> FindPluginSchema(llvm::StringRef plugin_name); + /// Load a trace from a trace description file and create Targets, + /// Processes and Threads based on the contents of such file. + /// + /// \param[in] debugger + /// The debugger instance where new Targets will be created as part of the + /// JSON data parsing. + /// + /// \param[in] trace_description_file + /// The file containing the necessary information to load the trace. + /// + /// \return + /// A \a TraceSP instance, or an \a llvm::Error if loading the trace + /// fails. + static llvm::Expected<lldb::TraceSP> + LoadPostMortemTraceFromFile(Debugger &debugger, + const FileSpec &trace_description_file); + /// Get the command handle for the "process trace start" command. virtual lldb::CommandObjectSP GetProcessTraceStartCommand(CommandInterpreter &interpreter) = 0; @@ -153,9 +167,9 @@ public: /// /// \return /// 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; + /// information failed to load, an \a llvm::Error is returned. + virtual llvm::Expected<lldb::TraceCursorUP> + CreateNewCursor(Thread &thread) = 0; /// Dump general info about a given thread's trace. Each Trace plug-in /// decides which data to show. @@ -233,15 +247,179 @@ public: /// \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); - /// \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(); + using OnBinaryDataReadCallback = + std::function<llvm::Error(llvm::ArrayRef<uint8_t> data)>; + using OnCpusBinaryDataReadCallback = std::function<llvm::Error( + const llvm::DenseMap<lldb::cpu_id_t, llvm::ArrayRef<uint8_t>> + &cpu_to_data)>; + + /// Fetch binary data associated with a thread, either live or postmortem, and + /// pass it to the given callback. The reason of having a callback is to free + /// the caller from having to manage the life cycle of the data and to hide + /// the different data fetching procedures that exist for live and post mortem + /// threads. + /// + /// The fetched data is not persisted after the callback is invoked. + /// + /// \param[in] tid + /// The tid who owns the data. + /// + /// \param[in] kind + /// The kind of data to read. + /// + /// \param[in] callback + /// The callback to be invoked once the data was successfully read. Its + /// return value, which is an \a llvm::Error, is returned by this + /// function. + /// + /// \return + /// An \a llvm::Error if the data couldn't be fetched, or the return value + /// of the callback, otherwise. + llvm::Error OnThreadBinaryDataRead(lldb::tid_t tid, llvm::StringRef kind, + OnBinaryDataReadCallback callback); + + /// Fetch binary data associated with a cpu, either live or postmortem, and + /// pass it to the given callback. The reason of having a callback is to free + /// the caller from having to manage the life cycle of the data and to hide + /// the different data fetching procedures that exist for live and post mortem + /// cpus. + /// + /// The fetched data is not persisted after the callback is invoked. + /// + /// \param[in] cpu_id + /// The cpu who owns the data. + /// + /// \param[in] kind + /// The kind of data to read. + /// + /// \param[in] callback + /// The callback to be invoked once the data was successfully read. Its + /// return value, which is an \a llvm::Error, is returned by this + /// function. + /// + /// \return + /// An \a llvm::Error if the data couldn't be fetched, or the return value + /// of the callback, otherwise. + llvm::Error OnCpuBinaryDataRead(lldb::cpu_id_t cpu_id, llvm::StringRef kind, + OnBinaryDataReadCallback callback); + + /// Similar to \a OnCpuBinaryDataRead but this is able to fetch the same data + /// from all cpus at once. + llvm::Error OnAllCpusBinaryDataRead(llvm::StringRef kind, + OnCpusBinaryDataReadCallback callback); + + /// \return + /// All the currently traced processes. + std::vector<Process *> GetAllProcesses(); + + /// \return + /// The list of cpus being traced. Might be empty depending on the + /// plugin. + llvm::ArrayRef<lldb::cpu_id_t> GetTracedCpus(); + + /// Helper method for reading a data file and passing its data to the given + /// callback. + static llvm::Error OnDataFileRead(FileSpec file, + OnBinaryDataReadCallback callback); + protected: + /// Get the currently traced live process. + /// + /// \return + /// If it's not a live process, return \a nullptr. + Process *GetLiveProcess(); + + /// Get the currently traced postmortem processes. + /// + /// \return + /// If it's not a live process session, return an empty list. + llvm::ArrayRef<Process *> GetPostMortemProcesses(); + + /// Dispatcher for live trace data requests with some additional error + /// checking. + llvm::Expected<std::vector<uint8_t>> + GetLiveTraceBinaryData(const TraceGetBinaryDataRequest &request, + uint64_t expected_size); + + /// Implementation of \a OnThreadBinaryDataRead() for live threads. + llvm::Error OnLiveThreadBinaryDataRead(lldb::tid_t tid, llvm::StringRef kind, + OnBinaryDataReadCallback callback); + + /// Implementation of \a OnLiveBinaryDataRead() for live cpus. + llvm::Error OnLiveCpuBinaryDataRead(lldb::cpu_id_t cpu, llvm::StringRef kind, + OnBinaryDataReadCallback callback); + + /// Implementation of \a OnThreadBinaryDataRead() for post mortem threads. + llvm::Error + OnPostMortemThreadBinaryDataRead(lldb::tid_t tid, llvm::StringRef kind, + OnBinaryDataReadCallback callback); + + /// Implementation of \a OnCpuBinaryDataRead() for post mortem cpus. + llvm::Error OnPostMortemCpuBinaryDataRead(lldb::cpu_id_t cpu_id, + llvm::StringRef kind, + OnBinaryDataReadCallback callback); + + /// Get the file path containing data of a postmortem thread given a data + /// identifier. + /// + /// \param[in] tid + /// The thread whose data is requested. + /// + /// \param[in] kind + /// The kind of data requested. + /// + /// \return + /// The file spec containing the requested data, or an \a llvm::Error in + /// case of failures. + llvm::Expected<FileSpec> GetPostMortemThreadDataFile(lldb::tid_t tid, + llvm::StringRef kind); + + /// Get the file path containing data of a postmortem cpu given a data + /// identifier. + /// + /// \param[in] cpu_id + /// The cpu whose data is requested. + /// + /// \param[in] kind + /// The kind of data requested. + /// + /// \return + /// The file spec containing the requested data, or an \a llvm::Error in + /// case of failures. + llvm::Expected<FileSpec> GetPostMortemCpuDataFile(lldb::cpu_id_t cpu_id, + llvm::StringRef kind); + + /// Associate a given thread with a data file using a data identifier. + /// + /// \param[in] tid + /// The thread associated with the data file. + /// + /// \param[in] kind + /// The kind of data being registered. + /// + /// \param[in] file_spec + /// The path of the data file. + void SetPostMortemThreadDataFile(lldb::tid_t tid, llvm::StringRef kind, + FileSpec file_spec); + + /// Associate a given cpu with a data file using a data identifier. + /// + /// \param[in] cpu_id + /// The cpu associated with the data file. + /// + /// \param[in] kind + /// The kind of data being registered. + /// + /// \param[in] file_spec + /// The path of the data file. + void SetPostMortemCpuDataFile(lldb::cpu_id_t cpu_id, llvm::StringRef kind, + FileSpec file_spec); + /// Get binary data of a live thread given a data identifier. /// /// \param[in] tid @@ -253,9 +431,23 @@ protected: /// \return /// A vector of bytes with the requested data, or an \a llvm::Error in /// case of failures. - llvm::Expected<llvm::ArrayRef<uint8_t>> + llvm::Expected<std::vector<uint8_t>> GetLiveThreadBinaryData(lldb::tid_t tid, llvm::StringRef kind); + /// Get binary data of a live cpu given a data identifier. + /// + /// \param[in] cpu_id + /// The cpu whose data is requested. + /// + /// \param[in] kind + /// The kind of data requested. + /// + /// \return + /// A vector of bytes with the requested data, or an \a llvm::Error in + /// case of failures. + llvm::Expected<std::vector<uint8_t>> + GetLiveCpuBinaryData(lldb::cpu_id_t cpu_id, llvm::StringRef kind); + /// Get binary data of the current process given a data identifier. /// /// \param[in] kind @@ -264,17 +456,23 @@ protected: /// \return /// A vector of bytes with the requested data, or an \a llvm::Error in /// case of failures. - llvm::Expected<llvm::ArrayRef<uint8_t>> + llvm::Expected<std::vector<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); + llvm::Optional<uint64_t> GetLiveThreadBinaryDataSize(lldb::tid_t tid, + llvm::StringRef kind); + + /// Get the size of the data returned by \a GetLiveCpuBinaryData + llvm::Optional<uint64_t> GetLiveCpuBinaryDataSize(lldb::cpu_id_t cpu_id, + llvm::StringRef kind); /// Get the size of the data returned by \a GetLiveProcessBinaryData - llvm::Optional<size_t> GetLiveProcessBinaryDataSize(llvm::StringRef kind); + llvm::Optional<uint64_t> GetLiveProcessBinaryDataSize(llvm::StringRef kind); + /// Constructor for post mortem processes - Trace() = default; + Trace(llvm::ArrayRef<lldb::ProcessSP> postmortem_processes, + llvm::Optional<std::vector<lldb::cpu_id_t>> postmortem_cpus); /// Constructor for a live process Trace(Process &live_process) : m_live_process(&live_process) {} @@ -304,22 +502,92 @@ protected: /// /// \param[in] state /// The jLLDBTraceGetState response. - virtual void - DoRefreshLiveProcessState(llvm::Expected<TraceGetStateResponse> state) = 0; + /// + /// \param[in] json_response + /// The original JSON response as a string. It might be useful to redecode + /// it if it contains custom data for a specific trace plug-in. + /// + /// \return + /// \b Error::success() if this operation succeedes, or an actual error + /// otherwise. + virtual llvm::Error + DoRefreshLiveProcessState(TraceGetStateResponse state, + llvm::StringRef json_response) = 0; - /// Method to be invoked by the plug-in to refresh the live process state. + /// Return the list of processes traced by this instance. None of the returned + /// pointers are invalid. + std::vector<Process *> GetTracedProcesses(); + + /// Method to be invoked by the plug-in to refresh the live process state. It + /// will invoked DoRefreshLiveProcessState at some point, which should be + /// implemented by the plug-in for custom state handling. + /// + /// The result is cached through the same process stop. Even in the case of + /// errors, it caches the error. /// - /// The result is cached through the same process stop. - void RefreshLiveProcessState(); + /// \return + /// An error message if this operation failed, or \b nullptr otherwise. + const char *RefreshLiveProcessState(); +private: 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; + + /// We package all the data that can change upon process stops to make sure + /// this contract is very visible. + /// This variable should only be accessed directly by constructores or live + /// process data refreshers. + struct Storage { + /// Portmortem processes traced by this object if doing non-live tracing. + /// Otherwise it's empty. + std::vector<Process *> postmortem_processes; + + /// These data kinds are returned by lldb-server when fetching the state of + /// the tracing session. The size in bytes can be used later for fetching + /// the data in batches. + /// \{ + + /// tid -> data kind -> size + llvm::DenseMap<lldb::tid_t, llvm::DenseMap<ConstString, uint64_t>> + live_thread_data; + + /// cpu id -> data kind -> size + llvm::DenseMap<lldb::cpu_id_t, llvm::DenseMap<ConstString, uint64_t>> + live_cpu_data_sizes; + /// cpu id -> data kind -> bytes + llvm::DenseMap<lldb::cpu_id_t, + llvm::DenseMap<ConstString, std::vector<uint8_t>>> + live_cpu_data; + + /// data kind -> size + llvm::DenseMap<ConstString, uint64_t> live_process_data; + /// \} + + /// The list of cpus being traced. Might be \b None depending on the + /// plug-in. + llvm::Optional<std::vector<lldb::cpu_id_t>> cpus; + + /// Postmortem traces can specific additional data files, which are + /// represented in this variable using a data kind identifier for each file. + /// \{ + + /// tid -> data kind -> file + llvm::DenseMap<lldb::tid_t, llvm::DenseMap<ConstString, FileSpec>> + postmortem_thread_data; + + /// cpu id -> data kind -> file + llvm::DenseMap<lldb::cpu_id_t, llvm::DenseMap<ConstString, FileSpec>> + postmortem_cpu_data; + + /// \} + + llvm::Optional<std::string> live_refresh_error; + } m_storage; + + /// Get the storage after refreshing the data in the case of a live process. + Storage &GetUpdatedStorage(); }; } // 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 index 14fc00d5f95b..a4cf6433c19a 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/TraceCursor.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/TraceCursor.h @@ -15,7 +15,8 @@ namespace lldb_private { -/// Class used for iterating over the instructions of a thread's trace. +/// Class used for iterating over the instructions of a thread's trace, among +/// other kinds of information. /// /// 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 @@ -23,60 +24,80 @@ namespace lldb_private { /// 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. +/// 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, then it's up to each +/// trace plug-in to decide whether to leave the old cursor unaffected or not. /// -/// 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. +/// Cursor items: +/// A \a TraceCursor can point at one of the following items: /// -/// Instructions: -/// A \a TraceCursor always points to a specific instruction or error in the -/// trace. +/// Errors: +/// 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. +/// +/// Events: +/// The cursor can also point at events in the trace, which aren't errors +/// nor instructions. An example of an event could be a context switch in +/// between two instructions. +/// +/// Instruction: +/// An actual instruction with a memory address. /// /// 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. +/// By default, the cursor points at the most recent item in the trace and is +/// set up to iterate backwards. 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. +/// for (; cursor->HasValue(); cursor->Next()) { +/// TraceItemKind kind = cursor->GetItemKind(); +/// switch (cursor->GetItemKind()): +/// case eTraceItemKindError: +/// cout << "error found: " << cursor->GetError() << endl; +/// break; +/// case eTraceItemKindEvent: +/// cout << "event found: " << cursor->GetEventTypeAsString() << endl; +/// break; +/// case eTraceItemKindInstruction: +/// std::cout << "instructions found at " << cursor->GetLoadAddress() << +/// std::endl; break; +/// } +/// } +/// +/// As the trace might be empty or the cursor might have reached the end of the +/// trace, you should always invoke \a HasValue() to make sure you don't access +/// invalid memory. +/// +/// Random accesses: +/// +/// The Trace Cursor offer random acesses in the trace via two APIs: +/// +/// TraceCursor::Seek(): +/// Unlike the \a TraceCursor::Next() API, which moves instruction by +/// instruction, 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. +/// +/// TraceCursor::GetId() / TraceCursor::SetId(id): +/// Each item (error or instruction) in the trace has a numeric identifier +/// which is defined by the trace plug-in. It's possible to access the id +/// of the current item using GetId(), and to reposition the cursor to a +/// given id using SetId(id). +/// +/// You can read more in the documentation of these methods. class TraceCursor { public: /// Helper enum to indicate the reference point when invoking /// \a TraceCursor::Seek(). + /// The following values are inspired by \a std::istream::seekg. enum class SeekType { /// The beginning of the trace, i.e the oldest item. - Set = 0, + Beginning = 0, /// The current position in the trace. Current, /// The end of the trace, i.e the most recent item. @@ -89,12 +110,6 @@ public: 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 @@ -108,8 +123,7 @@ public: /// \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. + /// Move the cursor to the next item (instruction or error). /// /// Direction: /// The traversal is done following the current direction of the trace. If @@ -117,95 +131,147 @@ public: /// chronologically. Otherwise, the traversal is done in /// the opposite direction. By default, a cursor moves backwards unless /// changed with \a TraceCursor::SetForwards(). + virtual void Next() = 0; + + /// \return + /// \b true if the cursor is pointing to a valid item. \b false if the + /// cursor has reached the end of the trace. + virtual bool HasValue() const = 0; + + /// Instruction identifiers: + /// + /// When building complex higher level tools, fast random accesses in the + /// trace might be needed, for which each instruction requires a unique + /// identifier within its thread trace. For example, a tool might want to + /// repeatedly inspect random consecutive portions of a trace. This means that + /// it will need to first move quickly to the beginning of each section and + /// then start its iteration. Given that the number of instructions can be in + /// the order of hundreds of millions, fast random access is necessary. /// - /// 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. + /// An example of such a tool could be an inspector of the call graph of a + /// trace, where each call is represented with its start and end instructions. + /// Inspecting all the instructions of a call requires moving to its first + /// instruction and then iterating until the last instruction, which following + /// the pattern explained above. /// - /// 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. + /// Instead of using 0-based indices as identifiers, each Trace plug-in can + /// decide the nature of these identifiers and thus no assumptions can be made + /// regarding their ordering and sequentiality. The reason is that an + /// instruction might be encoded by the plug-in in a way that hides its actual + /// 0-based index in the trace, but it's still possible to efficiently find + /// it. /// + /// Requirements: + /// - For a given thread, no two instructions have the same id. + /// - In terms of efficiency, moving the cursor to a given id should be as + /// fast as possible, but not necessarily O(1). That's why the recommended + /// way to traverse sequential instructions is to use the \a + /// TraceCursor::Next() method and only use \a TraceCursor::GoToId(id) + /// sparingly. + + /// Make the cursor point to the item whose identifier is \p id. + /// + /// \return + /// \b true if the given identifier exists and the cursor effectively + /// moved to it. Otherwise, \b false is returned and the cursor now points + /// to an invalid item, i.e. calling \a HasValue() will return \b false. + virtual bool GoToId(lldb::user_id_t id) = 0; + /// \return - /// \b true if the cursor effectively moved, \b false otherwise. - virtual bool Next() = 0; + /// \b true if and only if there's an instruction item with the given \p + /// id. + virtual bool HasId(lldb::user_id_t id) const = 0; + + /// \return + /// A unique identifier for the instruction or error this cursor is + /// pointing to. + virtual lldb::user_id_t GetId() const = 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. + /// an offset. /// /// 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. + /// If this resulting position would be out of bounds, the trace then points + /// to an invalid item, i.e. calling \a HasValue() returns \b false. /// /// \param[in] offset /// How many items to move forwards (if positive) or backwards (if - /// negative) from the given origin point. + /// negative) from the given origin point. For example, if origin is \b + /// End, then a negative offset would move backward in the trace, but a + /// positive offset would move past the trace to an invalid item. /// /// \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; + /// \b true if and only if the cursor ends up pointing to a valid item. + virtual bool Seek(int64_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 + /// Instruction, event or error information /// \{ /// \return + /// The kind of item the cursor is pointing at. + virtual lldb::TraceItemKind GetItemKind() const = 0; + + /// \return /// Whether the cursor points to an error or not. - virtual bool IsError() = 0; + bool IsError() const; - /// 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; + /// The error message the cursor is pointing at. + virtual const char *GetError() const = 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; + /// Whether the cursor points to an event or not. + bool IsEvent() const; + + /// \return + /// The specific kind of event the cursor is pointing at, or \b + /// TraceEvent::eTraceEventNone if the cursor not pointing to an event. + virtual lldb::TraceEvent GetEventType() const = 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; + /// A human-readable description of the event this cursor is pointing at. + const char *GetEventTypeAsString() const; /// \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; + /// A human-readable description of the given event. + static const char *EventKindToString(lldb::TraceEvent event_kind); + + /// \return + /// Whether the cursor points to an instruction. + bool IsInstruction() const; + + /// \return + /// The load address of the instruction the cursor is pointing at. + virtual lldb::addr_t GetLoadAddress() const = 0; + + /// Get the hardware counter of a given type associated with the current + /// instruction. Each architecture might support different counters. It might + /// happen that only some instructions of an entire trace have a given counter + /// associated with them. + /// + /// \param[in] counter_type + /// The counter type. + /// \return + /// The value of the counter or \b llvm::None if not available. + virtual llvm::Optional<uint64_t> + GetCounter(lldb::TraceCounter counter_type) const = 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/TraceDumper.h b/contrib/llvm-project/lldb/include/lldb/Target/TraceDumper.h new file mode 100644 index 000000000000..e78836e45b01 --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Target/TraceDumper.h @@ -0,0 +1,120 @@ +//===-- TraceDumper.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" + +#include "lldb/Symbol/SymbolContext.h" + +#ifndef LLDB_TARGET_TRACE_INSTRUCTION_DUMPER_H +#define LLDB_TARGET_TRACE_INSTRUCTION_DUMPER_H + +namespace lldb_private { + +/// Class that holds the configuration used by \a TraceDumper for +/// traversing and dumping instructions. +struct TraceDumperOptions { + /// If \b true, the cursor will be iterated forwards starting from the + /// oldest instruction. Otherwise, the iteration starts from the most + /// recent instruction. + bool forwards = false; + /// Dump only instruction addresses without disassembly nor symbol + /// information. + bool raw = false; + /// Dump in json format. + bool json = false; + /// When dumping in JSON format, pretty print the output. + bool pretty_print_json = false; + /// For each instruction, print the corresponding timestamp counter if + /// available. + bool show_tsc = false; + /// Dump the events that happened between instructions. + bool show_events = false; + /// Optional custom id to start traversing from. + llvm::Optional<uint64_t> id = llvm::None; + /// Optional number of instructions to skip from the starting position + /// of the cursor. + llvm::Optional<size_t> skip = llvm::None; +}; + +/// Class used to dump the instructions of a \a TraceCursor using its current +/// state and granularity. +class TraceDumper { +public: + /// Helper struct that holds symbol, disassembly and address information of an + /// instruction. + struct SymbolInfo { + SymbolContext sc; + Address address; + lldb::DisassemblerSP disassembler; + lldb::InstructionSP instruction; + lldb_private::ExecutionContext exe_ctx; + }; + + /// Helper struct that holds all the information we know about a trace item + struct TraceItem { + lldb::user_id_t id; + lldb::addr_t load_address; + llvm::Optional<uint64_t> tsc; + llvm::Optional<llvm::StringRef> error; + llvm::Optional<lldb::TraceEvent> event; + llvm::Optional<SymbolInfo> symbol_info; + llvm::Optional<SymbolInfo> prev_symbol_info; + }; + + /// Interface used to abstract away the format in which the instruction + /// information will be dumped. + class OutputWriter { + public: + virtual ~OutputWriter() = default; + + /// Notify this writer that the cursor ran out of data. + virtual void NoMoreData() {} + + /// Dump a trace item (instruction, error or event). + virtual void TraceItem(const TraceItem &item) = 0; + }; + + /// Create a instruction dumper for the cursor. + /// + /// \param[in] cursor + /// The cursor whose instructions will be dumped. + /// + /// \param[in] s + /// The stream where to dump the instructions to. + /// + /// \param[in] options + /// Additional options for configuring the dumping. + TraceDumper(lldb::TraceCursorUP &&cursor_up, Stream &s, + const TraceDumperOptions &options); + + /// 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] count + /// The number of instructions to print. + /// + /// \return + /// The instruction id of the last traversed instruction, or \b llvm::None + /// if no instructions were visited. + llvm::Optional<lldb::user_id_t> DumpInstructions(size_t count); + +private: + /// Create a trace item for the current position without symbol information. + TraceItem CreatRawTraceItem(); + + lldb::TraceCursorUP m_cursor_up; + TraceDumperOptions m_options; + std::unique_ptr<OutputWriter> m_writer_up; +}; + +} // namespace lldb_private + +#endif // LLDB_TARGET_TRACE_INSTRUCTION_DUMPER_H diff --git a/contrib/llvm-project/lldb/include/lldb/Target/TraceInstructionDumper.h b/contrib/llvm-project/lldb/include/lldb/Target/TraceInstructionDumper.h deleted file mode 100644 index c4878bfd3fd5..000000000000 --- a/contrib/llvm-project/lldb/include/lldb/Target/TraceInstructionDumper.h +++ /dev/null @@ -1,77 +0,0 @@ -//===-- 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 1c91c9fdd489..34f4e30d1350 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/UnixSignals.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/UnixSignals.h @@ -55,6 +55,9 @@ public: bool SetShouldNotify(int32_t signo, bool value); bool SetShouldNotify(const char *signal_name, bool value); + + bool ResetSignal(int32_t signo, bool reset_stop = true, + bool reset_notify = true, bool reset_suppress = true); // These provide an iterator through the signals available on this system. // Call GetFirstSignalNumber to get the first entry, then iterate on @@ -114,11 +117,13 @@ protected: std::string m_description; uint32_t m_hit_count = 0; bool m_suppress : 1, m_stop : 1, m_notify : 1; + bool m_default_suppress : 1, m_default_stop : 1, m_default_notify : 1; Signal(const char *name, bool default_suppress, bool default_stop, bool default_notify, const char *description, const char *alias); ~Signal() = default; + void Reset(bool reset_stop, bool reset_notify, bool reset_suppress); }; virtual void Reset(); diff --git a/contrib/llvm-project/lldb/include/lldb/Target/UnwindLLDB.h b/contrib/llvm-project/lldb/include/lldb/Target/UnwindLLDB.h index 939226c8c5b9..f80212cde3ca 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/UnwindLLDB.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/UnwindLLDB.h @@ -119,7 +119,7 @@ private: RegisterContextLLDBSP reg_ctx_lldb_sp; // These are all RegisterContextUnwind's - Cursor() {} + Cursor() = default; private: Cursor(const Cursor &) = delete; diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/AnsiTerminal.h b/contrib/llvm-project/lldb/include/lldb/Utility/AnsiTerminal.h index c391adb2cf89..caad56671537 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/AnsiTerminal.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/AnsiTerminal.h @@ -1,7 +1,3 @@ -#ifndef LLDB_UTILITY_ANSITERMINAL_H - -#define LLDB_UTILITY_ANSITERMINAL_H - //===---------------------AnsiTerminal.h ------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. @@ -10,6 +6,9 @@ // //===----------------------------------------------------------------------===// +#ifndef LLDB_UTILITY_ANSITERMINAL_H +#define LLDB_UTILITY_ANSITERMINAL_H + #define ANSI_FG_COLOR_BLACK 30 #define ANSI_FG_COLOR_RED 31 #define ANSI_FG_COLOR_GREEN 32 @@ -19,6 +18,15 @@ #define ANSI_FG_COLOR_CYAN 36 #define ANSI_FG_COLOR_WHITE 37 +#define ANSI_FG_COLOR_BRIGHT_BLACK 90 +#define ANSI_FG_COLOR_BRIGHT_RED 91 +#define ANSI_FG_COLOR_BRIGHT_GREEN 92 +#define ANSI_FG_COLOR_BRIGHT_YELLOW 93 +#define ANSI_FG_COLOR_BRIGHT_BLUE 94 +#define ANSI_FG_COLOR_BRIGHT_PURPLE 95 +#define ANSI_FG_COLOR_BRIGHT_CYAN 96 +#define ANSI_FG_COLOR_BRIGHT_WHITE 97 + #define ANSI_BG_COLOR_BLACK 40 #define ANSI_BG_COLOR_RED 41 #define ANSI_BG_COLOR_GREEN 42 @@ -28,6 +36,15 @@ #define ANSI_BG_COLOR_CYAN 46 #define ANSI_BG_COLOR_WHITE 47 +#define ANSI_BG_COLOR_BRIGHT_BLACK 100 +#define ANSI_BG_COLOR_BRIGHT_RED 101 +#define ANSI_BG_COLOR_BRIGHT_GREEN 102 +#define ANSI_BG_COLOR_BRIGHT_YELLOW 103 +#define ANSI_BG_COLOR_BRIGHT_BLUE 104 +#define ANSI_BG_COLOR_BRIGHT_PURPLE 105 +#define ANSI_BG_COLOR_BRIGHT_CYAN 106 +#define ANSI_BG_COLOR_BRIGHT_WHITE 107 + #define ANSI_SPECIAL_FRAMED 51 #define ANSI_SPECIAL_ENCIRCLED 52 @@ -67,45 +84,59 @@ inline std::string FormatAnsiTerminalCodes(llvm::StringRef format, bool do_color = true) { // Convert "${ansi.XXX}" tokens to ansi values or clear them if do_color is // false. + // clang-format off static const struct { const char *name; const char *value; } g_color_tokens[] = { #define _TO_STR2(_val) #_val #define _TO_STR(_val) _TO_STR2(_val) - {"fg.black}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLACK) ANSI_ESC_END}, - {"fg.red}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_RED) ANSI_ESC_END}, - {"fg.green}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_GREEN) ANSI_ESC_END}, - {"fg.yellow}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_YELLOW) ANSI_ESC_END}, - {"fg.blue}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLUE) ANSI_ESC_END}, - {"fg.purple}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_PURPLE) ANSI_ESC_END}, - {"fg.cyan}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_CYAN) ANSI_ESC_END}, - {"fg.white}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_WHITE) ANSI_ESC_END}, - {"bg.black}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLACK) ANSI_ESC_END}, - {"bg.red}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_RED) ANSI_ESC_END}, - {"bg.green}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_GREEN) ANSI_ESC_END}, - {"bg.yellow}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_YELLOW) ANSI_ESC_END}, - {"bg.blue}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLUE) ANSI_ESC_END}, - {"bg.purple}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_PURPLE) ANSI_ESC_END}, - {"bg.cyan}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_CYAN) ANSI_ESC_END}, - {"bg.white}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_WHITE) ANSI_ESC_END}, - {"normal}", ANSI_ESC_START _TO_STR(ANSI_CTRL_NORMAL) ANSI_ESC_END}, - {"bold}", ANSI_ESC_START _TO_STR(ANSI_CTRL_BOLD) ANSI_ESC_END}, - {"faint}", ANSI_ESC_START _TO_STR(ANSI_CTRL_FAINT) ANSI_ESC_END}, - {"italic}", ANSI_ESC_START _TO_STR(ANSI_CTRL_ITALIC) ANSI_ESC_END}, - {"underline}", ANSI_ESC_START _TO_STR(ANSI_CTRL_UNDERLINE) ANSI_ESC_END}, - {"slow-blink}", - ANSI_ESC_START _TO_STR(ANSI_CTRL_SLOW_BLINK) ANSI_ESC_END}, - {"fast-blink}", - ANSI_ESC_START _TO_STR(ANSI_CTRL_FAST_BLINK) ANSI_ESC_END}, - {"negative}", - ANSI_ESC_START _TO_STR(ANSI_CTRL_IMAGE_NEGATIVE) ANSI_ESC_END}, - {"conceal}", ANSI_ESC_START _TO_STR(ANSI_CTRL_CONCEAL) ANSI_ESC_END}, - {"crossed-out}", - ANSI_ESC_START _TO_STR(ANSI_CTRL_CROSSED_OUT) ANSI_ESC_END}, + {"fg.black}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLACK) ANSI_ESC_END}, + {"fg.red}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_RED) ANSI_ESC_END}, + {"fg.green}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_GREEN) ANSI_ESC_END}, + {"fg.yellow}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_YELLOW) ANSI_ESC_END}, + {"fg.blue}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLUE) ANSI_ESC_END}, + {"fg.purple}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_PURPLE) ANSI_ESC_END}, + {"fg.cyan}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_CYAN) ANSI_ESC_END}, + {"fg.white}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_WHITE) ANSI_ESC_END}, + {"fg.bright.black}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BRIGHT_BLACK) ANSI_ESC_END}, + {"fg.bright.red}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BRIGHT_RED) ANSI_ESC_END}, + {"fg.bright.green}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BRIGHT_GREEN) ANSI_ESC_END}, + {"fg.bright.yellow}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BRIGHT_YELLOW) ANSI_ESC_END}, + {"fg.bright.blue}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BRIGHT_BLUE) ANSI_ESC_END}, + {"fg.bright.purple}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BRIGHT_PURPLE) ANSI_ESC_END}, + {"fg.bright.cyan}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BRIGHT_CYAN) ANSI_ESC_END}, + {"fg.bright.white}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BRIGHT_WHITE) ANSI_ESC_END}, + {"bg.black}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLACK) ANSI_ESC_END}, + {"bg.red}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_RED) ANSI_ESC_END}, + {"bg.green}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_GREEN) ANSI_ESC_END}, + {"bg.yellow}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_YELLOW) ANSI_ESC_END}, + {"bg.blue}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLUE) ANSI_ESC_END}, + {"bg.purple}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_PURPLE) ANSI_ESC_END}, + {"bg.cyan}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_CYAN) ANSI_ESC_END}, + {"bg.white}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_WHITE) ANSI_ESC_END}, + {"bg.bright.black}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BRIGHT_BLACK) ANSI_ESC_END}, + {"bg.bright.red}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BRIGHT_RED) ANSI_ESC_END}, + {"bg.bright.green}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BRIGHT_GREEN) ANSI_ESC_END}, + {"bg.bright.yellow}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BRIGHT_YELLOW) ANSI_ESC_END}, + {"bg.bright.blue}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BRIGHT_BLUE) ANSI_ESC_END}, + {"bg.bright.purple}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BRIGHT_PURPLE) ANSI_ESC_END}, + {"bg.bright.cyan}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BRIGHT_CYAN) ANSI_ESC_END}, + {"bg.bright.white}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BRIGHT_WHITE) ANSI_ESC_END}, + {"normal}", ANSI_ESC_START _TO_STR(ANSI_CTRL_NORMAL) ANSI_ESC_END}, + {"bold}", ANSI_ESC_START _TO_STR(ANSI_CTRL_BOLD) ANSI_ESC_END}, + {"faint}", ANSI_ESC_START _TO_STR(ANSI_CTRL_FAINT) ANSI_ESC_END}, + {"italic}", ANSI_ESC_START _TO_STR(ANSI_CTRL_ITALIC) ANSI_ESC_END}, + {"underline}", ANSI_ESC_START _TO_STR(ANSI_CTRL_UNDERLINE) ANSI_ESC_END}, + {"slow-blink}", ANSI_ESC_START _TO_STR(ANSI_CTRL_SLOW_BLINK) ANSI_ESC_END}, + {"fast-blink}", ANSI_ESC_START _TO_STR(ANSI_CTRL_FAST_BLINK) ANSI_ESC_END}, + {"negative}", ANSI_ESC_START _TO_STR(ANSI_CTRL_IMAGE_NEGATIVE) ANSI_ESC_END}, + {"conceal}", ANSI_ESC_START _TO_STR(ANSI_CTRL_CONCEAL) ANSI_ESC_END}, + {"crossed-out}", ANSI_ESC_START _TO_STR(ANSI_CTRL_CROSSED_OUT) ANSI_ESC_END}, #undef _TO_STR #undef _TO_STR2 }; + // clang-format on auto codes = llvm::makeArrayRef(g_color_tokens); static const char tok_hdr[] = "${ansi."; diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/ArchSpec.h b/contrib/llvm-project/lldb/include/lldb/Utility/ArchSpec.h index fdfe6aceb033..f67acedf11c2 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/ArchSpec.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/ArchSpec.h @@ -92,6 +92,17 @@ public: eARM_abi_hard_float = 0x00000400 }; + enum RISCVeflags { + eRISCV_rvc = 0x00000001, /// RVC, +c + eRISCV_float_abi_soft = 0x00000000, /// soft float + eRISCV_float_abi_single = 0x00000002, /// single precision floating point, +f + eRISCV_float_abi_double = 0x00000004, /// double precision floating point, +d + eRISCV_float_abi_quad = 0x00000006, /// quad precision floating point, +q + eRISCV_float_abi_mask = 0x00000006, + eRISCV_rve = 0x00000008, /// RVE, +e + eRISCV_tso = 0x00000010, /// RVTSO (total store ordering) + }; + enum RISCVSubType { eRISCVSubType_unknown, eRISCVSubType_riscv32, diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/DataBuffer.h b/contrib/llvm-project/lldb/include/lldb/Utility/DataBuffer.h index c778299b89ad..e1c66fae7453 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/DataBuffer.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/DataBuffer.h @@ -20,12 +20,12 @@ namespace lldb_private { /// \class DataBuffer DataBuffer.h "lldb/Core/DataBuffer.h" -/// A pure virtual protocol class for abstracted data buffers. +/// A pure virtual protocol class for abstracted read only data buffers. /// -/// DataBuffer is an abstract class that gets packaged into a shared pointer -/// that can use to implement various ways to store data (on the heap, memory -/// mapped, cached inferior memory). It gets used by DataExtractor so many -/// DataExtractor objects can share the same data and sub-ranges of that +/// DataBuffer is an abstract class that gets packaged into a shared +/// pointer that can use to implement various ways to store data (on the heap, +/// memory mapped, cached inferior memory). It gets used by DataExtractor so +/// many DataExtractor objects can share the same data and sub-ranges of that /// shared data, and the last object that contains a reference to the shared /// data will free it. /// @@ -42,52 +42,106 @@ namespace lldb_private { /// with some extra function calls to load the data before it gets accessed. class DataBuffer { public: - /// Destructor - /// - /// The destructor is virtual as other classes will inherit from this class - /// 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() = default; - /// Get a pointer to the data. + /// Get the number of bytes in the data buffer. /// /// \return - /// A pointer to the bytes owned by this object, or NULL if the - /// object contains no bytes. - virtual uint8_t *GetBytes() = 0; + /// The number of bytes this object currently contains. + virtual lldb::offset_t GetByteSize() const = 0; /// Get a const pointer to the data. /// /// \return /// A const pointer to the bytes owned by this object, or NULL /// if the object contains no bytes. - virtual const uint8_t *GetBytes() const = 0; - - /// Get the number of bytes in the data buffer. - /// - /// \return - /// The number of bytes this object currently contains. - virtual lldb::offset_t GetByteSize() const = 0; + const uint8_t *GetBytes() const { return GetBytesImpl(); } llvm::ArrayRef<uint8_t> GetData() const { return llvm::ArrayRef<uint8_t>(GetBytes(), GetByteSize()); } + /// LLVM RTTI support. + /// { + static char ID; + virtual bool isA(const void *ClassID) const { return ClassID == &ID; } + static bool classof(const DataBuffer *data_buffer) { + return data_buffer->isA(&ID); + } + /// } + +protected: + /// Get a const pointer to the data. + /// + /// \return + /// A const pointer to the bytes owned by this object, or NULL + /// if the object contains no bytes. + virtual const uint8_t *GetBytesImpl() const = 0; +}; + +/// \class DataBuffer DataBuffer.h "lldb/Core/DataBuffer.h" +/// A pure virtual protocol class for abstracted writable data buffers. +/// +/// DataBuffer is an abstract class that gets packaged into a shared pointer +/// that can use to implement various ways to store data (on the heap, memory +/// mapped, cached inferior memory). It gets used by DataExtractor so many +/// DataExtractor objects can share the same data and sub-ranges of that +/// shared data, and the last object that contains a reference to the shared +/// data will free it. +class WritableDataBuffer : public DataBuffer { +public: + /// Destructor + /// + /// The destructor is virtual as other classes will inherit from this class + /// 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. + ~WritableDataBuffer() override = default; + + using DataBuffer::GetBytes; + using DataBuffer::GetData; + + /// Get a pointer to the data. + /// + /// \return + /// A pointer to the bytes owned by this object, or NULL if the + /// object contains no bytes. + uint8_t *GetBytes() { return const_cast<uint8_t *>(GetBytesImpl()); } + llvm::MutableArrayRef<uint8_t> GetData() { return llvm::MutableArrayRef<uint8_t>(GetBytes(), GetByteSize()); } + + /// LLVM RTTI support. + /// { + static char ID; + bool isA(const void *ClassID) const override { + return ClassID == &ID || DataBuffer::isA(ClassID); + } + static bool classof(const DataBuffer *data_buffer) { + return data_buffer->isA(&ID); + } + /// } }; -class DataBufferUnowned : public DataBuffer { +class DataBufferUnowned : public WritableDataBuffer { public: DataBufferUnowned(uint8_t *bytes, lldb::offset_t size) : m_bytes(bytes), m_size(size) {} - uint8_t *GetBytes() override { return m_bytes; } - const uint8_t *GetBytes() const override { return m_bytes; } + const uint8_t *GetBytesImpl() const override { return m_bytes; } lldb::offset_t GetByteSize() const override { return m_size; } + /// LLVM RTTI support. + /// { + static char ID; + bool isA(const void *ClassID) const override { + return ClassID == &ID || WritableDataBuffer::isA(ClassID); + } + static bool classof(const DataBuffer *data_buffer) { + return data_buffer->isA(&ID); + } + /// } private: uint8_t *m_bytes; lldb::offset_t m_size; diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/DataBufferHeap.h b/contrib/llvm-project/lldb/include/lldb/Utility/DataBufferHeap.h index ace526bf0a47..a7270e95bf6d 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/DataBufferHeap.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/DataBufferHeap.h @@ -27,7 +27,7 @@ namespace lldb_private { /// pages in. Large amounts of data that comes from files should probably use /// DataBufferLLVM, which can intelligently determine when memory mapping is /// optimal. -class DataBufferHeap : public DataBuffer { +class DataBufferHeap : public WritableDataBuffer { public: /// Default constructor /// @@ -54,17 +54,20 @@ public: /// The number of bytes in \a src to copy. DataBufferHeap(const void *src, lldb::offset_t src_len); + /// Construct by making a copy of a DataBuffer. + /// + /// \param[in] data_buffer + /// A read only data buffer to copy. + DataBufferHeap(const DataBuffer &data_buffer); + /// Destructor. /// /// Virtual destructor since this class inherits from a pure virtual base /// class #DataBuffer. ~DataBufferHeap() override; - /// \copydoc DataBuffer::GetBytes() - uint8_t *GetBytes() override; - /// \copydoc DataBuffer::GetBytes() const - const uint8_t *GetBytes() const override; + const uint8_t *GetBytesImpl() const override; /// \copydoc DataBuffer::GetByteSize() const lldb::offset_t GetByteSize() const override; @@ -80,8 +83,8 @@ public: /// to resize itself to. /// /// \return - /// The size in bytes after that this heap buffer was - /// successfully resized to. + /// The size in bytes after this heap buffer was resized. If + /// the resize failed the size will remain unchanged. lldb::offset_t SetByteSize(lldb::offset_t byte_size); /// Makes a copy of the \a src_len bytes in \a src. @@ -100,6 +103,17 @@ public: void Clear(); + /// LLVM RTTI support. + /// { + static char ID; + bool isA(const void *ClassID) const override { + return ClassID == &ID || WritableDataBuffer::isA(ClassID); + } + static bool classof(const DataBuffer *data_buffer) { + return data_buffer->isA(&ID); + } + /// } + private: // This object uses a std::vector<uint8_t> to store its data. This takes care // of free the data when the object is deleted. diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/DataBufferLLVM.h b/contrib/llvm-project/lldb/include/lldb/Utility/DataBufferLLVM.h index abb1bb40d534..1058d7ac0811 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/DataBufferLLVM.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/DataBufferLLVM.h @@ -17,30 +17,65 @@ namespace llvm { class WritableMemoryBuffer; +class MemoryBuffer; class Twine; -} +} // namespace llvm namespace lldb_private { - class FileSystem; + class DataBufferLLVM : public DataBuffer { public: ~DataBufferLLVM() override; - uint8_t *GetBytes() override; - const uint8_t *GetBytes() const override; + const uint8_t *GetBytesImpl() const override; + lldb::offset_t GetByteSize() const override; + + /// LLVM RTTI support. + /// { + static char ID; + bool isA(const void *ClassID) const override { + return ClassID == &ID || DataBuffer::isA(ClassID); + } + static bool classof(const DataBuffer *data_buffer) { + return data_buffer->isA(&ID); + } + /// } + + /// Construct a DataBufferLLVM from \p Buffer. \p Buffer must be a valid + /// pointer. + explicit DataBufferLLVM(std::unique_ptr<llvm::MemoryBuffer> Buffer); + +protected: + std::unique_ptr<llvm::MemoryBuffer> Buffer; +}; + +class WritableDataBufferLLVM : public WritableDataBuffer { +public: + ~WritableDataBufferLLVM() override; + + const uint8_t *GetBytesImpl() const override; lldb::offset_t GetByteSize() const override; - char *GetChars() { return reinterpret_cast<char *>(GetBytes()); } + /// LLVM RTTI support. + /// { + static char ID; + bool isA(const void *ClassID) const override { + return ClassID == &ID || WritableDataBuffer::isA(ClassID); + } + static bool classof(const DataBuffer *data_buffer) { + return data_buffer->isA(&ID); + } + /// } -private: - friend FileSystem; /// Construct a DataBufferLLVM from \p Buffer. \p Buffer must be a valid /// pointer. - explicit DataBufferLLVM(std::unique_ptr<llvm::WritableMemoryBuffer> Buffer); + explicit WritableDataBufferLLVM( + std::unique_ptr<llvm::WritableMemoryBuffer> Buffer); +protected: std::unique_ptr<llvm::WritableMemoryBuffer> Buffer; }; -} +} // namespace lldb_private #endif diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Event.h b/contrib/llvm-project/lldb/include/lldb/Utility/Event.h index d3176216115a..f533fc5c47fa 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/Event.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/Event.h @@ -42,7 +42,9 @@ public: virtual ~EventData(); virtual ConstString GetFlavor() const = 0; - + + virtual Log *GetLogChannel() { return nullptr; } + virtual void Dump(Stream *s) const; private: diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/GDBRemote.h b/contrib/llvm-project/lldb/include/lldb/Utility/GDBRemote.h index 451181624c87..e39bce5144cf 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/GDBRemote.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/GDBRemote.h @@ -55,7 +55,7 @@ struct GDBRemotePacket { enum Type { ePacketTypeInvalid = 0, ePacketTypeSend, ePacketTypeRecv }; - GDBRemotePacket() {} + GDBRemotePacket() = default; void Clear() { packet.data.clear(); diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Instrumentation.h b/contrib/llvm-project/lldb/include/lldb/Utility/Instrumentation.h index ff6591d63437..13ffc0bd39d0 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/Instrumentation.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/Instrumentation.h @@ -10,8 +10,6 @@ #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" - #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/ErrorHandling.h" diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/LLDBLog.h b/contrib/llvm-project/lldb/include/lldb/Utility/LLDBLog.h new file mode 100644 index 000000000000..63dbb63f6f56 --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Utility/LLDBLog.h @@ -0,0 +1,61 @@ +//===-- LLDBLog.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_LLDBLOG_H +#define LLDB_UTILITY_LLDBLOG_H + +#include "lldb/Utility/Log.h" +#include "llvm/ADT/BitmaskEnum.h" +#include <cstdint> + +namespace lldb_private { + +enum class LLDBLog : Log::MaskType { + API = Log::ChannelFlag<0>, + AST = Log::ChannelFlag<1>, + Breakpoints = Log::ChannelFlag<2>, + Commands = Log::ChannelFlag<3>, + Communication = Log::ChannelFlag<4>, + Connection = Log::ChannelFlag<5>, + DataFormatters = Log::ChannelFlag<6>, + Demangle = Log::ChannelFlag<7>, + DynamicLoader = Log::ChannelFlag<8>, + Events = Log::ChannelFlag<9>, + Expressions = Log::ChannelFlag<10>, + Host = Log::ChannelFlag<11>, + JITLoader = Log::ChannelFlag<12>, + Language = Log::ChannelFlag<13>, + MMap = Log::ChannelFlag<14>, + Modules = Log::ChannelFlag<15>, + Object = Log::ChannelFlag<16>, + OS = Log::ChannelFlag<17>, + Platform = Log::ChannelFlag<18>, + Process = Log::ChannelFlag<19>, + Script = Log::ChannelFlag<20>, + State = Log::ChannelFlag<21>, + Step = Log::ChannelFlag<22>, + Symbols = Log::ChannelFlag<23>, + SystemRuntime = Log::ChannelFlag<24>, + Target = Log::ChannelFlag<25>, + Temporary = Log::ChannelFlag<26>, + Thread = Log::ChannelFlag<27>, + Types = Log::ChannelFlag<28>, + Unwind = Log::ChannelFlag<29>, + Watchpoints = Log::ChannelFlag<30>, + OnDemand = Log::ChannelFlag<31>, + LLVM_MARK_AS_BITMASK_ENUM(Watchpoints), +}; + +LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); + +void InitializeLldbChannel(); + +template <> Log::Channel &LogChannelFor<LLDBLog>(); +} // namespace lldb_private + +#endif // LLDB_UTILITY_LLDBLOG_H diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Log.h b/contrib/llvm-project/lldb/include/lldb/Utility/Log.h index 09fd2cb3a7e6..404cbed14c18 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/Log.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/Log.h @@ -25,6 +25,7 @@ #include <cstdarg> #include <cstdint> #include <memory> +#include <mutex> #include <string> #include <type_traits> @@ -32,7 +33,6 @@ namespace llvm { class raw_ostream; } // Logging Options -#define LLDB_LOG_OPTION_THREADSAFE (1u << 0) #define LLDB_LOG_OPTION_VERBOSE (1u << 1) #define LLDB_LOG_OPTION_PREPEND_SEQUENCE (1u << 3) #define LLDB_LOG_OPTION_PREPEND_TIMESTAMP (1u << 4) @@ -45,6 +45,73 @@ class raw_ostream; // Logging Functions namespace lldb_private { +class LogHandler { +public: + virtual ~LogHandler() = default; + virtual void Emit(llvm::StringRef message) = 0; + + virtual bool isA(const void *ClassID) const { return ClassID == &ID; } + static bool classof(const LogHandler *obj) { return obj->isA(&ID); } + +private: + static char ID; +}; + +class StreamLogHandler : public LogHandler { +public: + StreamLogHandler(int fd, bool should_close, size_t buffer_size = 0); + ~StreamLogHandler() override; + + void Emit(llvm::StringRef message) override; + void Flush(); + + bool isA(const void *ClassID) const override { return ClassID == &ID; } + static bool classof(const LogHandler *obj) { return obj->isA(&ID); } + +private: + std::mutex m_mutex; + llvm::raw_fd_ostream m_stream; + static char ID; +}; + +class CallbackLogHandler : public LogHandler { +public: + CallbackLogHandler(lldb::LogOutputCallback callback, void *baton); + + void Emit(llvm::StringRef message) override; + + bool isA(const void *ClassID) const override { return ClassID == &ID; } + static bool classof(const LogHandler *obj) { return obj->isA(&ID); } + +private: + lldb::LogOutputCallback m_callback; + void *m_baton; + static char ID; +}; + +class RotatingLogHandler : public LogHandler { +public: + RotatingLogHandler(size_t size); + + void Emit(llvm::StringRef message) override; + void Dump(llvm::raw_ostream &stream) const; + + bool isA(const void *ClassID) const override { return ClassID == &ID; } + static bool classof(const LogHandler *obj) { return obj->isA(&ID); } + +private: + size_t NormalizeIndex(size_t i) const; + size_t GetNumMessages() const; + size_t GetFirstMessageIndex() const; + + mutable std::mutex m_mutex; + std::unique_ptr<std::string[]> m_messages; + const size_t m_size = 0; + size_t m_next_index = 0; + size_t m_total_count = 0; + static char ID; +}; + class Log final { public: /// The underlying type of all log channel enums. Declare them as: @@ -97,18 +164,7 @@ public: // after (or concurrently with) this function returning a non-null Log // pointer, it is still safe to attempt to write to the Log object -- the // output will be discarded. - Log *GetLogIfAll(MaskType mask) { - Log *log = log_ptr.load(std::memory_order_relaxed); - if (log && log->GetMask().AllSet(mask)) - return log; - return nullptr; - } - - // This function is safe to call at any time. If the channel is disabled - // after (or concurrently with) this function returning a non-null Log - // pointer, it is still safe to attempt to write to the Log object -- the - // output will be discarded. - Log *GetLogIfAny(MaskType mask) { + Log *GetLog(MaskType mask) { Log *log = log_ptr.load(std::memory_order_relaxed); if (log && log->GetMask().AnySet(mask)) return log; @@ -117,14 +173,12 @@ public: }; - static void Initialize(); - // Static accessors for logging channels static void Register(llvm::StringRef name, Channel &channel); static void Unregister(llvm::StringRef name); static bool - EnableLogChannel(const std::shared_ptr<llvm::raw_ostream> &log_stream_sp, + EnableLogChannel(const std::shared_ptr<LogHandler> &log_handler_sp, uint32_t log_options, llvm::StringRef channel, llvm::ArrayRef<const char *> categories, llvm::raw_ostream &error_stream); @@ -133,6 +187,10 @@ public: llvm::ArrayRef<const char *> categories, llvm::raw_ostream &error_stream); + static bool DumpLogChannel(llvm::StringRef channel, + llvm::raw_ostream &output_stream, + llvm::raw_ostream &error_stream); + static bool ListChannelCategories(llvm::StringRef channel, llvm::raw_ostream &stream); @@ -201,7 +259,7 @@ private: // Their modification however, is still protected by this mutex. llvm::sys::RWMutex m_mutex; - std::shared_ptr<llvm::raw_ostream> m_stream_sp; + std::shared_ptr<LogHandler> m_handler; std::atomic<uint32_t> m_options{0}; std::atomic<MaskType> m_mask{0}; @@ -212,16 +270,18 @@ private: void Format(llvm::StringRef file, llvm::StringRef function, const llvm::formatv_object_base &payload); - std::shared_ptr<llvm::raw_ostream> GetStream() { + std::shared_ptr<LogHandler> GetHandler() { llvm::sys::ScopedReader lock(m_mutex); - return m_stream_sp; + return m_handler; } - void Enable(const std::shared_ptr<llvm::raw_ostream> &stream_sp, - uint32_t options, uint32_t flags); + void Enable(const std::shared_ptr<LogHandler> &handler_sp, uint32_t options, + uint32_t flags); void Disable(uint32_t flags); + bool Dump(llvm::raw_ostream &stream); + typedef llvm::StringMap<Log> ChannelMap; static llvm::ManagedStatic<ChannelMap> g_channel_map; @@ -248,7 +308,7 @@ template <typename Cat> Log::Channel &LogChannelFor() = delete; template <typename Cat> Log *GetLog(Cat mask) { static_assert(std::is_same<Log::MaskType, std::underlying_type_t<Cat>>::value, ""); - return LogChannelFor<Cat>().GetLogIfAny(Log::MaskType(mask)); + return LogChannelFor<Cat>().GetLog(Log::MaskType(mask)); } } // namespace lldb_private @@ -310,4 +370,3 @@ template <typename Cat> Log *GetLog(Cat mask) { #endif // LLDB_UTILITY_LOG_H // TODO: Remove this and fix includes everywhere. -#include "lldb/Utility/Logging.h" diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Logging.h b/contrib/llvm-project/lldb/include/lldb/Utility/Logging.h deleted file mode 100644 index db84da244954..000000000000 --- a/contrib/llvm-project/lldb/include/lldb/Utility/Logging.h +++ /dev/null @@ -1,97 +0,0 @@ -//===-- Logging.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_LOGGING_H -#define LLDB_UTILITY_LOGGING_H - -#include "lldb/Utility/Log.h" -#include "llvm/ADT/BitmaskEnum.h" -#include <cstdint> - -namespace lldb_private { - -enum class LLDBLog : Log::MaskType { - API = Log::ChannelFlag<0>, - AST = Log::ChannelFlag<1>, - Breakpoints = Log::ChannelFlag<2>, - Commands = Log::ChannelFlag<3>, - Communication = Log::ChannelFlag<4>, - Connection = Log::ChannelFlag<5>, - DataFormatters = Log::ChannelFlag<6>, - Demangle = Log::ChannelFlag<7>, - DynamicLoader = Log::ChannelFlag<8>, - Events = Log::ChannelFlag<9>, - Expressions = Log::ChannelFlag<10>, - Host = Log::ChannelFlag<11>, - JITLoader = Log::ChannelFlag<12>, - Language = Log::ChannelFlag<13>, - MMap = Log::ChannelFlag<14>, - Modules = Log::ChannelFlag<15>, - Object = Log::ChannelFlag<16>, - OS = Log::ChannelFlag<17>, - Platform = Log::ChannelFlag<18>, - Process = Log::ChannelFlag<19>, - Script = Log::ChannelFlag<20>, - State = Log::ChannelFlag<21>, - Step = Log::ChannelFlag<22>, - Symbols = Log::ChannelFlag<23>, - SystemRuntime = Log::ChannelFlag<24>, - Target = Log::ChannelFlag<25>, - Temporary = Log::ChannelFlag<26>, - Thread = Log::ChannelFlag<27>, - Types = Log::ChannelFlag<28>, - Unwind = Log::ChannelFlag<29>, - Watchpoints = Log::ChannelFlag<30>, - LLVM_MARK_AS_BITMASK_ENUM(Watchpoints), -}; - -LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); - -// Log Bits specific to logging in lldb -#define LIBLLDB_LOG_PROCESS ::lldb_private::LLDBLog::Process -#define LIBLLDB_LOG_THREAD ::lldb_private::LLDBLog::Thread -#define LIBLLDB_LOG_DYNAMIC_LOADER ::lldb_private::LLDBLog::DynamicLoader -#define LIBLLDB_LOG_EVENTS ::lldb_private::LLDBLog::Events -#define LIBLLDB_LOG_BREAKPOINTS ::lldb_private::LLDBLog::Breakpoints -#define LIBLLDB_LOG_WATCHPOINTS ::lldb_private::LLDBLog::Watchpoints -#define LIBLLDB_LOG_STEP ::lldb_private::LLDBLog::Step -#define LIBLLDB_LOG_EXPRESSIONS ::lldb_private::LLDBLog::Expressions -#define LIBLLDB_LOG_TEMPORARY ::lldb_private::LLDBLog::Temporary -#define LIBLLDB_LOG_STATE ::lldb_private::LLDBLog::State -#define LIBLLDB_LOG_OBJECT ::lldb_private::LLDBLog::Object -#define LIBLLDB_LOG_COMMUNICATION ::lldb_private::LLDBLog::Communication -#define LIBLLDB_LOG_CONNECTION ::lldb_private::LLDBLog::Connection -#define LIBLLDB_LOG_HOST ::lldb_private::LLDBLog::Host -#define LIBLLDB_LOG_UNWIND ::lldb_private::LLDBLog::Unwind -#define LIBLLDB_LOG_API ::lldb_private::LLDBLog::API -#define LIBLLDB_LOG_SCRIPT ::lldb_private::LLDBLog::Script -#define LIBLLDB_LOG_COMMANDS ::lldb_private::LLDBLog::Commands -#define LIBLLDB_LOG_TYPES ::lldb_private::LLDBLog::Types -#define LIBLLDB_LOG_SYMBOLS ::lldb_private::LLDBLog::Symbols -#define LIBLLDB_LOG_MODULES ::lldb_private::LLDBLog::Modules -#define LIBLLDB_LOG_TARGET ::lldb_private::LLDBLog::Target -#define LIBLLDB_LOG_MMAP ::lldb_private::LLDBLog::MMap -#define LIBLLDB_LOG_OS ::lldb_private::LLDBLog::OS -#define LIBLLDB_LOG_PLATFORM ::lldb_private::LLDBLog::Platform -#define LIBLLDB_LOG_SYSTEM_RUNTIME ::lldb_private::LLDBLog::SystemRuntime -#define LIBLLDB_LOG_JIT_LOADER ::lldb_private::LLDBLog::JITLoader -#define LIBLLDB_LOG_LANGUAGE ::lldb_private::LLDBLog::Language -#define LIBLLDB_LOG_DATAFORMATTERS ::lldb_private::LLDBLog::DataFormatters -#define LIBLLDB_LOG_DEMANGLE ::lldb_private::LLDBLog::Demangle -#define LIBLLDB_LOG_AST ::lldb_private::LLDBLog::AST - -Log *GetLogIfAllCategoriesSet(LLDBLog mask); - -Log *GetLogIfAnyCategoriesSet(LLDBLog mask); - -void InitializeLldbChannel(); - -template <> Log::Channel &LogChannelFor<LLDBLog>(); -} // namespace lldb_private - -#endif // LLDB_UTILITY_LOGGING_H diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/ProcessInfo.h b/contrib/llvm-project/lldb/include/lldb/Utility/ProcessInfo.h index fc8b12768999..42a851f034ed 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/ProcessInfo.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/ProcessInfo.h @@ -107,7 +107,7 @@ protected: // to that process. class ProcessInstanceInfo : public ProcessInfo { public: - ProcessInstanceInfo() {} + ProcessInstanceInfo() = default; ProcessInstanceInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) : ProcessInfo(name, arch, pid), m_euid(UINT32_MAX), m_egid(UINT32_MAX), @@ -162,7 +162,7 @@ typedef std::vector<ProcessInstanceInfo> ProcessInstanceInfoList; class ProcessInstanceInfoMatch { public: - ProcessInstanceInfoMatch() {} + ProcessInstanceInfoMatch() = default; ProcessInstanceInfoMatch(const char *process_name, NameMatch process_name_match_type) diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/RangeMap.h b/contrib/llvm-project/lldb/include/lldb/Utility/RangeMap.h index 422f90d807a7..7eb0cab8084c 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/RangeMap.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/RangeMap.h @@ -59,6 +59,17 @@ template <typename B, typename S> struct Range { return false; } + Range Intersect(const Range &rhs) const { + const BaseType lhs_base = this->GetRangeBase(); + const BaseType rhs_base = rhs.GetRangeBase(); + const BaseType lhs_end = this->GetRangeEnd(); + const BaseType rhs_end = rhs.GetRangeEnd(); + Range range; + range.SetRangeBase(std::max(lhs_base, rhs_base)); + range.SetRangeEnd(std::min(lhs_end, rhs_end)); + return range; + } + BaseType GetRangeEnd() const { return base + size; } void SetRangeEnd(BaseType end) { @@ -99,12 +110,7 @@ template <typename B, typename S> struct Range { // Returns true if the two ranges intersect bool DoesIntersect(const Range &rhs) const { - const BaseType lhs_base = this->GetRangeBase(); - const BaseType rhs_base = rhs.GetRangeBase(); - const BaseType lhs_end = this->GetRangeEnd(); - const BaseType rhs_end = rhs.GetRangeEnd(); - bool result = (lhs_base < rhs_end) && (lhs_end > rhs_base); - return result; + return Intersect(rhs).IsValid(); } bool operator<(const Range &rhs) const { @@ -133,6 +139,38 @@ public: ~RangeVector() = default; + static RangeVector GetOverlaps(const RangeVector &vec1, + const RangeVector &vec2) { +#ifdef ASSERT_RANGEMAP_ARE_SORTED + assert(vec1.IsSorted() && vec2.IsSorted()); +#endif + RangeVector result; + auto pos1 = vec1.begin(); + auto end1 = vec1.end(); + auto pos2 = vec2.begin(); + auto end2 = vec2.end(); + while (pos1 != end1 && pos2 != end2) { + Entry entry = pos1->Intersect(*pos2); + if (entry.IsValid()) + result.Append(entry); + if (pos1->GetRangeEnd() < pos2->GetRangeEnd()) + ++pos1; + else + ++pos2; + } + return result; + } + + bool operator==(const RangeVector &rhs) const { + if (GetSize() != rhs.GetSize()) + return false; + for (size_t i = 0; i < GetSize(); ++i) { + if (GetEntryRef(i) != rhs.GetEntryRef(i)) + return false; + } + return true; + } + void Append(const Entry &entry) { m_entries.push_back(entry); } void Append(B base, S size) { m_entries.emplace_back(base, size); } diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Reproducer.h b/contrib/llvm-project/lldb/include/lldb/Utility/Reproducer.h index 35043d688511..e81abad2ec32 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/Reproducer.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/Reproducer.h @@ -220,25 +220,11 @@ private: mutable std::mutex m_mutex; }; -class Verifier { -public: - Verifier(Loader *loader) : m_loader(loader) {} - void Verify(llvm::function_ref<void(llvm::StringRef)> error_callback, - llvm::function_ref<void(llvm::StringRef)> warning_callback, - llvm::function_ref<void(llvm::StringRef)> note_callback) const; - -private: - Loader *m_loader; -}; - struct ReplayOptions { bool verify = true; bool check_version = true; }; -llvm::Error Finalize(Loader *loader); -llvm::Error Finalize(const FileSpec &root); - } // namespace repro } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/ReproducerProvider.h b/contrib/llvm-project/lldb/include/lldb/Utility/ReproducerProvider.h index 56aadf92369e..72ddf64f7ebc 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/ReproducerProvider.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/ReproducerProvider.h @@ -91,23 +91,6 @@ public: } }; -class FlushingFileCollector : public llvm::FileCollectorBase { -public: - FlushingFileCollector(llvm::StringRef files_path, llvm::StringRef dirs_path, - std::error_code &ec); - -protected: - void addFileImpl(llvm::StringRef file) override; - - llvm::vfs::directory_iterator - addDirectoryImpl(const llvm::Twine &dir, - llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs, - std::error_code &dir_ec) override; - - llvm::Optional<llvm::raw_fd_ostream> m_files_os; - llvm::Optional<llvm::raw_fd_ostream> m_dirs_os; -}; - class FileProvider : public Provider<FileProvider> { public: struct Info { @@ -116,25 +99,24 @@ public: }; FileProvider(const FileSpec &directory) : Provider(directory) { - std::error_code ec; - m_collector = std::make_shared<FlushingFileCollector>( - directory.CopyByAppendingPathComponent("files.txt").GetPath(), - directory.CopyByAppendingPathComponent("dirs.txt").GetPath(), ec); - if (ec) - m_collector.reset(); + m_collector = std::make_shared<llvm::FileCollector>( + directory.CopyByAppendingPathComponent("root").GetPath(), + directory.GetPath()); } - std::shared_ptr<llvm::FileCollectorBase> GetFileCollector() { + std::shared_ptr<llvm::FileCollector> GetFileCollector() { return m_collector; } + void Keep() override; + void RecordInterestingDirectory(const llvm::Twine &dir); void RecordInterestingDirectoryRecursive(const llvm::Twine &dir); static char ID; private: - std::shared_ptr<FlushingFileCollector> m_collector; + std::shared_ptr<llvm::FileCollector> m_collector; }; /// Provider for the LLDB version number. diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/StreamCallback.h b/contrib/llvm-project/lldb/include/lldb/Utility/StreamCallback.h deleted file mode 100644 index d234cbea85c6..000000000000 --- a/contrib/llvm-project/lldb/include/lldb/Utility/StreamCallback.h +++ /dev/null @@ -1,35 +0,0 @@ -//===-- StreamCallback.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_STREAMCALLBACK_H -#define LLDB_UTILITY_STREAMCALLBACK_H - -#include "lldb/lldb-types.h" -#include "llvm/Support/raw_ostream.h" - -#include <cstddef> -#include <cstdint> - -namespace lldb_private { - -class StreamCallback : public llvm::raw_ostream { -public: - StreamCallback(lldb::LogOutputCallback callback, void *baton); - ~StreamCallback() override = default; - -private: - lldb::LogOutputCallback m_callback; - void *m_baton; - - void write_impl(const char *Ptr, size_t Size) override; - uint64_t current_pos() const override; -}; - -} // namespace lldb_private - -#endif // LLDB_UTILITY_STREAMCALLBACK_H diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/StringExtractorGDBRemote.h b/contrib/llvm-project/lldb/include/lldb/Utility/StringExtractorGDBRemote.h index 459adae04452..c32ce0389116 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/StringExtractorGDBRemote.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/StringExtractorGDBRemote.h @@ -23,7 +23,7 @@ public: typedef bool (*ResponseValidatorCallback)( void *baton, const StringExtractorGDBRemote &response); - StringExtractorGDBRemote() {} + StringExtractorGDBRemote() = default; StringExtractorGDBRemote(llvm::StringRef str) : StringExtractor(str), m_validator(nullptr) {} @@ -136,6 +136,7 @@ public: eServerPacketType_vAttachName, eServerPacketType_vCont, eServerPacketType_vCont_actions, // vCont? + eServerPacketType_vKill, eServerPacketType_vRun, eServerPacketType_stop_reason, // '?' @@ -174,6 +175,10 @@ public: eServerPacketType_QMemTags, // write memory tags eServerPacketType_qLLDBSaveCore, + eServerPacketType_QSetIgnoredExceptions, + eServerPacketType_QNonStop, + eServerPacketType_vStopped, + eServerPacketType_vCtrlC, }; ServerPacketType GetServerPacketType() const; diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/StructuredData.h b/contrib/llvm-project/lldb/include/lldb/Utility/StructuredData.h index 11eee92f8c3b..9f6300f4f115 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/StructuredData.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/StructuredData.h @@ -375,15 +375,15 @@ public: } } - ObjectSP GetKeys() const { - auto object_sp = std::make_shared<Array>(); + ArraySP GetKeys() const { + auto array_sp = std::make_shared<Array>(); collection::const_iterator iter; for (iter = m_dict.begin(); iter != m_dict.end(); ++iter) { auto key_object_sp = std::make_shared<String>(); key_object_sp->SetValue(iter->first.AsCString()); - object_sp->Push(key_object_sp); + array_sp->Push(key_object_sp); } - return object_sp; + return array_sp; } ObjectSP GetValueForKey(llvm::StringRef key) const { diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/TraceGDBRemotePackets.h b/contrib/llvm-project/lldb/include/lldb/Utility/TraceGDBRemotePackets.h index 1d2448b05f2a..c6d3f524d1d1 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/TraceGDBRemotePackets.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/TraceGDBRemotePackets.h @@ -11,6 +11,8 @@ #include "llvm/Support/JSON.h" +#include <chrono> + #include "lldb/lldb-defines.h" #include "lldb/lldb-enumerations.h" @@ -44,7 +46,7 @@ struct TraceStartRequest { /// 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; + llvm::Optional<std::vector<lldb::tid_t>> tids; /// \return /// \b true if \a tids is \a None, i.e. whole process tracing. @@ -72,7 +74,7 @@ struct TraceStopRequest { 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; + llvm::Optional<std::vector<lldb::tid_t>> tids; }; bool fromJSON(const llvm::json::Value &value, TraceStopRequest &packet, @@ -97,7 +99,7 @@ struct TraceBinaryData { /// Identifier of data to fetch with jLLDBTraceGetBinaryData. std::string kind; /// Size in bytes for this data. - int64_t size; + uint64_t size; }; bool fromJSON(const llvm::json::Value &value, TraceBinaryData &packet, @@ -106,9 +108,9 @@ bool fromJSON(const llvm::json::Value &value, TraceBinaryData &packet, llvm::json::Value toJSON(const TraceBinaryData &packet); struct TraceThreadState { - int64_t tid; + lldb::tid_t tid; /// List of binary data objects for this thread. - std::vector<TraceBinaryData> binaryData; + std::vector<TraceBinaryData> binary_data; }; bool fromJSON(const llvm::json::Value &value, TraceThreadState &packet, @@ -116,9 +118,24 @@ bool fromJSON(const llvm::json::Value &value, TraceThreadState &packet, llvm::json::Value toJSON(const TraceThreadState &packet); +struct TraceCpuState { + lldb::cpu_id_t id; + /// List of binary data objects for this core. + std::vector<TraceBinaryData> binary_data; +}; + +bool fromJSON(const llvm::json::Value &value, TraceCpuState &packet, + llvm::json::Path path); + +llvm::json::Value toJSON(const TraceCpuState &packet); + struct TraceGetStateResponse { - std::vector<TraceThreadState> tracedThreads; - std::vector<TraceBinaryData> processBinaryData; + std::vector<TraceThreadState> traced_threads; + std::vector<TraceBinaryData> process_binary_data; + llvm::Optional<std::vector<TraceCpuState>> cpus; + llvm::Optional<std::vector<std::string>> warnings; + + void AddWarning(llvm::StringRef warning); }; bool fromJSON(const llvm::json::Value &value, TraceGetStateResponse &packet, @@ -135,11 +152,9 @@ struct TraceGetBinaryDataRequest { /// 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; + llvm::Optional<lldb::tid_t> tid; + /// Optional core id if the data is related to a cpu core. + llvm::Optional<lldb::cpu_id_t> cpu_id; }; bool fromJSON(const llvm::json::Value &value, diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/TraceIntelPTGDBRemotePackets.h b/contrib/llvm-project/lldb/include/lldb/Utility/TraceIntelPTGDBRemotePackets.h index 8f4947b1f189..36b594613a91 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/TraceIntelPTGDBRemotePackets.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/TraceIntelPTGDBRemotePackets.h @@ -11,27 +11,46 @@ #include "lldb/Utility/TraceGDBRemotePackets.h" +#include "llvm/Support/JSON.h" + +#include <chrono> + /// See docs/lldb-gdb-remote.txt for more information. +/// +/// Do not use system-dependent types, like size_t, because they might cause +/// issues when compiling on arm. namespace lldb_private { +// List of data kinds used by jLLDBGetState and jLLDBGetBinaryData. +struct IntelPTDataKinds { + static const char *kProcFsCpuInfo; + static const char *kIptTrace; + static const char *kPerfContextSwitchTrace; +}; + /// jLLDBTraceStart gdb-remote packet /// \{ struct TraceIntelPTStartRequest : TraceStartRequest { /// Size in bytes to use for each thread's trace buffer. - int64_t threadBufferSize; + uint64_t ipt_trace_size; /// Whether to enable TSC - bool enableTsc; + bool enable_tsc; /// PSB packet period - llvm::Optional<int64_t> psbPeriod; + llvm::Optional<uint64_t> psb_period; /// 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; + llvm::Optional<uint64_t> process_buffer_size_limit; + + /// Whether to have a trace buffer per thread or per cpu cpu. + llvm::Optional<bool> per_cpu_tracing; + + bool IsPerCpuTracing() const; }; bool fromJSON(const llvm::json::Value &value, TraceIntelPTStartRequest &packet, @@ -40,6 +59,67 @@ bool fromJSON(const llvm::json::Value &value, TraceIntelPTStartRequest &packet, llvm::json::Value toJSON(const TraceIntelPTStartRequest &packet); /// \} +/// Helper structure to help parse long numbers that can't +/// be easily represented by a JSON number that is compatible with +/// Javascript (52 bits) or that can also be represented as hex. +/// +/// \{ +struct JSONUINT64 { + uint64_t value; +}; + +llvm::json::Value toJSON(const JSONUINT64 &uint64, bool hex); + +bool fromJSON(const llvm::json::Value &value, JSONUINT64 &uint64, + llvm::json::Path path); +/// \} + +/// jLLDBTraceGetState gdb-remote packet +/// \{ + +/// TSC to wall time conversion values defined in the Linux perf_event_open API +/// when the capibilities cap_user_time and cap_user_time_zero are set. See the +/// See the documentation of `time_zero` in +/// https://man7.org/linux/man-pages/man2/perf_event_open.2.html for more +/// information. +struct LinuxPerfZeroTscConversion { + /// Convert TSC value to nanosecond wall time. The beginning of time (0 + /// nanoseconds) is defined by the kernel at boot time and has no particularly + /// useful meaning. On the other hand, this value is constant for an entire + /// trace session. + // See 'time_zero' section of + // https://man7.org/linux/man-pages/man2/perf_event_open.2.html + /// + /// \param[in] tsc + /// The TSC value to be converted. + /// + /// \return + /// Nanosecond wall time. + uint64_t ToNanos(uint64_t tsc) const; + + uint64_t ToTSC(uint64_t nanos) const; + + uint32_t time_mult; + uint16_t time_shift; + JSONUINT64 time_zero; +}; + +struct TraceIntelPTGetStateResponse : TraceGetStateResponse { + /// The TSC to wall time conversion if it exists, otherwise \b nullptr. + llvm::Optional<LinuxPerfZeroTscConversion> tsc_perf_zero_conversion; +}; + +bool fromJSON(const llvm::json::Value &value, + LinuxPerfZeroTscConversion &packet, llvm::json::Path path); + +llvm::json::Value toJSON(const LinuxPerfZeroTscConversion &packet); + +bool fromJSON(const llvm::json::Value &value, + TraceIntelPTGetStateResponse &packet, llvm::json::Path path); + +llvm::json::Value toJSON(const TraceIntelPTGetStateResponse &packet); +/// \} + } // namespace lldb_private #endif // LLDB_UTILITY_TRACEINTELPTGDBREMOTEPACKETS_H diff --git a/contrib/llvm-project/lldb/include/lldb/Version/Version.inc.in b/contrib/llvm-project/lldb/include/lldb/Version/Version.inc.in index 5098bb1c2be5..148bac2ffcff 100644 --- a/contrib/llvm-project/lldb/include/lldb/Version/Version.inc.in +++ b/contrib/llvm-project/lldb/include/lldb/Version/Version.inc.in @@ -2,5 +2,5 @@ #define LLDB_VERSION_STRING "@LLDB_VERSION@" #define LLDB_VERSION_MAJOR @LLDB_VERSION_MAJOR@ #define LLDB_VERSION_MINOR @LLDB_VERSION_MINOR@ -#define LLDB_VERSION_PATCHLEVEL @LLDB_VERSION_PATCHLEVEL@ +#define LLDB_VERSION_PATCH @LLDB_VERSION_PATCH@ #cmakedefine LLDB_FULL_VERSION_STRING "@LLDB_FULL_VERSION_STRING@" diff --git a/contrib/llvm-project/lldb/include/lldb/lldb-enumerations.h b/contrib/llvm-project/lldb/include/lldb/lldb-enumerations.h index a586b8423331..104e7253b791 100644 --- a/contrib/llvm-project/lldb/include/lldb/lldb-enumerations.h +++ b/contrib/llvm-project/lldb/include/lldb/lldb-enumerations.h @@ -602,6 +602,12 @@ enum CommandArgumentType { eArgTypeColumnNum, eArgTypeModuleUUID, eArgTypeSaveCoreStyle, + eArgTypeLogHandler, + eArgTypeSEDStylePair, + eArgTypeRecognizerID, + eArgTypeConnectURL, + eArgTypeTargetID, + eArgTypeStopHookID, eArgTypeLastArg // Always keep this entry as the last entry in this // enumeration!! }; @@ -749,6 +755,7 @@ enum BasicType { eBasicTypeUnsignedWChar, eBasicTypeChar16, eBasicTypeChar32, + eBasicTypeChar8, eBasicTypeShort, eBasicTypeUnsignedShort, eBasicTypeInt, @@ -1140,6 +1147,27 @@ enum SaveCoreStyle { eSaveCoreStackOnly = 3, }; +// Type of counter values associated with instructions in a trace. +enum TraceCounter { + // Timestamp counter, like the one offered by Intel CPUs (TSC). + eTraceCounterTSC = 0, +}; + +// Events that might happen during a trace session. +enum TraceEvent { + // Tracing was disabled for some time due to a software trigger + eTraceEventDisabledSW, + // Tracing was disable for some time due to a hardware trigger + eTraceEventDisabledHW, +}; + +// Enum used to identify which kind of item a \a TraceCursor is pointing at +enum TraceItemKind { + eTraceItemKindError = 0, + eTraceItemKindEvent, + eTraceItemKindInstruction, +}; + } // 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 6f8c52ff3749..487b2f20792b 100644 --- a/contrib/llvm-project/lldb/include/lldb/lldb-forward.h +++ b/contrib/llvm-project/lldb/include/lldb/lldb-forward.h @@ -67,6 +67,7 @@ class DWARFCallFrameInfo; class DWARFDataExtractor; class DWARFExpression; class DataBuffer; +class WritableDataBuffer; class DataBufferHeap; class DataEncoder; class DataExtractor; @@ -309,6 +310,7 @@ typedef std::shared_ptr<lldb_private::CommandObject> CommandObjectSP; typedef std::shared_ptr<lldb_private::Connection> ConnectionSP; typedef std::shared_ptr<lldb_private::CompileUnit> CompUnitSP; typedef std::shared_ptr<lldb_private::DataBuffer> DataBufferSP; +typedef std::shared_ptr<lldb_private::WritableDataBuffer> WritableDataBufferSP; typedef std::shared_ptr<lldb_private::DataExtractor> DataExtractorSP; typedef std::shared_ptr<lldb_private::Debugger> DebuggerSP; typedef std::weak_ptr<lldb_private::Debugger> DebuggerWP; diff --git a/contrib/llvm-project/lldb/include/lldb/lldb-private-enumerations.h b/contrib/llvm-project/lldb/include/lldb/lldb-private-enumerations.h index 9bbb889359b1..2d13e6ef65e1 100644 --- a/contrib/llvm-project/lldb/include/lldb/lldb-private-enumerations.h +++ b/contrib/llvm-project/lldb/include/lldb/lldb-private-enumerations.h @@ -222,6 +222,14 @@ enum StatisticKind { StatisticMax = 4 }; +// Enumeration that can be used to specify a log handler. +enum LogHandlerKind { + eLogHandlerStream, + eLogHandlerCallback, + eLogHandlerCircular, + eLogHandlerSystem, + eLogHandlerDefault = eLogHandlerStream, +}; inline std::string GetStatDescription(lldb_private::StatisticKind K) { switch (K) { 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 2ed083ec8ae9..41cc8bd389dc 100644 --- a/contrib/llvm-project/lldb/include/lldb/lldb-private-interfaces.h +++ b/contrib/llvm-project/lldb/include/lldb/lldb-private-interfaces.h @@ -45,13 +45,13 @@ typedef size_t (*ObjectFileGetModuleSpecifications)( lldb::offset_t data_offset, lldb::offset_t file_offset, lldb::offset_t length, ModuleSpecList &module_specs); typedef ObjectFile *(*ObjectFileCreateInstance)(const lldb::ModuleSP &module_sp, - lldb::DataBufferSP &data_sp, + lldb::DataBufferSP data_sp, lldb::offset_t data_offset, const FileSpec *file, lldb::offset_t file_offset, lldb::offset_t length); typedef ObjectFile *(*ObjectFileCreateMemoryInstance)( - const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, + const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t offset); typedef bool (*ObjectFileSaveCore)(const lldb::ProcessSP &process_sp, const FileSpec &outfile, @@ -115,8 +115,8 @@ typedef int (*ComparisonFunction)(const void *, const void *); typedef void (*DebuggerInitializeCallback)(Debugger &debugger); /// Trace /// \{ -typedef llvm::Expected<lldb::TraceSP> (*TraceCreateInstanceForSessionFile)( - const llvm::json::Value &trace_session_file, +typedef llvm::Expected<lldb::TraceSP> (*TraceCreateInstanceFromBundle)( + const llvm::json::Value &trace_bundle_description, llvm::StringRef session_file_dir, lldb_private::Debugger &debugger); typedef llvm::Expected<lldb::TraceSP> (*TraceCreateInstanceForLiveProcess)( Process &process); diff --git a/contrib/llvm-project/lldb/include/lldb/lldb-types.h b/contrib/llvm-project/lldb/include/lldb/lldb-types.h index 976da35b11dd..462f4275042c 100644 --- a/contrib/llvm-project/lldb/include/lldb/lldb-types.h +++ b/contrib/llvm-project/lldb/include/lldb/lldb-types.h @@ -89,6 +89,7 @@ typedef int32_t break_id_t; typedef int32_t watch_id_t; typedef void *opaque_compiler_type_t; typedef uint64_t queue_id_t; +typedef uint32_t cpu_id_t; // CPU core id } // namespace lldb #endif // LLDB_LLDB_TYPES_H diff --git a/contrib/llvm-project/lldb/source/API/SBBroadcaster.cpp b/contrib/llvm-project/lldb/source/API/SBBroadcaster.cpp index f145bc6e99d8..58920931bc5f 100644 --- a/contrib/llvm-project/lldb/source/API/SBBroadcaster.cpp +++ b/contrib/llvm-project/lldb/source/API/SBBroadcaster.cpp @@ -19,7 +19,7 @@ using namespace lldb_private; SBBroadcaster::SBBroadcaster() { LLDB_INSTRUMENT_VA(this); } SBBroadcaster::SBBroadcaster(const char *name) - : m_opaque_sp(new Broadcaster(nullptr, name)), m_opaque_ptr(nullptr) { + : m_opaque_sp(new Broadcaster(nullptr, name)) { LLDB_INSTRUMENT_VA(this, name); m_opaque_ptr = m_opaque_sp.get(); diff --git a/contrib/llvm-project/lldb/source/API/SBCommandInterpreter.cpp b/contrib/llvm-project/lldb/source/API/SBCommandInterpreter.cpp index 073c1a1b042c..aa46f1085dc9 100644 --- a/contrib/llvm-project/lldb/source/API/SBCommandInterpreter.cpp +++ b/contrib/llvm-project/lldb/source/API/SBCommandInterpreter.cpp @@ -47,20 +47,24 @@ public: auto_repeat_command == nullptr ? llvm::None : llvm::Optional<std::string>(auto_repeat_command); + // We don't know whether any given command coming from this interface takes + // arguments or not so here we're just disabling the basic args check. + CommandArgumentData none_arg{eArgTypeNone, eArgRepeatStar}; + m_arguments.push_back({none_arg}); } bool IsRemovable() const override { return true; } /// More documentation is available in lldb::CommandObject::GetRepeatCommand, - /// but in short, if nullptr is returned, the previous command will be + /// but in short, if llvm::None is returned, the previous command will be /// repeated, and if an empty string is returned, no commands will be /// executed. - const char *GetRepeatCommand(Args ¤t_command_args, - uint32_t index) override { + llvm::Optional<std::string> GetRepeatCommand(Args ¤t_command_args, + uint32_t index) override { if (!m_auto_repeat_command) - return nullptr; + return llvm::None; else - return m_auto_repeat_command->c_str(); + return m_auto_repeat_command; } protected: @@ -329,6 +333,12 @@ bool SBCommandInterpreter::HasAliasOptions() { return (IsValid() ? m_opaque_ptr->HasAliasOptions() : false); } +bool SBCommandInterpreter::IsInteractive() { + LLDB_INSTRUMENT_VA(this); + + return (IsValid() ? m_opaque_ptr->IsInteractive() : false); +} + SBProcess SBCommandInterpreter::GetProcess() { LLDB_INSTRUMENT_VA(this); @@ -417,7 +427,7 @@ void SBCommandInterpreter::reset( m_opaque_ptr = interpreter; } -void SBCommandInterpreter::SourceInitFileInHomeDirectory( +void SBCommandInterpreter::SourceInitFileInGlobalDirectory( SBCommandReturnObject &result) { LLDB_INSTRUMENT_VA(this, result); @@ -427,13 +437,20 @@ void SBCommandInterpreter::SourceInitFileInHomeDirectory( std::unique_lock<std::recursive_mutex> lock; if (target_sp) lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex()); - m_opaque_ptr->SourceInitFileHome(result.ref()); + m_opaque_ptr->SourceInitFileGlobal(result.ref()); } else { result->AppendError("SBCommandInterpreter is not valid"); } } void SBCommandInterpreter::SourceInitFileInHomeDirectory( + SBCommandReturnObject &result) { + LLDB_INSTRUMENT_VA(this, result); + + SourceInitFileInHomeDirectory(result, /*is_repl=*/false); +} + +void SBCommandInterpreter::SourceInitFileInHomeDirectory( SBCommandReturnObject &result, bool is_repl) { LLDB_INSTRUMENT_VA(this, result, is_repl); diff --git a/contrib/llvm-project/lldb/source/API/SBCompileUnit.cpp b/contrib/llvm-project/lldb/source/API/SBCompileUnit.cpp index 46a319c6b7a3..3aa65e225d7a 100644 --- a/contrib/llvm-project/lldb/source/API/SBCompileUnit.cpp +++ b/contrib/llvm-project/lldb/source/API/SBCompileUnit.cpp @@ -77,6 +77,20 @@ SBLineEntry SBCompileUnit::GetLineEntryAtIndex(uint32_t idx) const { return sb_line_entry; } +uint32_t SBCompileUnit::FindLineEntryIndex(lldb::SBLineEntry &line_entry, + bool exact) const { + LLDB_INSTRUMENT_VA(this, line_entry, exact); + + if (!m_opaque_ptr || !line_entry.IsValid()) + return UINT32_MAX; + + LineEntry found_line_entry; + + return m_opaque_ptr->FindLineEntry(0, line_entry.GetLine(), + line_entry.GetFileSpec().get(), exact, + &line_entry.ref()); +} + uint32_t SBCompileUnit::FindLineEntryIndex(uint32_t start_idx, uint32_t line, SBFileSpec *inline_file_spec) const { LLDB_INSTRUMENT_VA(this, start_idx, line, inline_file_spec); diff --git a/contrib/llvm-project/lldb/source/API/SBDebugger.cpp b/contrib/llvm-project/lldb/source/API/SBDebugger.cpp index 8b09d6a8e435..0de934b2a9bd 100644 --- a/contrib/llvm-project/lldb/source/API/SBDebugger.cpp +++ b/contrib/llvm-project/lldb/source/API/SBDebugger.cpp @@ -6,10 +6,10 @@ // //===----------------------------------------------------------------------===// +#include "lldb/API/SBDebugger.h" #include "SystemInitializerFull.h" #include "lldb/Utility/Instrumentation.h" - -#include "lldb/API/SBDebugger.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/API/SBBroadcaster.h" #include "lldb/API/SBCommandInterpreter.h" @@ -27,6 +27,7 @@ #include "lldb/API/SBStructuredData.h" #include "lldb/API/SBTarget.h" #include "lldb/API/SBThread.h" +#include "lldb/API/SBTrace.h" #include "lldb/API/SBTypeCategory.h" #include "lldb/API/SBTypeFilter.h" #include "lldb/API/SBTypeFormat.h" @@ -35,6 +36,7 @@ #include "lldb/API/SBTypeSynthetic.h" #include "lldb/Core/Debugger.h" +#include "lldb/Core/DebuggerEvents.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Progress.h" #include "lldb/Core/StreamFile.h" @@ -56,6 +58,8 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/PrettyStackTrace.h" +#include "llvm/Support/Signals.h" using namespace lldb; using namespace lldb_private; @@ -151,10 +155,9 @@ const char *SBDebugger::GetProgressFromEvent(const lldb::SBEvent &event, uint64_t &completed, uint64_t &total, bool &is_debugger_specific) { - LLDB_INSTRUMENT_VA(event, progress_id, completed, total, - is_debugger_specific); - const Debugger::ProgressEventData *progress_data = - Debugger::ProgressEventData::GetEventDataFromEvent(event.get()); + LLDB_INSTRUMENT_VA(event); + const ProgressEventData *progress_data = + ProgressEventData::GetEventDataFromEvent(event.get()); if (progress_data == nullptr) return nullptr; progress_id = progress_data->GetID(); @@ -164,6 +167,26 @@ const char *SBDebugger::GetProgressFromEvent(const lldb::SBEvent &event, return progress_data->GetMessage().c_str(); } +lldb::SBStructuredData +SBDebugger::GetDiagnosticFromEvent(const lldb::SBEvent &event) { + LLDB_INSTRUMENT_VA(event); + + const DiagnosticEventData *diagnostic_data = + DiagnosticEventData::GetEventDataFromEvent(event.get()); + if (!diagnostic_data) + return {}; + + auto dictionary = std::make_unique<StructuredData::Dictionary>(); + dictionary->AddStringItem("message", diagnostic_data->GetMessage()); + dictionary->AddStringItem("type", diagnostic_data->GetPrefix()); + dictionary->AddBooleanItem("debugger_specific", + diagnostic_data->IsDebuggerSpecific()); + + SBStructuredData data; + data.m_impl_up->SetObjectSP(std::move(dictionary)); + return data; +} + SBBroadcaster SBDebugger::GetBroadcaster() { LLDB_INSTRUMENT_VA(this); SBBroadcaster broadcaster(&m_opaque_sp->GetBroadcaster(), false); @@ -186,6 +209,15 @@ lldb::SBError SBDebugger::InitializeWithErrorHandling() { return error; } +void SBDebugger::PrintStackTraceOnError() { + LLDB_INSTRUMENT(); + + llvm::EnablePrettyStackTrace(); + static std::string executable = + llvm::sys::fs::getMainExecutable(nullptr, nullptr); + llvm::sys::PrintStackTraceOnErrorSignal(executable); +} + void SBDebugger::Terminate() { LLDB_INSTRUMENT(); @@ -236,6 +268,7 @@ SBDebugger SBDebugger::Create(bool source_init_files, interp.get()->SkipLLDBInitFiles(false); interp.get()->SkipAppInitFiles(false); SBCommandReturnObject result; + interp.SourceInitFileInGlobalDirectory(result); interp.SourceInitFileInHomeDirectory(result, false); } else { interp.get()->SkipLLDBInitFiles(true); @@ -760,7 +793,7 @@ lldb::SBTarget SBDebugger::CreateTarget(const char *filename, sb_error.SetErrorString("invalid debugger"); } - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + Log *log = GetLog(LLDBLog::API); LLDB_LOGF(log, "SBDebugger(%p)::CreateTarget (filename=\"%s\", triple=%s, " "platform_name=%s, add_dependent_modules=%u, error=%s) => " @@ -788,7 +821,7 @@ SBDebugger::CreateTargetWithFileAndTargetTriple(const char *filename, sb_target.SetSP(target_sp); } - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + Log *log = GetLog(LLDBLog::API); LLDB_LOGF(log, "SBDebugger(%p)::CreateTargetWithFileAndTargetTriple " "(filename=\"%s\", triple=%s) => SBTarget(%p)", @@ -802,7 +835,7 @@ SBTarget SBDebugger::CreateTargetWithFileAndArch(const char *filename, const char *arch_cstr) { LLDB_INSTRUMENT_VA(this, filename, arch_cstr); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + Log *log = GetLog(LLDBLog::API); SBTarget sb_target; TargetSP target_sp; @@ -858,7 +891,7 @@ SBTarget SBDebugger::CreateTarget(const char *filename) { if (error.Success()) sb_target.SetSP(target_sp); } - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + Log *log = GetLog(LLDBLog::API); LLDB_LOGF(log, "SBDebugger(%p)::CreateTarget (filename=\"%s\") => SBTarget(%p)", static_cast<void *>(m_opaque_sp.get()), filename, @@ -873,7 +906,7 @@ SBTarget SBDebugger::GetDummyTarget() { if (m_opaque_sp) { sb_target.SetSP(m_opaque_sp->GetDummyTarget().shared_from_this()); } - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + Log *log = GetLog(LLDBLog::API); LLDB_LOGF(log, "SBDebugger(%p)::GetDummyTarget() => SBTarget(%p)", static_cast<void *>(m_opaque_sp.get()), static_cast<void *>(sb_target.GetSP().get())); @@ -894,7 +927,7 @@ bool SBDebugger::DeleteTarget(lldb::SBTarget &target) { } } - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + Log *log = GetLog(LLDBLog::API); LLDB_LOGF(log, "SBDebugger(%p)::DeleteTarget (SBTarget(%p)) => %i", static_cast<void *>(m_opaque_sp.get()), static_cast<void *>(target.m_opaque_sp.get()), result); @@ -977,7 +1010,7 @@ uint32_t SBDebugger::GetNumTargets() { SBTarget SBDebugger::GetSelectedTarget() { LLDB_INSTRUMENT_VA(this); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + Log *log = GetLog(LLDBLog::API); SBTarget sb_target; TargetSP target_sp; @@ -1001,7 +1034,7 @@ SBTarget SBDebugger::GetSelectedTarget() { void SBDebugger::SetSelectedTarget(SBTarget &sb_target) { LLDB_INSTRUMENT_VA(this, sb_target); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + Log *log = GetLog(LLDBLog::API); TargetSP target_sp(sb_target.GetSP()); if (m_opaque_sp) { @@ -1019,7 +1052,7 @@ void SBDebugger::SetSelectedTarget(SBTarget &sb_target) { SBPlatform SBDebugger::GetSelectedPlatform() { LLDB_INSTRUMENT_VA(this); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + Log *log = GetLog(LLDBLog::API); SBPlatform sb_platform; DebuggerSP debugger_sp(m_opaque_sp); @@ -1036,7 +1069,7 @@ SBPlatform SBDebugger::GetSelectedPlatform() { void SBDebugger::SetSelectedPlatform(SBPlatform &sb_platform) { LLDB_INSTRUMENT_VA(this, sb_platform); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + Log *log = GetLog(LLDBLog::API); DebuggerSP debugger_sp(m_opaque_sp); if (debugger_sp) { @@ -1123,7 +1156,7 @@ void SBDebugger::DispatchInput(void *baton, const void *data, size_t data_len) { void SBDebugger::DispatchInput(const void *data, size_t data_len) { LLDB_INSTRUMENT_VA(this, data, data_len); - // Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + // Log *log(GetLog (LLDBLog::API)); // // if (log) // LLDB_LOGF(log, "SBDebugger(%p)::DispatchInput (data=\"%.*s\", @@ -1312,7 +1345,7 @@ void SBDebugger::SetTerminalWidth(uint32_t term_width) { const char *SBDebugger::GetPrompt() const { LLDB_INSTRUMENT_VA(this); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + Log *log = GetLog(LLDBLog::API); LLDB_LOGF(log, "SBDebugger(%p)::GetPrompt () => \"%s\"", static_cast<void *>(m_opaque_sp.get()), @@ -1428,21 +1461,11 @@ SBError SBDebugger::SetCurrentPlatform(const char *platform_name_cstr) { SBError sb_error; if (m_opaque_sp) { if (platform_name_cstr && platform_name_cstr[0]) { - ConstString platform_name(platform_name_cstr); - PlatformSP platform_sp(Platform::Find(platform_name)); - - if (platform_sp) { - // Already have a platform with this name, just select it - m_opaque_sp->GetPlatformList().SetSelectedPlatform(platform_sp); - } else { - // We don't have a platform by this name yet, create one - platform_sp = Platform::Create(platform_name, sb_error.ref()); - if (platform_sp) { - // We created the platform, now append and select it - bool make_selected = true; - m_opaque_sp->GetPlatformList().Append(platform_sp, make_selected); - } - } + PlatformList &platforms = m_opaque_sp->GetPlatformList(); + if (PlatformSP platform_sp = platforms.GetOrCreate(platform_name_cstr)) + platforms.SetSelectedPlatform(platform_sp); + else + sb_error.ref().SetErrorString("platform not found"); } else { sb_error.ref().SetErrorString("invalid platform name"); } @@ -1598,7 +1621,8 @@ bool SBDebugger::EnableLog(const char *channel, const char **categories) { std::string error; llvm::raw_string_ostream error_stream(error); return m_opaque_sp->EnableLog(channel, GetCategoryArray(categories), "", - log_options, error_stream); + log_options, /*buffer_size=*/0, + eLogHandlerStream, error_stream); } else return false; } @@ -1611,3 +1635,10 @@ void SBDebugger::SetLoggingCallback(lldb::LogOutputCallback log_callback, return m_opaque_sp->SetLoggingCallback(log_callback, baton); } } + +SBTrace +SBDebugger::LoadTraceFromFile(SBError &error, + const SBFileSpec &trace_description_file) { + LLDB_INSTRUMENT_VA(this, error, trace_description_file); + return SBTrace::LoadTraceFromFile(error, *this, trace_description_file); +} diff --git a/contrib/llvm-project/lldb/source/API/SBFrame.cpp b/contrib/llvm-project/lldb/source/API/SBFrame.cpp index ffbbed00f8e2..ea9c2bb747e1 100644 --- a/contrib/llvm-project/lldb/source/API/SBFrame.cpp +++ b/contrib/llvm-project/lldb/source/API/SBFrame.cpp @@ -38,6 +38,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Instrumentation.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Stream.h" #include "lldb/API/SBAddress.h" @@ -636,9 +637,9 @@ SBValue SBFrame::FindValue(const char *name, ValueType value_type, for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx) { const RegisterSet *reg_set = reg_ctx->GetRegisterSet(set_idx); if (reg_set && - ((reg_set->name && strcasecmp(reg_set->name, name) == 0) || - (reg_set->short_name && - strcasecmp(reg_set->short_name, name) == 0))) { + (llvm::StringRef(reg_set->name).equals_insensitive(name) || + llvm::StringRef(reg_set->short_name) + .equals_insensitive(name))) { value_sp = ValueObjectRegisterSet::Create(frame, reg_ctx, set_idx); sb_value.SetSP(value_sp); @@ -1033,7 +1034,7 @@ lldb::SBValue SBFrame::EvaluateExpression(const char *expr, const SBExpressionOptions &options) { LLDB_INSTRUMENT_VA(this, expr, options); - Log *expr_log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *expr_log = GetLog(LLDBLog::Expressions); SBValue expr_result; diff --git a/contrib/llvm-project/lldb/source/API/SBHostOS.cpp b/contrib/llvm-project/lldb/source/API/SBHostOS.cpp index 06cf654031a1..cb026fd9203b 100644 --- a/contrib/llvm-project/lldb/source/API/SBHostOS.cpp +++ b/contrib/llvm-project/lldb/source/API/SBHostOS.cpp @@ -102,7 +102,9 @@ lldb::thread_t SBHostOS::ThreadCreate(const char *name, void *thread_arg, SBError *error_ptr) { LLDB_INSTRUMENT_VA(name, thread_function, thread_arg, error_ptr); llvm::Expected<HostThread> thread = - ThreadLauncher::LaunchThread(name, thread_function, thread_arg); + ThreadLauncher::LaunchThread(name, [thread_function, thread_arg] { + return thread_function(thread_arg); + }); if (!thread) { if (error_ptr) error_ptr->SetError(Status(thread.takeError())); diff --git a/contrib/llvm-project/lldb/source/API/SBListener.cpp b/contrib/llvm-project/lldb/source/API/SBListener.cpp index 2ce17a5f521d..a7008dc5224e 100644 --- a/contrib/llvm-project/lldb/source/API/SBListener.cpp +++ b/contrib/llvm-project/lldb/source/API/SBListener.cpp @@ -23,12 +23,11 @@ using namespace lldb_private; SBListener::SBListener() { LLDB_INSTRUMENT_VA(this); } SBListener::SBListener(const char *name) - : m_opaque_sp(Listener::MakeListener(name)), m_unused_ptr(nullptr) { + : m_opaque_sp(Listener::MakeListener(name)) { LLDB_INSTRUMENT_VA(this, name); } -SBListener::SBListener(const SBListener &rhs) - : m_opaque_sp(rhs.m_opaque_sp), m_unused_ptr(nullptr) { +SBListener::SBListener(const SBListener &rhs) : m_opaque_sp(rhs.m_opaque_sp) { LLDB_INSTRUMENT_VA(this, rhs); } @@ -43,7 +42,7 @@ const lldb::SBListener &SBListener::operator=(const lldb::SBListener &rhs) { } SBListener::SBListener(const lldb::ListenerSP &listener_sp) - : m_opaque_sp(listener_sp), m_unused_ptr(nullptr) {} + : m_opaque_sp(listener_sp) {} SBListener::~SBListener() = default; diff --git a/contrib/llvm-project/lldb/source/API/SBMemoryRegionInfo.cpp b/contrib/llvm-project/lldb/source/API/SBMemoryRegionInfo.cpp index 7d9db478dde1..e811bf31c722 100644 --- a/contrib/llvm-project/lldb/source/API/SBMemoryRegionInfo.cpp +++ b/contrib/llvm-project/lldb/source/API/SBMemoryRegionInfo.cpp @@ -126,16 +126,16 @@ const char *SBMemoryRegionInfo::GetName() { bool SBMemoryRegionInfo::HasDirtyMemoryPageList() { LLDB_INSTRUMENT_VA(this); - return m_opaque_up->GetDirtyPageList().hasValue(); + return m_opaque_up->GetDirtyPageList().has_value(); } uint32_t SBMemoryRegionInfo::GetNumDirtyPages() { LLDB_INSTRUMENT_VA(this); uint32_t num_dirty_pages = 0; - llvm::Optional<std::vector<addr_t>> dirty_page_list = + const llvm::Optional<std::vector<addr_t>> &dirty_page_list = m_opaque_up->GetDirtyPageList(); - if (dirty_page_list.hasValue()) + if (dirty_page_list) num_dirty_pages = dirty_page_list.getValue().size(); return num_dirty_pages; @@ -147,7 +147,7 @@ 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()) + if (dirty_page_list && idx < dirty_page_list.getValue().size()) dirty_page_addr = dirty_page_list.getValue()[idx]; return dirty_page_addr; diff --git a/contrib/llvm-project/lldb/source/API/SBMemoryRegionInfoList.cpp b/contrib/llvm-project/lldb/source/API/SBMemoryRegionInfoList.cpp index 39dee86dc300..f8381d1098a0 100644 --- a/contrib/llvm-project/lldb/source/API/SBMemoryRegionInfoList.cpp +++ b/contrib/llvm-project/lldb/source/API/SBMemoryRegionInfoList.cpp @@ -21,8 +21,7 @@ class MemoryRegionInfoListImpl { public: MemoryRegionInfoListImpl() : m_regions() {} - MemoryRegionInfoListImpl(const MemoryRegionInfoListImpl &rhs) - : m_regions(rhs.m_regions) {} + MemoryRegionInfoListImpl(const MemoryRegionInfoListImpl &rhs) = default; MemoryRegionInfoListImpl &operator=(const MemoryRegionInfoListImpl &rhs) { if (this == &rhs) diff --git a/contrib/llvm-project/lldb/source/API/SBModule.cpp b/contrib/llvm-project/lldb/source/API/SBModule.cpp index 1454012d3eb9..c4e876eb15de 100644 --- a/contrib/llvm-project/lldb/source/API/SBModule.cpp +++ b/contrib/llvm-project/lldb/source/API/SBModule.cpp @@ -617,9 +617,9 @@ uint32_t SBModule::GetVersion(uint32_t *versions, uint32_t num_versions) { if (num_versions > 0) versions[0] = version.empty() ? UINT32_MAX : version.getMajor(); if (num_versions > 1) - versions[1] = version.getMinor().getValueOr(UINT32_MAX); + versions[1] = version.getMinor().value_or(UINT32_MAX); if (num_versions > 2) - versions[2] = version.getSubminor().getValueOr(UINT32_MAX); + versions[2] = version.getSubminor().value_or(UINT32_MAX); for (uint32_t i = 3; i < num_versions; ++i) versions[i] = UINT32_MAX; return result; diff --git a/contrib/llvm-project/lldb/source/API/SBPlatform.cpp b/contrib/llvm-project/lldb/source/API/SBPlatform.cpp index d521a38b30e8..ba18ba6d187f 100644 --- a/contrib/llvm-project/lldb/source/API/SBPlatform.cpp +++ b/contrib/llvm-project/lldb/source/API/SBPlatform.cpp @@ -48,8 +48,7 @@ struct PlatformConnectOptions { // PlatformShellCommand struct PlatformShellCommand { PlatformShellCommand(llvm::StringRef shell_interpreter, - llvm::StringRef shell_command) - : m_status(0), m_signo(0) { + llvm::StringRef shell_command) { if (!shell_interpreter.empty()) m_shell = shell_interpreter.str(); @@ -293,9 +292,7 @@ SBPlatform::SBPlatform() { LLDB_INSTRUMENT_VA(this); } SBPlatform::SBPlatform(const char *platform_name) { LLDB_INSTRUMENT_VA(this, platform_name); - Status error; - if (platform_name && platform_name[0]) - m_opaque_sp = Platform::Create(ConstString(platform_name), error); + m_opaque_sp = Platform::Create(platform_name); } SBPlatform::SBPlatform(const SBPlatform &rhs) { @@ -342,7 +339,7 @@ const char *SBPlatform::GetName() { PlatformSP platform_sp(GetSP()); if (platform_sp) - return platform_sp->GetName().GetCString(); + return ConstString(platform_sp->GetName()).AsCString(); return nullptr; } @@ -427,7 +424,7 @@ const char *SBPlatform::GetOSBuild() { PlatformSP platform_sp(GetSP()); if (platform_sp) { - std::string s = platform_sp->GetOSBuildString().getValueOr(""); + std::string s = platform_sp->GetOSBuildString().value_or(""); if (!s.empty()) { // Const-ify the string so we don't need to worry about the lifetime of // the string @@ -442,7 +439,7 @@ const char *SBPlatform::GetOSDescription() { PlatformSP platform_sp(GetSP()); if (platform_sp) { - std::string s = platform_sp->GetOSKernelDescription().getValueOr(""); + std::string s = platform_sp->GetOSKernelDescription().value_or(""); if (!s.empty()) { // Const-ify the string so we don't need to worry about the lifetime of // the string @@ -476,7 +473,7 @@ uint32_t SBPlatform::GetOSMinorVersion() { llvm::VersionTuple version; if (PlatformSP platform_sp = GetSP()) version = platform_sp->GetOSVersion(); - return version.getMinor().getValueOr(UINT32_MAX); + return version.getMinor().value_or(UINT32_MAX); } uint32_t SBPlatform::GetOSUpdateVersion() { @@ -485,7 +482,7 @@ uint32_t SBPlatform::GetOSUpdateVersion() { llvm::VersionTuple version; if (PlatformSP platform_sp = GetSP()) version = platform_sp->GetOSVersion(); - return version.getSubminor().getValueOr(UINT32_MAX); + return version.getSubminor().value_or(UINT32_MAX); } void SBPlatform::SetSDKRoot(const char *sysroot) { diff --git a/contrib/llvm-project/lldb/source/API/SBProcess.cpp b/contrib/llvm-project/lldb/source/API/SBProcess.cpp index 2538013412b6..27593559bb3d 100644 --- a/contrib/llvm-project/lldb/source/API/SBProcess.cpp +++ b/contrib/llvm-project/lldb/source/API/SBProcess.cpp @@ -1138,6 +1138,13 @@ bool SBProcess::IsInstrumentationRuntimePresent( lldb::SBError SBProcess::SaveCore(const char *file_name) { LLDB_INSTRUMENT_VA(this, file_name); + return SaveCore(file_name, "", SaveCoreStyle::eSaveCoreFull); +} + +lldb::SBError SBProcess::SaveCore(const char *file_name, + const char *flavor, + SaveCoreStyle core_style) { + LLDB_INSTRUMENT_VA(this, file_name, flavor, core_style); lldb::SBError error; ProcessSP process_sp(GetSP()); @@ -1155,8 +1162,9 @@ lldb::SBError SBProcess::SaveCore(const char *file_name) { } FileSpec core_file(file_name); - SaveCoreStyle core_style = SaveCoreStyle::eSaveCoreFull; - error.ref() = PluginManager::SaveCore(process_sp, core_file, core_style, ""); + error.ref() = PluginManager::SaveCore(process_sp, core_file, core_style, + flavor); + return error; } diff --git a/contrib/llvm-project/lldb/source/API/SBQueue.cpp b/contrib/llvm-project/lldb/source/API/SBQueue.cpp index b2c143f6357e..b97da3ef02ed 100644 --- a/contrib/llvm-project/lldb/source/API/SBQueue.cpp +++ b/contrib/llvm-project/lldb/source/API/SBQueue.cpp @@ -27,12 +27,9 @@ namespace lldb_private { class QueueImpl { public: - QueueImpl() {} + QueueImpl() = default; - QueueImpl(const lldb::QueueSP &queue_sp) - : m_thread_list_fetched(false), m_pending_items_fetched(false) { - m_queue_wp = queue_sp; - } + QueueImpl(const lldb::QueueSP &queue_sp) { m_queue_wp = queue_sp; } QueueImpl(const QueueImpl &rhs) { if (&rhs == this) diff --git a/contrib/llvm-project/lldb/source/API/SBReproducer.cpp b/contrib/llvm-project/lldb/source/API/SBReproducer.cpp index d3d27cc57748..7431b49d3ea6 100644 --- a/contrib/llvm-project/lldb/source/API/SBReproducer.cpp +++ b/contrib/llvm-project/lldb/source/API/SBReproducer.cpp @@ -110,20 +110,7 @@ const char *SBReproducer::Replay(const char *path, const char *SBReproducer::Finalize(const char *path) { LLDB_INSTRUMENT_VA(path) - static std::string error; - - repro::Loader *loader = repro::Reproducer::Instance().GetLoader(); - if (!loader) { - error = "unable to get replay loader."; - return error.c_str(); - } - - if (auto e = repro::Finalize(loader)) { - error = llvm::toString(std::move(e)); - return error.c_str(); - } - - return nullptr; + return "Reproducer finalize has been removed"; } bool SBReproducer::Generate() { diff --git a/contrib/llvm-project/lldb/source/API/SBStream.cpp b/contrib/llvm-project/lldb/source/API/SBStream.cpp index 9ceef3466f93..870cbb9e14d5 100644 --- a/contrib/llvm-project/lldb/source/API/SBStream.cpp +++ b/contrib/llvm-project/lldb/source/API/SBStream.cpp @@ -12,6 +12,7 @@ #include "lldb/Core/StreamFile.h" #include "lldb/Host/FileSystem.h" #include "lldb/Utility/Instrumentation.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" @@ -98,7 +99,7 @@ void SBStream::RedirectToFile(const char *path, bool append) { llvm::Expected<FileUP> file = FileSystem::Instance().Open(FileSpec(path), open_options); if (!file) { - LLDB_LOG_ERROR(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API), file.takeError(), + LLDB_LOG_ERROR(GetLog(LLDBLog::API), file.takeError(), "Cannot open {1}: {0}", path); return; } diff --git a/contrib/llvm-project/lldb/source/API/SBTarget.cpp b/contrib/llvm-project/lldb/source/API/SBTarget.cpp index 75534b2343d4..bf64bb342aaf 100644 --- a/contrib/llvm-project/lldb/source/API/SBTarget.cpp +++ b/contrib/llvm-project/lldb/source/API/SBTarget.cpp @@ -8,7 +8,7 @@ #include "lldb/API/SBTarget.h" #include "lldb/Utility/Instrumentation.h" - +#include "lldb/Utility/LLDBLog.h" #include "lldb/lldb-public.h" #include "lldb/API/SBBreakpoint.h" @@ -1116,8 +1116,7 @@ bool SBTarget::FindBreakpointsByName(const char *name, llvm::Expected<std::vector<BreakpointSP>> expected_vector = target_sp->GetBreakpointList().FindBreakpointsByName(name); if (!expected_vector) { - LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS), - "invalid breakpoint name: {}", + LLDB_LOG(GetLog(LLDBLog::Breakpoints), "invalid breakpoint name: {}", llvm::toString(expected_vector.takeError())); return false; } @@ -1589,6 +1588,18 @@ const char *SBTarget::GetTriple() { return nullptr; } +const char *SBTarget::GetABIName() { + LLDB_INSTRUMENT_VA(this); + + TargetSP target_sp(GetSP()); + if (target_sp) { + std::string abi_name(target_sp->GetABIName().str()); + ConstString const_name(abi_name.c_str()); + return const_name.GetCString(); + } + return nullptr; +} + uint32_t SBTarget::GetDataByteSize() { LLDB_INSTRUMENT_VA(this); @@ -2195,7 +2206,7 @@ lldb::SBValue SBTarget::EvaluateExpression(const char *expr, const SBExpressionOptions &options) { LLDB_INSTRUMENT_VA(this, expr, options); - Log *expr_log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *expr_log = GetLog(LLDBLog::Expressions); SBValue expr_result; ValueObjectSP expr_value_sp; TargetSP target_sp(GetSP()); diff --git a/contrib/llvm-project/lldb/source/API/SBTrace.cpp b/contrib/llvm-project/lldb/source/API/SBTrace.cpp index 64a675e2e16c..fe9003237073 100644 --- a/contrib/llvm-project/lldb/source/API/SBTrace.cpp +++ b/contrib/llvm-project/lldb/source/API/SBTrace.cpp @@ -9,6 +9,7 @@ #include "lldb/Target/Process.h" #include "lldb/Utility/Instrumentation.h" +#include "lldb/API/SBDebugger.h" #include "lldb/API/SBStructuredData.h" #include "lldb/API/SBThread.h" #include "lldb/API/SBTrace.h" @@ -19,6 +20,7 @@ using namespace lldb; using namespace lldb_private; +using namespace llvm; SBTrace::SBTrace() { LLDB_INSTRUMENT_VA(this); } @@ -26,6 +28,21 @@ SBTrace::SBTrace(const lldb::TraceSP &trace_sp) : m_opaque_sp(trace_sp) { LLDB_INSTRUMENT_VA(this, trace_sp); } +SBTrace SBTrace::LoadTraceFromFile(SBError &error, SBDebugger &debugger, + const SBFileSpec &trace_description_file) { + LLDB_INSTRUMENT_VA(error, debugger, trace_description_file); + + Expected<lldb::TraceSP> trace_or_err = Trace::LoadPostMortemTraceFromFile( + debugger.ref(), trace_description_file.ref()); + + if (!trace_or_err) { + error.SetErrorString(toString(trace_or_err.takeError()).c_str()); + return SBTrace(); + } + + return SBTrace(trace_or_err.get()); +} + const char *SBTrace::GetStartConfigurationHelp() { LLDB_INSTRUMENT_VA(this); return m_opaque_sp ? m_opaque_sp->GetStartConfigurationHelp() : nullptr; diff --git a/contrib/llvm-project/lldb/source/API/SBType.cpp b/contrib/llvm-project/lldb/source/API/SBType.cpp index da9202bf9386..533930c0544b 100644 --- a/contrib/llvm-project/lldb/source/API/SBType.cpp +++ b/contrib/llvm-project/lldb/source/API/SBType.cpp @@ -273,6 +273,14 @@ bool SBType::IsScopedEnumerationType() { return m_opaque_sp->GetCompilerType(true).IsScopedEnumerationType(); } +bool SBType::IsAggregateType() { + LLDB_INSTRUMENT_VA(this); + + if (!IsValid()) + return false; + return m_opaque_sp->GetCompilerType(true).IsAggregateType(); +} + lldb::SBType SBType::GetFunctionReturnType() { LLDB_INSTRUMENT_VA(this); diff --git a/contrib/llvm-project/lldb/source/API/SBValue.cpp b/contrib/llvm-project/lldb/source/API/SBValue.cpp index 20581cfabdd6..f9e03172a4d0 100644 --- a/contrib/llvm-project/lldb/source/API/SBValue.cpp +++ b/contrib/llvm-project/lldb/source/API/SBValue.cpp @@ -69,9 +69,7 @@ public: } } - ValueImpl(const ValueImpl &rhs) - : m_valobj_sp(rhs.m_valobj_sp), m_use_dynamic(rhs.m_use_dynamic), - m_use_synthetic(rhs.m_use_synthetic), m_name(rhs.m_name) {} + ValueImpl(const ValueImpl &rhs) = default; ValueImpl &operator=(const ValueImpl &rhs) { if (this != &rhs) { @@ -332,7 +330,7 @@ size_t SBValue::GetByteSize() { ValueLocker locker; lldb::ValueObjectSP value_sp(GetSP(locker)); if (value_sp) { - result = value_sp->GetByteSize().getValueOr(0); + result = value_sp->GetByteSize().value_or(0); } return result; diff --git a/contrib/llvm-project/lldb/source/API/SBValueList.cpp b/contrib/llvm-project/lldb/source/API/SBValueList.cpp index a67030c506f4..4b36b04c8d35 100644 --- a/contrib/llvm-project/lldb/source/API/SBValueList.cpp +++ b/contrib/llvm-project/lldb/source/API/SBValueList.cpp @@ -19,9 +19,9 @@ using namespace lldb_private; class ValueListImpl { public: - ValueListImpl() {} + ValueListImpl() = default; - ValueListImpl(const ValueListImpl &rhs) : m_values(rhs.m_values) {} + ValueListImpl(const ValueListImpl &rhs) = default; ValueListImpl &operator=(const ValueListImpl &rhs) { if (this == &rhs) diff --git a/contrib/llvm-project/lldb/source/Breakpoint/Breakpoint.cpp b/contrib/llvm-project/lldb/source/Breakpoint/Breakpoint.cpp index eeb8eac33567..578cf14283d9 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/Breakpoint.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/Breakpoint.cpp @@ -19,13 +19,14 @@ #include "lldb/Core/ModuleList.h" #include "lldb/Core/SearchFilter.h" #include "lldb/Core/Section.h" -#include "lldb/Target/SectionLoadList.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Symbol/SymbolContext.h" +#include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" #include "lldb/Target/ThreadSpec.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" @@ -487,7 +488,7 @@ void Breakpoint::ClearAllBreakpointSites() { void Breakpoint::ModulesChanged(ModuleList &module_list, bool load, bool delete_locations) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); LLDB_LOGF(log, "Breakpoint::ModulesChanged: num_modules: %zu load: %i " "delete_locations: %i\n", @@ -646,7 +647,7 @@ static bool SymbolContextsMightBeEquivalent(SymbolContext &old_sc, void Breakpoint::ModuleReplaced(ModuleSP old_module_sp, ModuleSP new_module_sp) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); LLDB_LOGF(log, "Breakpoint::ModulesReplaced for %s\n", old_module_sp->GetSpecificationDescription().c_str()); // First find all the locations that are in the old module @@ -1009,10 +1010,32 @@ void Breakpoint::SendBreakpointChangedEvent(BreakpointEventData *data) { delete data; } +const char *Breakpoint::BreakpointEventTypeAsCString(BreakpointEventType type) { + switch (type) { + case eBreakpointEventTypeInvalidType: return "invalid"; + case eBreakpointEventTypeAdded: return "breakpoint added"; + case eBreakpointEventTypeRemoved: return "breakpoint removed"; + case eBreakpointEventTypeLocationsAdded: return "locations added"; + case eBreakpointEventTypeLocationsRemoved: return "locations removed"; + case eBreakpointEventTypeLocationsResolved: return "locations resolved"; + case eBreakpointEventTypeEnabled: return "breakpoint enabled"; + case eBreakpointEventTypeDisabled: return "breakpoint disabled"; + case eBreakpointEventTypeCommandChanged: return "command changed"; + case eBreakpointEventTypeConditionChanged: return "condition changed"; + case eBreakpointEventTypeIgnoreChanged: return "ignore count changed"; + case eBreakpointEventTypeThreadChanged: return "thread changed"; + case eBreakpointEventTypeAutoContinueChanged: return "autocontinue changed"; + }; + llvm_unreachable("Fully covered switch above!"); +} + +Log *Breakpoint::BreakpointEventData::GetLogChannel() { + return GetLog(LLDBLog::Breakpoints); +} + Breakpoint::BreakpointEventData::BreakpointEventData( BreakpointEventType sub_type, const BreakpointSP &new_breakpoint_sp) - : EventData(), m_breakpoint_event(sub_type), - m_new_breakpoint_sp(new_breakpoint_sp) {} + : m_breakpoint_event(sub_type), m_new_breakpoint_sp(new_breakpoint_sp) {} Breakpoint::BreakpointEventData::~BreakpointEventData() = default; @@ -1025,7 +1048,7 @@ ConstString Breakpoint::BreakpointEventData::GetFlavor() const { return BreakpointEventData::GetFlavorString(); } -BreakpointSP &Breakpoint::BreakpointEventData::GetBreakpoint() { +BreakpointSP Breakpoint::BreakpointEventData::GetBreakpoint() const { return m_new_breakpoint_sp; } @@ -1034,7 +1057,14 @@ Breakpoint::BreakpointEventData::GetBreakpointEventType() const { return m_breakpoint_event; } -void Breakpoint::BreakpointEventData::Dump(Stream *s) const {} +void Breakpoint::BreakpointEventData::Dump(Stream *s) const { + if (!s) + return; + BreakpointEventType event_type = GetBreakpointEventType(); + break_id_t bkpt_id = GetBreakpoint()->GetID(); + s->Format("bkpt: {0} type: {1}", bkpt_id, + BreakpointEventTypeAsCString(event_type)); +} const Breakpoint::BreakpointEventData * Breakpoint::BreakpointEventData::GetEventDataFromEvent(const Event *event) { diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointID.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointID.cpp index 9bd22898196e..245cf7913335 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointID.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointID.cpp @@ -33,7 +33,7 @@ bool BreakpointID::IsRangeIdentifier(llvm::StringRef str) { } bool BreakpointID::IsValidIDExpression(llvm::StringRef str) { - return BreakpointID::ParseCanonicalReference(str).hasValue(); + return BreakpointID::ParseCanonicalReference(str).has_value(); } llvm::ArrayRef<llvm::StringRef> BreakpointID::GetRangeSpecifiers() { diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointIDList.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointIDList.cpp index 172674dc2dd2..dd16d3b6388c 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointIDList.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointIDList.cpp @@ -52,7 +52,7 @@ bool BreakpointIDList::AddBreakpointID(BreakpointID bp_id) { bool BreakpointIDList::AddBreakpointID(const char *bp_id_str) { auto bp_id = BreakpointID::ParseCanonicalReference(bp_id_str); - if (!bp_id.hasValue()) + if (!bp_id) return false; m_breakpoint_ids.push_back(*bp_id); @@ -76,7 +76,7 @@ bool BreakpointIDList::FindBreakpointID(BreakpointID &bp_id, bool BreakpointIDList::FindBreakpointID(const char *bp_id_str, size_t *position) const { auto bp_id = BreakpointID::ParseCanonicalReference(bp_id_str); - if (!bp_id.hasValue()) + if (!bp_id) return false; return FindBreakpointID(*bp_id, position); @@ -89,7 +89,7 @@ void BreakpointIDList::InsertStringArray( for (const char *str : string_array) { auto bp_id = BreakpointID::ParseCanonicalReference(str); - if (bp_id.hasValue()) + if (bp_id) m_breakpoint_ids.push_back(*bp_id); } result.SetStatus(eReturnStatusSuccessFinishNoResult); @@ -163,7 +163,7 @@ void BreakpointIDList::FindAndReplaceIDRanges(Args &old_args, Target *target, BreakpointSP breakpoint_sp; auto bp_id = BreakpointID::ParseCanonicalReference(bp_id_str); - if (bp_id.hasValue()) + if (bp_id) breakpoint_sp = target->GetBreakpointByID(bp_id->GetBreakpointID()); if (!breakpoint_sp) { new_args.Clear(); @@ -192,7 +192,7 @@ void BreakpointIDList::FindAndReplaceIDRanges(Args &old_args, Target *target, auto start_bp = BreakpointID::ParseCanonicalReference(range_from); auto end_bp = BreakpointID::ParseCanonicalReference(range_to); - if (!start_bp.hasValue() || + if (!start_bp || !target->GetBreakpointByID(start_bp->GetBreakpointID())) { new_args.Clear(); result.AppendErrorWithFormat("'%s' is not a valid breakpoint ID.\n", @@ -200,7 +200,7 @@ void BreakpointIDList::FindAndReplaceIDRanges(Args &old_args, Target *target, return; } - if (!end_bp.hasValue() || + if (!end_bp || !target->GetBreakpointByID(end_bp->GetBreakpointID())) { new_args.Clear(); result.AppendErrorWithFormat("'%s' is not a valid breakpoint ID.\n", diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointList.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointList.cpp index ca181ee306a4..f4d4b2edbf08 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointList.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointList.cpp @@ -23,8 +23,7 @@ static void NotifyChange(const BreakpointSP &bp, BreakpointEventType event) { } BreakpointList::BreakpointList(bool is_internal) - : m_mutex(), m_breakpoints(), m_next_break_id(0), - m_is_internal(is_internal) {} + : m_next_break_id(0), m_is_internal(is_internal) {} BreakpointList::~BreakpointList() = default; diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointLocation.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointLocation.cpp index 0c4d3e052c53..0ee8bcf491ea 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointLocation.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointLocation.cpp @@ -22,6 +22,7 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadSpec.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" @@ -33,8 +34,7 @@ BreakpointLocation::BreakpointLocation(break_id_t loc_id, Breakpoint &owner, bool hardware, bool check_for_resolver) : m_being_created(true), m_should_resolve_indirect_functions(false), m_is_reexported(false), m_is_indirect(false), m_address(addr), - m_owner(owner), m_options_up(), m_bp_site_sp(), m_condition_mutex(), - m_condition_hash(0), m_loc_id(loc_id), m_hit_counter() { + m_owner(owner), m_condition_hash(0), m_loc_id(loc_id), m_hit_counter() { if (check_for_resolver) { Symbol *symbol = m_address.CalculateSymbolContextSymbol(); if (symbol && symbol->IsIndirect()) { @@ -233,7 +233,7 @@ const char *BreakpointLocation::GetConditionText(size_t *hash) const { bool BreakpointLocation::ConditionSaysStop(ExecutionContext &exe_ctx, Status &error) { - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS); + Log *log = GetLog(LLDBLog::Breakpoints); std::lock_guard<std::mutex> guard(m_condition_mutex); @@ -393,7 +393,7 @@ bool BreakpointLocation::ValidForThisThread(Thread &thread) { bool BreakpointLocation::ShouldStop(StoppointCallbackContext *context) { bool should_stop = true; - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS); + Log *log = GetLog(LLDBLog::Breakpoints); // Do this first, if a location is disabled, it shouldn't increment its hit // count. @@ -450,7 +450,7 @@ bool BreakpointLocation::ResolveBreakpointSite() { process->CreateBreakpointSite(shared_from_this(), m_owner.IsHardware()); if (new_id == LLDB_INVALID_BREAK_ID) { - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS); + Log *log = GetLog(LLDBLog::Breakpoints); if (log) log->Warning("Failed to add breakpoint site at 0x%" PRIx64, m_address.GetOpcodeLoadAddress(&m_owner.GetTarget())); diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointLocationCollection.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointLocationCollection.cpp index 6c55629b5aad..d649e889c3f7 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointLocationCollection.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointLocationCollection.cpp @@ -17,8 +17,7 @@ using namespace lldb; using namespace lldb_private; // BreakpointLocationCollection constructor -BreakpointLocationCollection::BreakpointLocationCollection() - : m_break_loc_collection(), m_collection_mutex() {} +BreakpointLocationCollection::BreakpointLocationCollection() = default; // Destructor BreakpointLocationCollection::~BreakpointLocationCollection() = default; @@ -123,8 +122,11 @@ bool BreakpointLocationCollection::ShouldStop( size_t i = 0; size_t prev_size = GetSize(); while (i < prev_size) { - // ShouldStop can remove the breakpoint from the list - if (GetByIndex(i)->ShouldStop(context)) + // ShouldStop can remove the breakpoint from the list, or even delete + // it, so we should + BreakpointLocationSP cur_loc_sp = GetByIndex(i); + BreakpointSP keep_bkpt_alive_sp = cur_loc_sp->GetBreakpoint().shared_from_this(); + if (cur_loc_sp->ShouldStop(context)) shouldStop = true; if (prev_size == GetSize()) diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointLocationList.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointLocationList.cpp index 6d271864c445..46f66276d28d 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointLocationList.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointLocationList.cpp @@ -20,8 +20,7 @@ using namespace lldb; using namespace lldb_private; BreakpointLocationList::BreakpointLocationList(Breakpoint &owner) - : m_owner(owner), m_locations(), m_address_to_location(), m_mutex(), - m_next_id(0), m_new_location_recorder(nullptr) {} + : m_owner(owner), m_next_id(0), m_new_location_recorder(nullptr) {} BreakpointLocationList::~BreakpointLocationList() = default; diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointOptions.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointOptions.cpp index 86a7c483df83..6fc6948aaccc 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointOptions.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointOptions.cpp @@ -60,14 +60,10 @@ std::unique_ptr<BreakpointOptions::CommandData> BreakpointOptions::CommandData::CreateFromStructuredData( const StructuredData::Dictionary &options_dict, Status &error) { std::unique_ptr<CommandData> data_up(new CommandData()); - bool found_something = false; bool success = options_dict.GetValueForKeyAsBoolean( GetKey(OptionNames::StopOnError), data_up->stop_on_error); - if (success) - found_something = true; - llvm::StringRef interpreter_str; ScriptLanguage interp_language; success = options_dict.GetValueForKeyAsString( @@ -78,7 +74,6 @@ BreakpointOptions::CommandData::CreateFromStructuredData( return data_up; } - found_something = true; interp_language = ScriptInterpreter::StringToLanguage(interpreter_str); if (interp_language == eScriptLanguageUnknown) { error.SetErrorStringWithFormatv("Unknown breakpoint command language: {0}.", @@ -91,7 +86,6 @@ BreakpointOptions::CommandData::CreateFromStructuredData( success = options_dict.GetValueForKeyAsArray(GetKey(OptionNames::UserSource), user_source); if (success) { - found_something = true; size_t num_elems = user_source->GetSize(); for (size_t i = 0; i < num_elems; i++) { llvm::StringRef elem_string; @@ -101,10 +95,7 @@ BreakpointOptions::CommandData::CreateFromStructuredData( } } - if (found_something) - return data_up; - else - return std::unique_ptr<BreakpointOptions::CommandData>(); + return data_up; } const char *BreakpointOptions::g_option_names[( @@ -121,11 +112,10 @@ bool BreakpointOptions::NullCallback(void *baton, // BreakpointOptions constructor BreakpointOptions::BreakpointOptions(bool all_flags_set) - : m_callback(BreakpointOptions::NullCallback), m_callback_baton_sp(), + : m_callback(BreakpointOptions::NullCallback), m_baton_is_command_baton(false), m_callback_is_synchronous(false), - m_enabled(true), m_one_shot(false), m_ignore_count(0), m_thread_spec_up(), - m_condition_text(), m_condition_text_hash(0), m_auto_continue(false), - m_set_flags(0) { + m_enabled(true), m_one_shot(false), m_ignore_count(0), + m_condition_text_hash(0), m_auto_continue(false), m_set_flags(0) { if (all_flags_set) m_set_flags.Set(~((Flags::ValueType)0)); } @@ -151,8 +141,8 @@ BreakpointOptions::BreakpointOptions(const BreakpointOptions &rhs) m_baton_is_command_baton(rhs.m_baton_is_command_baton), m_callback_is_synchronous(rhs.m_callback_is_synchronous), m_enabled(rhs.m_enabled), m_one_shot(rhs.m_one_shot), - m_ignore_count(rhs.m_ignore_count), m_thread_spec_up(), - m_auto_continue(rhs.m_auto_continue), m_set_flags(rhs.m_set_flags) { + m_ignore_count(rhs.m_ignore_count), m_auto_continue(rhs.m_auto_continue), + m_set_flags(rhs.m_set_flags) { if (rhs.m_thread_spec_up != nullptr) m_thread_spec_up = std::make_unique<ThreadSpec>(*rhs.m_thread_spec_up); m_condition_text = rhs.m_condition_text; diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolver.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolver.cpp index d3d57a282d09..71cbb2b2c666 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolver.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolver.cpp @@ -24,6 +24,7 @@ #include "lldb/Symbol/Function.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" @@ -108,8 +109,7 @@ BreakpointResolverSP BreakpointResolver::CreateFromStructuredData( return result_sp; } - BreakpointResolver *resolver; - + BreakpointResolver *resolver = nullptr; switch (resolver_type) { case FileLineResolver: resolver = BreakpointResolverFileLine::CreateFromStructuredData( @@ -138,13 +138,12 @@ BreakpointResolverSP BreakpointResolver::CreateFromStructuredData( llvm_unreachable("Should never get an unresolvable resolver type."); } - if (!error.Success()) { + if (!resolver || error.Fail()) return result_sp; - } else { - // Add on the global offset option: - resolver->SetOffset(offset); - return BreakpointResolverSP(resolver); - } + + // Add on the global offset option: + resolver->SetOffset(offset); + return BreakpointResolverSP(resolver); } StructuredData::DictionarySP BreakpointResolver::WrapOptionsDict( @@ -292,7 +291,7 @@ void BreakpointResolver::AddLocation(SearchFilter &filter, const SymbolContext &sc, bool skip_prologue, llvm::StringRef log_ident) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); Address line_start = sc.line_entry.range.GetBaseAddress(); if (!line_start.IsValid()) { LLDB_LOGF(log, diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverAddress.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverAddress.cpp index 3187e8464f6f..c173fc0c2a7a 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverAddress.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverAddress.cpp @@ -7,14 +7,12 @@ //===----------------------------------------------------------------------===// #include "lldb/Breakpoint/BreakpointResolverAddress.h" - - #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Module.h" #include "lldb/Core/Section.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" -#include "lldb/Utility/Log.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/StreamString.h" using namespace lldb; @@ -30,8 +28,7 @@ BreakpointResolverAddress::BreakpointResolverAddress( BreakpointResolverAddress::BreakpointResolverAddress(const BreakpointSP &bkpt, const Address &addr) : BreakpointResolver(bkpt, BreakpointResolver::AddressResolver), - m_addr(addr), m_resolved_addr(LLDB_INVALID_ADDRESS), m_module_filespec() { -} + m_addr(addr), m_resolved_addr(LLDB_INVALID_ADDRESS) {} BreakpointResolver *BreakpointResolverAddress::CreateFromStructuredData( const BreakpointSP &bkpt, const StructuredData::Dictionary &options_dict, @@ -143,8 +140,7 @@ Searcher::CallbackReturn BreakpointResolverAddress::SearchCallback( if (bp_loc_sp && !breakpoint.IsInternal()) { StreamString s; bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose); - Log *log( - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); LLDB_LOGF(log, "Added location: %s\n", s.GetData()); } } else { diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp index be4616064f9e..ff044526799c 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp @@ -12,6 +12,7 @@ #include "lldb/Core/Module.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Function.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" @@ -99,10 +100,10 @@ BreakpointResolverFileLine::SerializeToStructuredData() { 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)); + m_location_spec.GetLine().value_or(0)); options_dict_sp->AddIntegerItem( GetKey(OptionNames::Column), - m_location_spec.GetColumn().getValueOr(LLDB_INVALID_COLUMN_NUMBER)); + m_location_spec.GetColumn().value_or(LLDB_INVALID_COLUMN_NUMBER)); options_dict_sp->AddBooleanItem(GetKey(OptionNames::Inlines), m_location_spec.GetCheckInlines()); options_dict_sp->AddBooleanItem(GetKey(OptionNames::ExactMatch), @@ -127,7 +128,7 @@ void BreakpointResolverFileLine::FilterContexts(SymbolContextList &sc_list, if (is_relative) relative_path = m_location_spec.GetFileSpec().GetDirectory().GetStringRef(); - Log * log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS); + Log *log = GetLog(LLDBLog::Breakpoints); for(uint32_t i = 0; i < sc_list.GetSize(); ++i) { SymbolContext sc; sc_list.GetContextAtIndex(i, sc); @@ -226,7 +227,7 @@ 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. - const uint32_t line = m_location_spec.GetLine().getValueOr(0); + const uint32_t line = m_location_spec.GetLine().value_or(0); const llvm::Optional<uint16_t> column = m_location_spec.GetColumn(); // We'll create a new SourceLocationSpec that can take into account the @@ -237,7 +238,7 @@ Searcher::CallbackReturn BreakpointResolverFileLine::SearchCallback( if (is_relative) search_file_spec.GetDirectory().Clear(); SourceLocationSpec search_location_spec( - search_file_spec, m_location_spec.GetLine().getValueOr(0), + search_file_spec, m_location_spec.GetLine().value_or(0), m_location_spec.GetColumn(), m_location_spec.GetCheckInlines(), m_location_spec.GetExactMatch()); @@ -271,7 +272,7 @@ lldb::SearchDepth BreakpointResolverFileLine::GetDepth() { void BreakpointResolverFileLine::GetDescription(Stream *s) { s->Printf("file = '%s', line = %u, ", m_location_spec.GetFileSpec().GetPath().c_str(), - m_location_spec.GetLine().getValueOr(0)); + m_location_spec.GetLine().value_or(0)); auto column = m_location_spec.GetColumn(); if (column) s->Printf("column = %u, ", *column); diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverName.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverName.cpp index 49087b39944d..24e36f35bef0 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverName.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverName.cpp @@ -15,8 +15,9 @@ #include "lldb/Symbol/Function.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Symbol/SymbolContext.h" -#include "lldb/Target/Target.h" #include "lldb/Target/Language.h" +#include "lldb/Target/Target.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" @@ -28,12 +29,11 @@ BreakpointResolverName::BreakpointResolverName(const BreakpointSP &bkpt, LanguageType language, Breakpoint::MatchType type, lldb::addr_t offset, bool skip_prologue) : BreakpointResolver(bkpt, BreakpointResolver::NameResolver, offset), - m_class_name(), m_regex(), m_match_type(type), m_language(language), - m_skip_prologue(skip_prologue) { + m_match_type(type), m_language(language), m_skip_prologue(skip_prologue) { if (m_match_type == Breakpoint::Regexp) { m_regex = RegularExpression(name_cstr); if (!m_regex.IsValid()) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); if (log) log->Warning("function name regexp: \"%s\" did not compile.", @@ -252,7 +252,7 @@ void BreakpointResolverName::AddNameLookup(ConstString name, Searcher::CallbackReturn BreakpointResolverName::SearchCallback(SearchFilter &filter, SymbolContext &context, Address *addr) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); if (m_class_name) { if (log) diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointSite.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointSite.cpp index f0469326657c..11ebc59c7e12 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointSite.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointSite.cpp @@ -25,9 +25,9 @@ BreakpointSite::BreakpointSite(BreakpointSiteList *list, m_type(eSoftware), // Process subclasses need to set this correctly using // SetType() m_saved_opcode(), m_trap_opcode(), - m_enabled(false), // Need to create it disabled, so the first enable turns - // it on. - m_owners(), m_owners_mutex() { + m_enabled(false) // Need to create it disabled, so the first enable turns + // it on. +{ m_owners.Add(owner); } diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointSiteList.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointSiteList.cpp index c6966145e42b..32a2f24d411a 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointSiteList.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointSiteList.cpp @@ -14,7 +14,7 @@ using namespace lldb; using namespace lldb_private; -BreakpointSiteList::BreakpointSiteList() : m_mutex(), m_bp_site_list() {} +BreakpointSiteList::BreakpointSiteList() = default; BreakpointSiteList::~BreakpointSiteList() = default; diff --git a/contrib/llvm-project/lldb/source/Breakpoint/StoppointCallbackContext.cpp b/contrib/llvm-project/lldb/source/Breakpoint/StoppointCallbackContext.cpp index a561c99b1d92..926c0afe8fc1 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/StoppointCallbackContext.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/StoppointCallbackContext.cpp @@ -10,7 +10,7 @@ using namespace lldb_private; -StoppointCallbackContext::StoppointCallbackContext() : exe_ctx_ref() {} +StoppointCallbackContext::StoppointCallbackContext() = default; StoppointCallbackContext::StoppointCallbackContext( Event *e, const ExecutionContext &exe_ctx, bool synchronously) diff --git a/contrib/llvm-project/lldb/source/Breakpoint/Watchpoint.cpp b/contrib/llvm-project/lldb/source/Breakpoint/Watchpoint.cpp index 29ae1ef3df26..933661ad7b15 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/Watchpoint.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/Watchpoint.cpp @@ -17,6 +17,7 @@ #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/ThreadSpec.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Stream.h" @@ -29,8 +30,7 @@ Watchpoint::Watchpoint(Target &target, lldb::addr_t addr, uint32_t size, m_enabled(false), m_is_hardware(hardware), m_is_watch_variable(false), m_is_ephemeral(false), m_disabled_count(0), m_watch_read(0), m_watch_write(0), m_watch_was_read(0), m_watch_was_written(0), - m_ignore_count(0), m_false_alarms(0), m_decl_str(), m_watch_spec_str(), - m_type(), m_error(), m_options(), m_being_created(true) { + m_ignore_count(0), m_false_alarms(0), m_being_created(true) { if (type && type->IsValid()) m_type = *type; @@ -40,9 +40,8 @@ Watchpoint::Watchpoint(Target &target, lldb::addr_t addr, uint32_t size, auto type_system_or_err = target.GetScratchTypeSystemForLanguage(eLanguageTypeC); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR( - lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS), - std::move(err), "Failed to set type."); + LLDB_LOG_ERROR(GetLog(LLDBLog::Watchpoints), std::move(err), + "Failed to set type."); } else { m_type = type_system_or_err->GetBuiltinTypeForEncodingAndBitSize( eEncodingUint, 8 * size); @@ -330,8 +329,7 @@ void Watchpoint::SendWatchpointChangedEvent(WatchpointEventData *data) { Watchpoint::WatchpointEventData::WatchpointEventData( WatchpointEventType sub_type, const WatchpointSP &new_watchpoint_sp) - : EventData(), m_watchpoint_event(sub_type), - m_new_watchpoint_sp(new_watchpoint_sp) {} + : m_watchpoint_event(sub_type), m_new_watchpoint_sp(new_watchpoint_sp) {} Watchpoint::WatchpointEventData::~WatchpointEventData() = default; diff --git a/contrib/llvm-project/lldb/source/Breakpoint/WatchpointList.cpp b/contrib/llvm-project/lldb/source/Breakpoint/WatchpointList.cpp index 100c1e51ac5a..fc0cc9126d60 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/WatchpointList.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/WatchpointList.cpp @@ -12,7 +12,7 @@ using namespace lldb; using namespace lldb_private; -WatchpointList::WatchpointList() : m_watchpoints(), m_mutex() {} +WatchpointList::WatchpointList() = default; WatchpointList::~WatchpointList() = default; diff --git a/contrib/llvm-project/lldb/source/Breakpoint/WatchpointOptions.cpp b/contrib/llvm-project/lldb/source/Breakpoint/WatchpointOptions.cpp index a578e8744efb..c27cd62e0220 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/WatchpointOptions.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/WatchpointOptions.cpp @@ -27,14 +27,12 @@ bool WatchpointOptions::NullCallback(void *baton, // WatchpointOptions constructor WatchpointOptions::WatchpointOptions() - : m_callback(WatchpointOptions::NullCallback), m_callback_baton_sp(), - m_thread_spec_up() {} + : m_callback(WatchpointOptions::NullCallback) {} // WatchpointOptions copy constructor WatchpointOptions::WatchpointOptions(const WatchpointOptions &rhs) : m_callback(rhs.m_callback), m_callback_baton_sp(rhs.m_callback_baton_sp), - m_callback_is_synchronous(rhs.m_callback_is_synchronous), - m_thread_spec_up() { + m_callback_is_synchronous(rhs.m_callback_is_synchronous) { if (rhs.m_thread_spec_up != nullptr) m_thread_spec_up = std::make_unique<ThreadSpec>(*rhs.m_thread_spec_up); } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.cpp index c4e55fdb3b9c..755cf6c61f26 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.cpp @@ -179,7 +179,7 @@ public: class BreakpointDummyOptionGroup : public OptionGroup { public: - BreakpointDummyOptionGroup() {} + BreakpointDummyOptionGroup() = default; ~BreakpointDummyOptionGroup() override = default; @@ -252,7 +252,7 @@ public: class CommandOptions : public OptionGroup { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -1118,7 +1118,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -1249,7 +1249,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -1401,7 +1401,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -1618,7 +1618,7 @@ public: class BreakpointAccessOptionGroup : public OptionGroup { public: - BreakpointAccessOptionGroup() {} + BreakpointAccessOptionGroup() = default; ~BreakpointAccessOptionGroup() override = default; @@ -2018,8 +2018,99 @@ class CommandObjectBreakpointName : public CommandObjectMultiword { public: CommandObjectBreakpointName(CommandInterpreter &interpreter) : CommandObjectMultiword( - interpreter, "name", "Commands to manage name tags for breakpoints", - "breakpoint name <subcommand> [<command-options>]") { + interpreter, "name", "Commands to manage breakpoint names") { + + + SetHelpLong( + R"( +Breakpoint names provide a general tagging mechanism for breakpoints. Each +breakpoint name can be added to any number of breakpoints, and each breakpoint +can have any number of breakpoint names attached to it. For instance: + + (lldb) break name add -N MyName 1-10 + +adds the name MyName to breakpoints 1-10, and: + + (lldb) break set -n myFunc -N Name1 -N Name2 + +adds two names to the breakpoint set at myFunc. + +They have a number of interrelated uses: + +1) They provide a stable way to refer to a breakpoint (e.g. in another +breakpoint's action). Using the breakpoint ID for this purpose is fragile, since +it depends on the order of breakpoint creation. Giving a name to the breakpoint +you want to act on, and then referring to it by name, is more robust: + + (lldb) break set -n myFunc -N BKPT1 + (lldb) break set -n myOtherFunc -C "break disable BKPT1" + +2) This is actually just a specific use of a more general feature of breakpoint +names. The <breakpt-id-list> argument type used to specify one or more +breakpoints in most of the commands that deal with breakpoints also accepts +breakpoint names. That allows you to refer to one breakpoint in a stable +manner, but also makes them a convenient grouping mechanism, allowing you to +easily act on a group of breakpoints by using their name, for instance disabling +them all in one action: + + (lldb) break set -n myFunc -N Group1 + (lldb) break set -n myOtherFunc -N Group1 + (lldb) break disable Group1 + +3) But breakpoint names are also entities in their own right, and can be +configured with all the modifiable attributes of a breakpoint. Then when you +add a breakpoint name to a breakpoint, the breakpoint will be configured to +match the state of the breakpoint name. The link between the name and the +breakpoints sharing it remains live, so if you change the configuration on the +name, it will also change the configurations on the breakpoints: + + (lldb) break name configure -i 10 IgnoreSome + (lldb) break set -n myFunc -N IgnoreSome + (lldb) break list IgnoreSome + 2: name = 'myFunc', locations = 0 (pending) Options: ignore: 10 enabled + Names: + IgnoreSome + (lldb) break name configure -i 5 IgnoreSome + (lldb) break list IgnoreSome + 2: name = 'myFunc', locations = 0 (pending) Options: ignore: 5 enabled + Names: + IgnoreSome + +Options that are not configured on a breakpoint name don't affect the value of +those options on the breakpoints they are added to. So for instance, if Name1 +has the -i option configured and Name2 the -c option, adding both names to a +breakpoint will set the -i option from Name1 and the -c option from Name2, and +the other options will be unaltered. + +If you add multiple names to a breakpoint which have configured values for +the same option, the last name added's value wins. + +The "liveness" of these settings is one way, from name to breakpoint. +If you use "break modify" to change an option that is also configured on a name +which that breakpoint has, the "break modify" command will override the setting +for that breakpoint, but won't change the value configured in the name or on the +other breakpoints sharing that name. + +4) Breakpoint names are also a convenient way to copy option sets from one +breakpoint to another. Using the -B option to "breakpoint name configure" makes +a name configured with all the options of the original breakpoint. Then +adding that name to another breakpoint copies over all the values from the +original breakpoint to the new one. + +5) You can also use breakpoint names to hide breakpoints from the breakpoint +operations that act on all breakpoints: "break delete", "break disable" and +"break list". You do that by specifying a "false" value for the +--allow-{list,delete,disable} options to "breakpoint name configure" and then +adding that name to a breakpoint. + +This won't keep the breakpoint from being deleted or disabled if you refer to it +specifically by ID. The point of the feature is to make sure users don't +inadvertently delete or disable useful breakpoints (e.g. ones an IDE is using +for its own purposes) as part of a "delete all" or "disable all" operation. The +list hiding is because it's confusing for people to see breakpoints they +didn't set. + +)"); CommandObjectSP add_command_object( new CommandObjectBreakpointNameAdd(interpreter)); CommandObjectSP delete_command_object( @@ -2059,7 +2150,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -2255,7 +2346,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpointCommand.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpointCommand.cpp index 637e8b8bd578..bf0cae51d733 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpointCommand.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpointCommand.cpp @@ -281,7 +281,7 @@ are no syntax errors may indicate that a function was declared but never called. class CommandOptions : public OptionGroup { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -501,7 +501,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.cpp index 4b4932dd367b..39c7207bbdbe 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.cpp @@ -56,9 +56,9 @@ public: ~CommandObjectCommandsSource() override = default; - const char *GetRepeatCommand(Args ¤t_command_args, - uint32_t index) override { - return ""; + llvm::Optional<std::string> GetRepeatCommand(Args ¤t_command_args, + uint32_t index) override { + return std::string(""); } void @@ -206,7 +206,7 @@ class CommandObjectCommandsAlias : public CommandObjectRaw { protected: class CommandOptions : public OptionGroup { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -824,6 +824,8 @@ a number follows 'f':" R"( (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/')"); + CommandArgumentData thread_arg{eArgTypeSEDStylePair, eArgRepeatOptional}; + m_arguments.push_back({thread_arg}); } ~CommandObjectCommandsAddRegex() override = default; @@ -1022,7 +1024,7 @@ private: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -1076,7 +1078,7 @@ public: std::string funct, std::string help, ScriptedCommandSynchronicity synch) : CommandObjectRaw(interpreter, name), m_function_name(funct), - m_synchro(synch), m_fetched_help_long(false) { + m_synchro(synch) { if (!help.empty()) SetHelp(help); else { @@ -1139,7 +1141,7 @@ protected: private: std::string m_function_name; ScriptedCommandSynchronicity m_synchro; - bool m_fetched_help_long; + bool m_fetched_help_long = false; }; class CommandObjectScriptingObject : public CommandObjectRaw { @@ -1267,7 +1269,7 @@ public: protected: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -1422,7 +1424,7 @@ public: protected: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -1445,7 +1447,7 @@ protected: m_short_help = std::string(option_arg); break; case 'o': - m_overwrite = true; + m_overwrite_lazy = eLazyBoolYes; break; case 's': m_synchronicity = @@ -1467,7 +1469,7 @@ protected: m_class_name.clear(); m_funct_name.clear(); m_short_help.clear(); - m_overwrite = false; + m_overwrite_lazy = eLazyBoolCalculate; m_synchronicity = eScriptedCommandSynchronicitySynchronous; } @@ -1480,7 +1482,7 @@ protected: std::string m_class_name; std::string m_funct_name; std::string m_short_help; - bool m_overwrite; + LazyBool m_overwrite_lazy = eLazyBoolCalculate; ScriptedCommandSynchronicity m_synchronicity = eScriptedCommandSynchronicitySynchronous; }; @@ -1499,7 +1501,6 @@ protected: ScriptInterpreter *interpreter = GetDebugger().GetScriptInterpreter(); if (interpreter) { - StringList lines; lines.SplitIntoLines(data); if (lines.GetSize() > 0) { @@ -1562,8 +1563,19 @@ protected: result.AppendError("'command script add' requires at least one argument"); return false; } - // Store the options in case we get multi-line input - m_overwrite = m_options.m_overwrite; + // Store the options in case we get multi-line input, also figure out the + // default if not user supplied: + switch (m_options.m_overwrite_lazy) { + case eLazyBoolCalculate: + m_overwrite = !GetDebugger().GetCommandInterpreter().GetRequireCommandOverwrite(); + break; + case eLazyBoolYes: + m_overwrite = true; + break; + case eLazyBoolNo: + m_overwrite = false; + } + Status path_error; m_container = GetCommandInterpreter().VerifyUserMultiwordCmdPath( command, true, path_error); @@ -1637,8 +1649,9 @@ protected: std::string m_cmd_name; CommandObjectMultiword *m_container = nullptr; std::string m_short_help; - bool m_overwrite; - ScriptedCommandSynchronicity m_synchronicity; + bool m_overwrite = false; + ScriptedCommandSynchronicity m_synchronicity = + eScriptedCommandSynchronicitySynchronous; }; // CommandObjectCommandsScriptList @@ -1653,11 +1666,6 @@ public: ~CommandObjectCommandsScriptList() override = default; bool DoExecute(Args &command, CommandReturnObject &result) override { - if (command.GetArgumentCount() != 0) { - result.AppendError("'command script list' doesn't take any arguments"); - return false; - } - m_interpreter.GetHelp(result, CommandInterpreter::eCommandTypesUserDef); result.SetStatus(eReturnStatusSuccessFinishResult); @@ -1678,11 +1686,6 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - if (command.GetArgumentCount() != 0) { - result.AppendError("'command script clear' doesn't take any arguments"); - return false; - } - m_interpreter.RemoveAllUser(); result.SetStatus(eReturnStatusSuccessFinishResult); @@ -1879,7 +1882,7 @@ public: protected: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -2088,8 +2091,8 @@ public: : CommandObjectMultiword( interpreter, "command container", "Commands for adding container commands to lldb. " - "Container commands are containers for other commands. You can" - "add nested container commands by specifying a command path, but " + "Container commands are containers for other commands. You can " + "add nested container commands by specifying a command path, " "but you can't add commands into the built-in command hierarchy.", "command container <subcommand> [<subcommand-options>]") { LoadSubCommand("add", CommandObjectSP(new CommandObjectCommandsContainerAdd( diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectDisassemble.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectDisassemble.cpp index e3c40ed73cf6..9d081c83c0fb 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectDisassemble.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectDisassemble.cpp @@ -278,11 +278,20 @@ CommandObjectDisassemble::GetContainingAddressRanges() { llvm::Expected<std::vector<AddressRange>> CommandObjectDisassemble::GetCurrentFunctionRanges() { + Process *process = m_exe_ctx.GetProcessPtr(); StackFrame *frame = m_exe_ctx.GetFramePtr(); if (!frame) { - return llvm::createStringError(llvm::inconvertibleErrorCode(), - "Cannot disassemble around the current " - "function without a selected frame.\n"); + if (process) { + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Cannot disassemble around the current " + "function without the process being stopped.\n"); + } else { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Cannot disassemble around the current " + "function without a selected frame: " + "no currently running process.\n"); + } } SymbolContext sc( frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol)); @@ -301,11 +310,20 @@ CommandObjectDisassemble::GetCurrentFunctionRanges() { llvm::Expected<std::vector<AddressRange>> CommandObjectDisassemble::GetCurrentLineRanges() { + Process *process = m_exe_ctx.GetProcessPtr(); StackFrame *frame = m_exe_ctx.GetFramePtr(); if (!frame) { - return llvm::createStringError(llvm::inconvertibleErrorCode(), - "Cannot disassemble around the current " - "line without a selected frame.\n"); + if (process) { + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Cannot disassemble around the current " + "function without the process being stopped.\n"); + } else { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Cannot disassemble around the current " + "line without a selected frame: " + "no currently running process.\n"); + } } LineEntry pc_line_entry( @@ -361,11 +379,20 @@ CommandObjectDisassemble::GetNameRanges(CommandReturnObject &result) { llvm::Expected<std::vector<AddressRange>> CommandObjectDisassemble::GetPCRanges() { + Process *process = m_exe_ctx.GetProcessPtr(); StackFrame *frame = m_exe_ctx.GetFramePtr(); if (!frame) { - return llvm::createStringError(llvm::inconvertibleErrorCode(), - "Cannot disassemble around the current " - "PC without a selected frame.\n"); + if (process) { + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Cannot disassemble around the current " + "function without the process being stopped.\n"); + } else { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Cannot disassemble around the current " + "PC without a selected frame: " + "no currently running process.\n"); + } } if (m_options.num_instructions == 0) { @@ -447,7 +474,7 @@ bool CommandObjectDisassemble::DoExecute(Args &command, "\"disassemble\" arguments are specified as options.\n"); const int terminal_width = GetCommandInterpreter().GetDebugger().GetTerminalWidth(); - GetOptions()->GenerateOptionUsage(result.GetErrorStream(), this, + GetOptions()->GenerateOptionUsage(result.GetErrorStream(), *this, terminal_width); return false; } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.cpp index e1a289b219c3..59c2cdb0938c 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.cpp @@ -24,7 +24,7 @@ using namespace lldb; using namespace lldb_private; -CommandObjectExpression::CommandOptions::CommandOptions() {} +CommandObjectExpression::CommandOptions::CommandOptions() = default; CommandObjectExpression::CommandOptions::~CommandOptions() = default; @@ -486,9 +486,6 @@ bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr, void CommandObjectExpression::IOHandlerInputComplete(IOHandler &io_handler, std::string &line) { io_handler.SetIsDone(true); - // StreamSP output_stream = - // io_handler.GetDebugger().GetAsyncOutputStream(); - // StreamSP error_stream = io_handler.GetDebugger().GetAsyncErrorStream(); StreamFileSP output_sp = io_handler.GetOutputStreamFileSP(); StreamFileSP error_sp = io_handler.GetErrorStreamFileSP(); diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.cpp index 70881f2d0061..9f2c79d84ad4 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.cpp @@ -137,16 +137,16 @@ protected: ValueObjectSP valobj_sp; - if (m_options.address.hasValue()) { - if (m_options.reg.hasValue() || m_options.offset.hasValue()) { + if (m_options.address) { + if (m_options.reg || m_options.offset) { result.AppendError( "`frame diagnose --address` is incompatible with other arguments."); return false; } valobj_sp = frame_sp->GuessValueForAddress(m_options.address.getValue()); - } else if (m_options.reg.hasValue()) { + } else if (m_options.reg) { valobj_sp = frame_sp->GuessValueForRegisterAndOffset( - m_options.reg.getValue(), m_options.offset.getValueOr(0)); + m_options.reg.getValue(), m_options.offset.value_or(0)); } else { StopInfoSP stop_info_sp = thread->GetStopInfo(); if (!stop_info_sp) { @@ -304,7 +304,7 @@ protected: Thread *thread = m_exe_ctx.GetThreadPtr(); uint32_t frame_idx = UINT32_MAX; - if (m_options.relative_frame_offset.hasValue()) { + if (m_options.relative_frame_offset) { // The one and only argument is a signed relative frame index frame_idx = thread->GetSelectedFrameIndex(); if (frame_idx == UINT32_MAX) @@ -348,7 +348,7 @@ protected: "too many arguments; expected frame-index, saw '%s'.\n", command[0].c_str()); m_options.GenerateOptionUsage( - result.GetErrorStream(), this, + result.GetErrorStream(), *this, GetCommandInterpreter().GetDebugger().GetTerminalWidth()); return false; } @@ -695,11 +695,8 @@ protected: } } - if (m_interpreter.TruncationWarningNecessary()) { - result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(), - m_cmd_name.c_str()); - m_interpreter.TruncationWarningGiven(); - } + m_interpreter.PrintWarningsIfNecessary(result.GetOutputStream(), + m_cmd_name); // Increment statistics. bool res = result.Succeeded(); @@ -726,7 +723,7 @@ class CommandObjectFrameRecognizerAdd : public CommandObjectParsed { private: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, @@ -927,7 +924,11 @@ class CommandObjectFrameRecognizerDelete : public CommandObjectParsed { public: CommandObjectFrameRecognizerDelete(CommandInterpreter &interpreter) : CommandObjectParsed(interpreter, "frame recognizer delete", - "Delete an existing frame recognizer.", nullptr) {} + "Delete an existing frame recognizer by id.", + nullptr) { + CommandArgumentData thread_arg{eArgTypeRecognizerID, eArgRepeatPlain}; + m_arguments.push_back({thread_arg}); + } ~CommandObjectFrameRecognizerDelete() override = default; diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectGUI.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectGUI.cpp index 86c47a2f0634..a63d1718610c 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectGUI.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectGUI.cpp @@ -26,22 +26,18 @@ CommandObjectGUI::~CommandObjectGUI() = default; bool CommandObjectGUI::DoExecute(Args &args, CommandReturnObject &result) { #if LLDB_ENABLE_CURSES - if (args.GetArgumentCount() == 0) { - Debugger &debugger = GetDebugger(); - - File &input = debugger.GetInputFile(); - File &output = debugger.GetOutputFile(); - if (input.GetStream() && output.GetStream() && input.GetIsRealTerminal() && - input.GetIsInteractive()) { - IOHandlerSP io_handler_sp(new IOHandlerCursesGUI(debugger)); - if (io_handler_sp) - debugger.RunIOHandlerAsync(io_handler_sp); - result.SetStatus(eReturnStatusSuccessFinishResult); - } else { - result.AppendError("the gui command requires an interactive terminal."); - } + Debugger &debugger = GetDebugger(); + + File &input = debugger.GetInputFile(); + File &output = debugger.GetOutputFile(); + if (input.GetStream() && output.GetStream() && input.GetIsRealTerminal() && + input.GetIsInteractive()) { + IOHandlerSP io_handler_sp(new IOHandlerCursesGUI(debugger)); + if (io_handler_sp) + debugger.RunIOHandlerAsync(io_handler_sp); + result.SetStatus(eReturnStatusSuccessFinishResult); } else { - result.AppendError("the gui command takes no arguments."); + result.AppendError("the gui command requires an interactive terminal."); } return true; #else diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectHelp.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectHelp.h index 71799ebb3121..a0ed157b9caf 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectHelp.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectHelp.h @@ -32,7 +32,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectLog.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectLog.cpp index d432ab244805..684cb35da1cc 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectLog.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectLog.cpp @@ -11,6 +11,8 @@ #include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionArgParser.h" +#include "lldb/Interpreter/OptionValueEnumeration.h" +#include "lldb/Interpreter/OptionValueUInt64.h" #include "lldb/Interpreter/Options.h" #include "lldb/Utility/Args.h" #include "lldb/Utility/FileSpec.h" @@ -21,7 +23,40 @@ using namespace lldb; using namespace lldb_private; -#define LLDB_OPTIONS_log +static constexpr OptionEnumValueElement g_log_handler_type[] = { + { + eLogHandlerDefault, + "default", + "Use the default (stream) log handler", + }, + { + eLogHandlerStream, + "stream", + "Write log messages to the debugger output stream or to a file if one " + "is specified. A buffer size (in bytes) can be specified with -b. If " + "no buffer size is specified the output is unbuffered.", + }, + { + eLogHandlerCircular, + "circular", + "Write log messages to a fixed size circular buffer. A buffer size " + "(number of messages) must be specified with -b.", + }, + { + eLogHandlerSystem, + "os", + "Write log messages to the operating system log.", + }, +}; + +static constexpr OptionEnumValues LogHandlerType() { + return OptionEnumValues(g_log_handler_type); +} + +#define LLDB_OPTIONS_log_enable +#include "CommandOptions.inc" + +#define LLDB_OPTIONS_log_dump #include "CommandOptions.inc" /// Common completion logic for log enable/disable. @@ -75,7 +110,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -89,8 +124,17 @@ public: log_file.SetFile(option_arg, FileSpec::Style::native); FileSystem::Instance().Resolve(log_file); break; - case 't': - log_options |= LLDB_LOG_OPTION_THREADSAFE; + case 'h': + handler = (LogHandlerKind)OptionArgParser::ToOptionEnum( + option_arg, GetDefinitions()[option_idx].enum_values, 0, error); + if (!error.Success()) + error.SetErrorStringWithFormat( + "unrecognized value for log handler '%s'", + option_arg.str().c_str()); + break; + case 'b': + error = + buffer_size.SetValueFromString(option_arg, eVarSetOperationAssign); break; case 'v': log_options |= LLDB_LOG_OPTION_VERBOSE; @@ -125,16 +169,18 @@ public: void OptionParsingStarting(ExecutionContext *execution_context) override { log_file.Clear(); + buffer_size.Clear(); + handler = eLogHandlerStream; log_options = 0; } llvm::ArrayRef<OptionDefinition> GetDefinitions() override { - return llvm::makeArrayRef(g_log_options); + return llvm::makeArrayRef(g_log_enable_options); } - // Instance variables to hold the values for command options. - FileSpec log_file; + OptionValueUInt64 buffer_size; + LogHandlerKind handler = eLogHandlerStream; uint32_t log_options = 0; }; @@ -153,6 +199,13 @@ protected: return false; } + if (m_options.handler == eLogHandlerCircular && + m_options.buffer_size.GetCurrentValue() == 0) { + result.AppendError( + "the circular buffer handler requires a non-zero buffer size.\n"); + return false; + } + // Store into a std::string since we're about to shift the channel off. const std::string channel = std::string(args[0].ref()); args.Shift(); // Shift off the channel @@ -164,9 +217,10 @@ protected: std::string error; llvm::raw_string_ostream error_stream(error); - bool success = - GetDebugger().EnableLog(channel, args.GetArgumentArrayRef(), log_file, - m_options.log_options, error_stream); + bool success = GetDebugger().EnableLog( + channel, args.GetArgumentArrayRef(), log_file, m_options.log_options, + m_options.buffer_size.GetCurrentValue(), m_options.handler, + error_stream); result.GetErrorStream() << error_stream.str(); if (success) @@ -294,6 +348,114 @@ protected: return result.Succeeded(); } }; +class CommandObjectLogDump : public CommandObjectParsed { +public: + CommandObjectLogDump(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "log dump", + "dump circular buffer logs", nullptr) { + CommandArgumentEntry arg1; + CommandArgumentData channel_arg; + + // Define the first (and only) variant of this arg. + channel_arg.arg_type = eArgTypeLogChannel; + channel_arg.arg_repetition = eArgRepeatPlain; + + // There is only one variant this argument could be; put it into the + // argument entry. + arg1.push_back(channel_arg); + + // Push the data for the first argument into the m_arguments vector. + m_arguments.push_back(arg1); + } + + ~CommandObjectLogDump() override = default; + + Options *GetOptions() override { return &m_options; } + + class CommandOptions : public Options { + public: + CommandOptions() = default; + + ~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 'f': + log_file.SetFile(option_arg, FileSpec::Style::native); + FileSystem::Instance().Resolve(log_file); + break; + default: + llvm_unreachable("Unimplemented option"); + } + + return error; + } + + void OptionParsingStarting(ExecutionContext *execution_context) override { + log_file.Clear(); + } + + llvm::ArrayRef<OptionDefinition> GetDefinitions() override { + return llvm::makeArrayRef(g_log_dump_options); + } + + FileSpec log_file; + }; + + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + CompleteEnableDisable(request); + } + +protected: + bool DoExecute(Args &args, CommandReturnObject &result) override { + if (args.empty()) { + result.AppendErrorWithFormat( + "%s takes a log channel and one or more log types.\n", + m_cmd_name.c_str()); + return false; + } + + std::unique_ptr<llvm::raw_ostream> stream_up; + if (m_options.log_file) { + const File::OpenOptions flags = File::eOpenOptionWriteOnly | + File::eOpenOptionCanCreate | + File::eOpenOptionTruncate; + llvm::Expected<FileUP> file = FileSystem::Instance().Open( + m_options.log_file, flags, lldb::eFilePermissionsFileDefault, false); + if (!file) { + result.AppendErrorWithFormat("Unable to open log file '%s': %s", + m_options.log_file.GetCString(), + llvm::toString(file.takeError()).c_str()); + return false; + } + stream_up = std::make_unique<llvm::raw_fd_ostream>( + (*file)->GetDescriptor(), /*shouldClose=*/true); + } else { + stream_up = std::make_unique<llvm::raw_fd_ostream>( + GetDebugger().GetOutputFile().GetDescriptor(), /*shouldClose=*/false); + } + + const std::string channel = std::string(args[0].ref()); + std::string error; + llvm::raw_string_ostream error_stream(error); + if (Log::DumpLogChannel(channel, *stream_up, error_stream)) { + result.SetStatus(eReturnStatusSuccessFinishNoResult); + } else { + result.SetStatus(eReturnStatusFailed); + result.GetErrorStream() << error_stream.str(); + } + + return result.Succeeded(); + } + + CommandOptions m_options; +}; class CommandObjectLogTimerEnable : public CommandObjectParsed { public: @@ -503,6 +665,8 @@ CommandObjectLog::CommandObjectLog(CommandInterpreter &interpreter) CommandObjectSP(new CommandObjectLogDisable(interpreter))); LoadSubCommand("list", CommandObjectSP(new CommandObjectLogList(interpreter))); + LoadSubCommand("dump", + CommandObjectSP(new CommandObjectLogDump(interpreter))); LoadSubCommand("timers", CommandObjectSP(new CommandObjectLogTimer(interpreter))); } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp index 1033d13f9f26..98fa38f25635 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp @@ -16,6 +16,7 @@ #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Interpreter/OptionGroupFormat.h" +#include "lldb/Interpreter/OptionGroupMemoryTag.h" #include "lldb/Interpreter/OptionGroupOutputFile.h" #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h" #include "lldb/Interpreter/OptionValueLanguage.h" @@ -33,7 +34,6 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/Args.h" #include "lldb/Utility/DataBufferHeap.h" -#include "lldb/Utility/DataBufferLLVM.h" #include "lldb/Utility/StreamString.h" #include "llvm/Support/MathExtras.h" #include <cinttypes> @@ -91,10 +91,6 @@ public: error = m_offset.SetValueFromString(option_value); break; - case '\x01': - m_show_tags = true; - break; - default: llvm_unreachable("Unimplemented option"); } @@ -108,7 +104,6 @@ public: m_force = false; m_offset.Clear(); m_language_for_type.Clear(); - m_show_tags = false; } Status FinalizeSettings(Target *target, OptionGroupFormat &format_options) { @@ -282,7 +277,6 @@ public: bool m_force; OptionValueUInt64 m_offset; OptionValueLanguage m_language_for_type; - bool m_show_tags = false; }; // Read memory from the inferior process @@ -294,8 +288,7 @@ public: "Read from the memory of the current target process.", nullptr, eCommandRequiresTarget | eCommandProcessMustBePaused), m_format_options(eFormatBytesWithASCII, 1, 8), - - m_next_addr(LLDB_INVALID_ADDRESS), m_prev_byte_size(0), + m_memory_tag_options(/*note_binary=*/true), m_prev_format_options(eFormatBytesWithASCII, 1, 8) { CommandArgumentEntry arg1; CommandArgumentEntry arg2; @@ -338,6 +331,8 @@ public: m_option_group.Append(&m_outfile_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3); m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_3); + m_option_group.Append(&m_memory_tag_options, LLDB_OPT_SET_ALL, + LLDB_OPT_SET_ALL); m_option_group.Finalize(); } @@ -345,9 +340,9 @@ public: Options *GetOptions() override { return &m_option_group; } - const char *GetRepeatCommand(Args ¤t_command_args, - uint32_t index) override { - return m_cmd_name.c_str(); + llvm::Optional<std::string> GetRepeatCommand(Args ¤t_command_args, + uint32_t index) override { + return m_cmd_name; } protected: @@ -557,11 +552,13 @@ protected: if (!m_format_options.AnyOptionWasSet() && !m_memory_options.AnyOptionWasSet() && !m_outfile_options.AnyOptionWasSet() && - !m_varobj_options.AnyOptionWasSet()) { + !m_varobj_options.AnyOptionWasSet() && + !m_memory_tag_options.AnyOptionWasSet()) { m_format_options = m_prev_format_options; m_memory_options = m_prev_memory_options; m_outfile_options = m_prev_outfile_options; m_varobj_options = m_prev_varobj_options; + m_memory_tag_options = m_prev_memory_tag_options; } } @@ -595,7 +592,10 @@ protected: return false; } - ABISP abi = m_exe_ctx.GetProcessPtr()->GetABI(); + ABISP abi; + if (Process *proc = m_exe_ctx.GetProcessPtr()) + abi = proc->GetABI(); + if (abi) addr = abi->FixDataAddress(addr); @@ -641,7 +641,7 @@ protected: return false; } - DataBufferSP data_sp; + WritableDataBufferSP data_sp; size_t bytes_read = 0; if (compiler_type.GetOpaqueQualType()) { // Make sure we don't display our type as ASCII bytes like the default @@ -755,6 +755,7 @@ protected: m_prev_memory_options = m_memory_options; m_prev_outfile_options = m_outfile_options; m_prev_varobj_options = m_varobj_options; + m_prev_memory_tag_options = m_memory_tag_options; m_prev_compiler_type = compiler_type; std::unique_ptr<Stream> output_stream_storage; @@ -866,7 +867,7 @@ protected: size_t bytes_dumped = DumpDataExtractor( data, output_stream_p, 0, format, item_byte_size, item_count, num_per_line / target->GetArchitecture().GetDataByteSize(), addr, 0, 0, - exe_scope, m_memory_options.m_show_tags); + exe_scope, m_memory_tag_options.GetShowTags().GetCurrentValue()); m_next_addr = addr + bytes_dumped; output_stream_p->EOL(); return true; @@ -877,12 +878,14 @@ protected: OptionGroupReadMemory m_memory_options; OptionGroupOutputFile m_outfile_options; OptionGroupValueObjectDisplay m_varobj_options; - lldb::addr_t m_next_addr; - lldb::addr_t m_prev_byte_size; + OptionGroupMemoryTag m_memory_tag_options; + lldb::addr_t m_next_addr = LLDB_INVALID_ADDRESS; + lldb::addr_t m_prev_byte_size = 0; OptionGroupFormat m_prev_format_options; OptionGroupReadMemory m_prev_memory_options; OptionGroupOutputFile m_prev_outfile_options; OptionGroupValueObjectDisplay m_prev_varobj_options; + OptionGroupMemoryTag m_prev_memory_tag_options; CompilerType m_prev_compiler_type; }; @@ -975,6 +978,8 @@ public: m_arguments.push_back(arg2); m_option_group.Append(&m_memory_options); + m_option_group.Append(&m_memory_tag_options, LLDB_OPT_SET_ALL, + LLDB_OPT_SET_ALL); m_option_group.Finalize(); } @@ -986,7 +991,7 @@ protected: class ProcessMemoryIterator { public: ProcessMemoryIterator(ProcessSP process_sp, lldb::addr_t base) - : m_process_sp(process_sp), m_base_addr(base), m_is_valid(true) { + : m_process_sp(process_sp), m_base_addr(base) { lldbassert(process_sp.get() != nullptr); } @@ -1010,7 +1015,7 @@ protected: private: ProcessSP m_process_sp; lldb::addr_t m_base_addr; - bool m_is_valid; + bool m_is_valid = true; }; bool DoExecute(Args &command, CommandReturnObject &result) override { // No need to check "process" for validity as eCommandRequiresProcess @@ -1054,9 +1059,14 @@ protected: DataBufferHeap buffer; - if (m_memory_options.m_string.OptionWasSet()) - buffer.CopyData(m_memory_options.m_string.GetStringValue()); - else if (m_memory_options.m_expr.OptionWasSet()) { + if (m_memory_options.m_string.OptionWasSet()) { + llvm::StringRef str = m_memory_options.m_string.GetStringValue(); + if (str.empty()) { + result.AppendError("search string must have non-zero length."); + return false; + } + buffer.CopyData(str); + } else if (m_memory_options.m_expr.OptionWasSet()) { StackFrame *frame = m_exe_ctx.GetFramePtr(); ValueObjectSP result_sp; if ((eExpressionCompleted == @@ -1134,7 +1144,9 @@ protected: DumpDataExtractor( data, &result.GetOutputStream(), 0, lldb::eFormatBytesWithASCII, 1, dumpbuffer.GetByteSize(), 16, - found_location + m_memory_options.m_offset.GetCurrentValue(), 0, 0); + found_location + m_memory_options.m_offset.GetCurrentValue(), 0, 0, + m_exe_ctx.GetBestExecutionContextScope(), + m_memory_tag_options.GetShowTags().GetCurrentValue()); result.GetOutputStream().EOL(); } @@ -1177,6 +1189,7 @@ protected: OptionGroupOptions m_option_group; OptionGroupFindMemory m_memory_options; + OptionGroupMemoryTag m_memory_tag_options; }; #define LLDB_OPTIONS_memory_write @@ -1187,7 +1200,7 @@ class CommandObjectMemoryWrite : public CommandObjectParsed { public: class OptionGroupWriteMemory : public OptionGroup { public: - OptionGroupWriteMemory() {} + OptionGroupWriteMemory() = default; ~OptionGroupWriteMemory() override = default; @@ -1586,9 +1599,9 @@ public: ~CommandObjectMemoryHistory() override = default; - const char *GetRepeatCommand(Args ¤t_command_args, - uint32_t index) override { - return m_cmd_name.c_str(); + llvm::Optional<std::string> GetRepeatCommand(Args ¤t_command_args, + uint32_t index) override { + return m_cmd_name; } protected: @@ -1638,20 +1651,112 @@ protected: // CommandObjectMemoryRegion #pragma mark CommandObjectMemoryRegion +#define LLDB_OPTIONS_memory_region +#include "CommandOptions.inc" + class CommandObjectMemoryRegion : public CommandObjectParsed { public: + class OptionGroupMemoryRegion : public OptionGroup { + public: + OptionGroupMemoryRegion() : OptionGroup(), m_all(false, false) {} + + ~OptionGroupMemoryRegion() override = default; + + llvm::ArrayRef<OptionDefinition> GetDefinitions() override { + return llvm::makeArrayRef(g_memory_region_options); + } + + Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, + ExecutionContext *execution_context) override { + Status status; + const int short_option = g_memory_region_options[option_idx].short_option; + + switch (short_option) { + case 'a': + m_all.SetCurrentValue(true); + m_all.SetOptionWasSet(); + break; + default: + llvm_unreachable("Unimplemented option"); + } + + return status; + } + + void OptionParsingStarting(ExecutionContext *execution_context) override { + m_all.Clear(); + } + + OptionValueBoolean m_all; + }; + CommandObjectMemoryRegion(CommandInterpreter &interpreter) : CommandObjectParsed(interpreter, "memory region", "Get information on the memory region containing " "an address in the current target process.", - "memory region ADDR", + "memory region <address-expression> (or --all)", eCommandRequiresProcess | eCommandTryTargetAPILock | - eCommandProcessMustBeLaunched), - m_prev_end_addr(LLDB_INVALID_ADDRESS) {} + eCommandProcessMustBeLaunched) { + // Address in option set 1. + m_arguments.push_back(CommandArgumentEntry{CommandArgumentData( + eArgTypeAddressOrExpression, eArgRepeatPlain, LLDB_OPT_SET_1)}); + // "--all" will go in option set 2. + m_option_group.Append(&m_memory_region_options); + m_option_group.Finalize(); + } ~CommandObjectMemoryRegion() override = default; + Options *GetOptions() override { return &m_option_group; } + protected: + void DumpRegion(CommandReturnObject &result, Target &target, + const MemoryRegionInfo &range_info, lldb::addr_t load_addr) { + lldb_private::Address addr; + ConstString section_name; + if (target.ResolveLoadAddress(load_addr, addr)) { + SectionSP section_sp(addr.GetSection()); + if (section_sp) { + // Got the top most section, not the deepest section + while (section_sp->GetParent()) + section_sp = section_sp->GetParent(); + section_name = section_sp->GetName(); + } + } + + ConstString name = range_info.GetName(); + result.AppendMessageWithFormatv( + "[{0:x16}-{1:x16}) {2:r}{3:w}{4:x}{5}{6}{7}{8}", + range_info.GetRange().GetRangeBase(), + range_info.GetRange().GetRangeEnd(), range_info.GetReadable(), + range_info.GetWritable(), range_info.GetExecutable(), name ? " " : "", + name, section_name ? " " : "", section_name); + MemoryRegionInfo::OptionalBool memory_tagged = range_info.GetMemoryTagged(); + 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) { + 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)[i]); + } + result.AppendMessageWithFormat(".\n"); + } + } + } + bool DoExecute(Args &command, CommandReturnObject &result) override { ProcessSP process_sp = m_exe_ctx.GetProcessSP(); if (!process_sp) { @@ -1668,6 +1773,13 @@ protected: const lldb::ABISP &abi = process_sp->GetABI(); if (argc == 1) { + if (m_memory_region_options.m_all) { + result.AppendError( + "The \"--all\" option cannot be used when an address " + "argument is given"); + return false; + } + auto load_addr_str = command[0].ref(); // Non-address bits in this will be handled later by GetMemoryRegion load_addr = OptionArgParser::ToAddress(&m_exe_ctx, load_addr_str, @@ -1681,67 +1793,58 @@ protected: // When we're repeating the command, the previous end address is // used for load_addr. If that was 0xF...F then we must have // reached the end of memory. - (argc == 0 && load_addr == LLDB_INVALID_ADDRESS) || + (argc == 0 && !m_memory_region_options.m_all && + load_addr == LLDB_INVALID_ADDRESS) || // If the target has non-address bits (tags, limited virtual // address size, etc.), the end of mappable memory will be lower // than that. So if we find any non-address bit set, we must be // at the end of the mappable range. - (abi && (abi->FixDataAddress(load_addr) != load_addr))) { - result.AppendErrorWithFormat("'%s' takes one argument:\nUsage: %s\n", - m_cmd_name.c_str(), m_cmd_syntax.c_str()); + (abi && (abi->FixAnyAddress(load_addr) != load_addr))) { + result.AppendErrorWithFormat( + "'%s' takes one argument or \"--all\" option:\nUsage: %s\n", + m_cmd_name.c_str(), m_cmd_syntax.c_str()); return false; } - lldb_private::MemoryRegionInfo range_info; - error = process_sp->GetMemoryRegionInfo(load_addr, range_info); - if (error.Success()) { - lldb_private::Address addr; - ConstString name = range_info.GetName(); - ConstString section_name; - if (process_sp->GetTarget().ResolveLoadAddress(load_addr, addr)) { - SectionSP section_sp(addr.GetSection()); - if (section_sp) { - // Got the top most section, not the deepest section - while (section_sp->GetParent()) - section_sp = section_sp->GetParent(); - section_name = section_sp->GetName(); + // Is is important that we track the address used to request the region as + // this will give the correct section name in the case that regions overlap. + // On Windows we get mutliple regions that start at the same place but are + // different sizes and refer to different sections. + std::vector<std::pair<lldb_private::MemoryRegionInfo, lldb::addr_t>> + region_list; + if (m_memory_region_options.m_all) { + // We don't use GetMemoryRegions here because it doesn't include unmapped + // areas like repeating the command would. So instead, emulate doing that. + lldb::addr_t addr = 0; + while (error.Success() && addr != LLDB_INVALID_ADDRESS && + // When there are non-address bits the last range will not extend + // to LLDB_INVALID_ADDRESS but to the max virtual address. + // This prevents us looping forever if that is the case. + (abi && (abi->FixAnyAddress(addr) == addr))) { + lldb_private::MemoryRegionInfo region_info; + error = process_sp->GetMemoryRegionInfo(addr, region_info); + + if (error.Success()) { + region_list.push_back({region_info, addr}); + addr = region_info.GetRange().GetRangeEnd(); } } - result.AppendMessageWithFormatv( - "[{0:x16}-{1:x16}) {2:r}{3:w}{4:x}{5}{6}{7}{8}", - range_info.GetRange().GetRangeBase(), - range_info.GetRange().GetRangeEnd(), range_info.GetReadable(), - range_info.GetWritable(), range_info.GetExecutable(), name ? " " : "", - name, section_name ? " " : "", section_name); - MemoryRegionInfo::OptionalBool memory_tagged = - range_info.GetMemoryTagged(); - 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"); - } + // Even if we read nothing, don't error for --all + error.Clear(); + } else { + lldb_private::MemoryRegionInfo region_info; + error = process_sp->GetMemoryRegionInfo(load_addr, region_info); + if (error.Success()) + region_list.push_back({region_info, load_addr}); + } + + if (error.Success()) { + for (std::pair<MemoryRegionInfo, addr_t> &range : region_list) { + DumpRegion(result, process_sp->GetTarget(), range.first, range.second); + m_prev_end_addr = range.first.GetRange().GetRangeEnd(); } - m_prev_end_addr = range_info.GetRange().GetRangeEnd(); result.SetStatus(eReturnStatusSuccessFinishResult); return true; } @@ -1750,14 +1853,17 @@ protected: return false; } - const char *GetRepeatCommand(Args ¤t_command_args, - uint32_t index) override { + llvm::Optional<std::string> GetRepeatCommand(Args ¤t_command_args, + uint32_t index) override { // If we repeat this command, repeat it without any arguments so we can // show the next memory range - return m_cmd_name.c_str(); + return m_cmd_name; } - lldb::addr_t m_prev_end_addr; + lldb::addr_t m_prev_end_addr = LLDB_INVALID_ADDRESS; + + OptionGroupOptions m_option_group; + OptionGroupMemoryRegion m_memory_region_options; }; // CommandObjectMemory diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectMemoryTag.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectMemoryTag.cpp index d108cf58b18c..67461cac5a29 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectMemoryTag.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectMemoryTag.cpp @@ -138,7 +138,7 @@ class CommandObjectMemoryTagWrite : public CommandObjectParsed { public: class OptionGroupTagWrite : public OptionGroup { public: - OptionGroupTagWrite() : m_end_addr(LLDB_INVALID_ADDRESS) {} + OptionGroupTagWrite() = default; ~OptionGroupTagWrite() override = default; @@ -168,7 +168,7 @@ public: m_end_addr = LLDB_INVALID_ADDRESS; } - lldb::addr_t m_end_addr; + lldb::addr_t m_end_addr = LLDB_INVALID_ADDRESS; }; CommandObjectMemoryTagWrite(CommandInterpreter &interpreter) diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectMultiword.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectMultiword.cpp index 0629342748aa..e4fdb7365e72 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectMultiword.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectMultiword.cpp @@ -290,15 +290,16 @@ void CommandObjectMultiword::HandleCompletion(CompletionRequest &request) { sub_command_object->HandleCompletion(request); } -const char *CommandObjectMultiword::GetRepeatCommand(Args ¤t_command_args, - uint32_t index) { +llvm::Optional<std::string> +CommandObjectMultiword::GetRepeatCommand(Args ¤t_command_args, + uint32_t index) { index++; if (current_command_args.GetArgumentCount() <= index) - return nullptr; + return llvm::None; CommandObject *sub_command_object = GetSubcommandObject(current_command_args[index].ref()); if (sub_command_object == nullptr) - return nullptr; + return llvm::None; return sub_command_object->GetRepeatCommand(current_command_args, index); } @@ -419,12 +420,13 @@ void CommandObjectProxy::HandleArgumentCompletion( proxy_command->HandleArgumentCompletion(request, opt_element_vector); } -const char *CommandObjectProxy::GetRepeatCommand(Args ¤t_command_args, - uint32_t index) { +llvm::Optional<std::string> +CommandObjectProxy::GetRepeatCommand(Args ¤t_command_args, + uint32_t index) { CommandObject *proxy_command = GetProxyCommandObject(); if (proxy_command) return proxy_command->GetRepeatCommand(current_command_args, index); - return nullptr; + return llvm::None; } llvm::StringRef CommandObjectProxy::GetUnsupportedError() { diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.cpp index 4c18465c868a..42b19db5efc4 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.cpp @@ -150,6 +150,8 @@ public: { m_option_group.Append(&m_platform_options, LLDB_OPT_SET_ALL, 1); m_option_group.Finalize(); + CommandArgumentData platform_arg{eArgTypePlatform, eArgRepeatPlain}; + m_arguments.push_back({platform_arg}); } ~CommandObjectPlatformSelect() override = default; @@ -271,7 +273,10 @@ public: : CommandObjectParsed( interpreter, "platform connect", "Select the current platform by providing a connection URL.", - "platform connect <connect-url>", 0) {} + "platform connect <connect-url>", 0) { + CommandArgumentData platform_arg{eArgTypeConnectURL, eArgRepeatPlain}; + m_arguments.push_back({platform_arg}); + } ~CommandObjectPlatformConnect() override = default; @@ -415,7 +420,10 @@ public: CommandObjectPlatformMkDir(CommandInterpreter &interpreter) : CommandObjectParsed(interpreter, "platform mkdir", "Make a new directory on the remote end.", nullptr, - 0) {} + 0) { + CommandArgumentData thread_arg{eArgTypePath, eArgRepeatPlain}; + m_arguments.push_back({thread_arg}); + } ~CommandObjectPlatformMkDir() override = default; @@ -461,7 +469,10 @@ class CommandObjectPlatformFOpen : public CommandObjectParsed { public: CommandObjectPlatformFOpen(CommandInterpreter &interpreter) : CommandObjectParsed(interpreter, "platform file open", - "Open a file on the remote end.", nullptr, 0) {} + "Open a file on the remote end.", nullptr, 0) { + CommandArgumentData path_arg{eArgTypePath, eArgRepeatPlain}; + m_arguments.push_back({path_arg}); + } ~CommandObjectPlatformFOpen() override = default; @@ -521,7 +532,10 @@ class CommandObjectPlatformFClose : public CommandObjectParsed { public: CommandObjectPlatformFClose(CommandInterpreter &interpreter) : CommandObjectParsed(interpreter, "platform file close", - "Close a file on the remote end.", nullptr, 0) {} + "Close a file on the remote end.", nullptr, 0) { + CommandArgumentData path_arg{eArgTypeUnsignedInteger, eArgRepeatPlain}; + m_arguments.push_back({path_arg}); + } ~CommandObjectPlatformFClose() override = default; @@ -562,7 +576,10 @@ public: CommandObjectPlatformFRead(CommandInterpreter &interpreter) : CommandObjectParsed(interpreter, "platform file read", "Read data from a file on the remote end.", nullptr, - 0) {} + 0) { + CommandArgumentData path_arg{eArgTypeUnsignedInteger, eArgRepeatPlain}; + m_arguments.push_back({path_arg}); + } ~CommandObjectPlatformFRead() override = default; @@ -600,7 +617,7 @@ public: protected: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -655,7 +672,10 @@ public: CommandObjectPlatformFWrite(CommandInterpreter &interpreter) : CommandObjectParsed(interpreter, "platform file write", "Write data to a file on the remote end.", nullptr, - 0) {} + 0) { + CommandArgumentData path_arg{eArgTypeUnsignedInteger, eArgRepeatPlain}; + m_arguments.push_back({path_arg}); + } ~CommandObjectPlatformFWrite() override = default; @@ -692,7 +712,7 @@ public: protected: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -1070,6 +1090,10 @@ public: Relative source file paths are resolved against lldb's local working directory. Omitting the destination places the file in the platform working directory.)"); + CommandArgumentData source_arg{eArgTypePath, eArgRepeatPlain}; + CommandArgumentData path_arg{eArgTypePath, eArgRepeatOptional}; + m_arguments.push_back({source_arg}); + m_arguments.push_back({path_arg}); } ~CommandObjectPlatformPutFile() override = default; @@ -1121,6 +1145,8 @@ public: eCommandRequiresTarget | eCommandTryTargetAPILock) { m_all_options.Append(&m_options); m_all_options.Finalize(); + CommandArgumentData run_arg_arg{eArgTypeRunArgs, eArgRepeatStar}; + m_arguments.push_back({run_arg_arg}); } ~CommandObjectPlatformProcessLaunch() override = default; @@ -1229,84 +1255,78 @@ protected: if (platform_sp) { Status error; - if (args.GetArgumentCount() == 0) { - if (platform_sp) { - Stream &ostrm = result.GetOutputStream(); - - lldb::pid_t pid = - m_options.match_info.GetProcessInfo().GetProcessID(); - if (pid != LLDB_INVALID_PROCESS_ID) { - ProcessInstanceInfo proc_info; - if (platform_sp->GetProcessInfo(pid, proc_info)) { - ProcessInstanceInfo::DumpTableHeader(ostrm, m_options.show_args, - m_options.verbose); - proc_info.DumpAsTableRow(ostrm, platform_sp->GetUserIDResolver(), - m_options.show_args, m_options.verbose); - result.SetStatus(eReturnStatusSuccessFinishResult); - } else { - result.AppendErrorWithFormat( - "no process found with pid = %" PRIu64 "\n", pid); - } + if (platform_sp) { + Stream &ostrm = result.GetOutputStream(); + + lldb::pid_t pid = m_options.match_info.GetProcessInfo().GetProcessID(); + if (pid != LLDB_INVALID_PROCESS_ID) { + ProcessInstanceInfo proc_info; + if (platform_sp->GetProcessInfo(pid, proc_info)) { + ProcessInstanceInfo::DumpTableHeader(ostrm, m_options.show_args, + m_options.verbose); + proc_info.DumpAsTableRow(ostrm, platform_sp->GetUserIDResolver(), + m_options.show_args, m_options.verbose); + result.SetStatus(eReturnStatusSuccessFinishResult); } else { - ProcessInstanceInfoList proc_infos; - const uint32_t matches = - platform_sp->FindProcesses(m_options.match_info, proc_infos); - const char *match_desc = nullptr; - const char *match_name = - m_options.match_info.GetProcessInfo().GetName(); - if (match_name && match_name[0]) { - switch (m_options.match_info.GetNameMatchType()) { - case NameMatch::Ignore: - break; - case NameMatch::Equals: - match_desc = "matched"; - break; - case NameMatch::Contains: - match_desc = "contained"; - break; - case NameMatch::StartsWith: - match_desc = "started with"; - break; - case NameMatch::EndsWith: - match_desc = "ended with"; - break; - case NameMatch::RegularExpression: - match_desc = "matched the regular expression"; - break; - } + result.AppendErrorWithFormat( + "no process found with pid = %" PRIu64 "\n", pid); + } + } else { + ProcessInstanceInfoList proc_infos; + const uint32_t matches = + platform_sp->FindProcesses(m_options.match_info, proc_infos); + const char *match_desc = nullptr; + const char *match_name = + m_options.match_info.GetProcessInfo().GetName(); + if (match_name && match_name[0]) { + switch (m_options.match_info.GetNameMatchType()) { + case NameMatch::Ignore: + break; + case NameMatch::Equals: + match_desc = "matched"; + break; + case NameMatch::Contains: + match_desc = "contained"; + break; + case NameMatch::StartsWith: + match_desc = "started with"; + break; + case NameMatch::EndsWith: + match_desc = "ended with"; + break; + case NameMatch::RegularExpression: + match_desc = "matched the regular expression"; + break; } + } - if (matches == 0) { - if (match_desc) - result.AppendErrorWithFormatv( - "no processes were found that {0} \"{1}\" on the \"{2}\" " - "platform\n", - match_desc, match_name, platform_sp->GetPluginName()); - else - result.AppendErrorWithFormatv( - "no processes were found on the \"{0}\" platform\n", - platform_sp->GetPluginName()); - } else { - result.AppendMessageWithFormat( - "%u matching process%s found on \"%s\"", matches, - matches > 1 ? "es were" : " was", - platform_sp->GetName().GetCString()); - if (match_desc) - result.AppendMessageWithFormat(" whose name %s \"%s\"", - match_desc, match_name); - result.AppendMessageWithFormat("\n"); - ProcessInstanceInfo::DumpTableHeader(ostrm, m_options.show_args, - m_options.verbose); - for (uint32_t i = 0; i < matches; ++i) { - proc_infos[i].DumpAsTableRow( - ostrm, platform_sp->GetUserIDResolver(), - m_options.show_args, m_options.verbose); - } + if (matches == 0) { + if (match_desc) + result.AppendErrorWithFormatv( + "no processes were found that {0} \"{1}\" on the \"{2}\" " + "platform\n", + match_desc, match_name, platform_sp->GetName()); + else + result.AppendErrorWithFormatv( + "no processes were found on the \"{0}\" platform\n", + platform_sp->GetName()); + } else { + result.AppendMessageWithFormatv( + "{0} matching process{1} found on \"{2}\"", matches, + matches > 1 ? "es were" : " was", platform_sp->GetName()); + if (match_desc) + result.AppendMessageWithFormat(" whose name %s \"%s\"", + match_desc, match_name); + result.AppendMessageWithFormat("\n"); + ProcessInstanceInfo::DumpTableHeader(ostrm, m_options.show_args, + m_options.verbose); + for (uint32_t i = 0; i < matches; ++i) { + proc_infos[i].DumpAsTableRow( + ostrm, platform_sp->GetUserIDResolver(), m_options.show_args, + m_options.verbose); } } } - } else { - result.AppendError("invalid args: process list takes only options\n"); } } else { result.AppendError("no platform is selected\n"); @@ -1316,7 +1336,7 @@ protected: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -1680,7 +1700,7 @@ class CommandObjectPlatformShell : public CommandObjectRaw { public: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -1738,7 +1758,10 @@ public: CommandObjectPlatformShell(CommandInterpreter &interpreter) : CommandObjectRaw(interpreter, "platform shell", "Run a shell command on the current platform.", - "platform shell <shell-command>", 0) {} + "platform shell <shell-command>", 0) { + CommandArgumentData thread_arg{eArgTypeNone, eArgRepeatStar}; + m_arguments.push_back({thread_arg}); + } ~CommandObjectPlatformShell() override = default; @@ -1825,7 +1848,12 @@ public: : CommandObjectParsed( interpreter, "platform target-install", "Install a target (bundle or executable file) to the remote end.", - "platform target-install <local-thing> <remote-sandbox>", 0) {} + "platform target-install <local-thing> <remote-sandbox>", 0) { + CommandArgumentData local_arg{eArgTypePath, eArgRepeatPlain}; + CommandArgumentData remote_arg{eArgTypePath, eArgRepeatPlain}; + m_arguments.push_back({local_arg}); + m_arguments.push_back({remote_arg}); + } ~CommandObjectPlatformInstall() override = default; diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp index c73f0df0aaf2..c76ae99057f2 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp @@ -8,9 +8,12 @@ #include "CommandObjectProcess.h" #include "CommandObjectTrace.h" +#include "CommandObjectBreakpoint.h" #include "CommandOptionsProcessLaunch.h" #include "lldb/Breakpoint/Breakpoint.h" +#include "lldb/Breakpoint/BreakpointIDList.h" #include "lldb/Breakpoint/BreakpointLocation.h" +#include "lldb/Breakpoint/BreakpointName.h" #include "lldb/Breakpoint/BreakpointSite.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" @@ -29,6 +32,8 @@ #include "lldb/Utility/Args.h" #include "lldb/Utility/State.h" +#include "llvm/ADT/ScopeExit.h" + #include <bitset> using namespace lldb; @@ -145,10 +150,10 @@ public: Options *GetOptions() override { return &m_all_options; } - const char *GetRepeatCommand(Args ¤t_command_args, - uint32_t index) override { + llvm::Optional<std::string> GetRepeatCommand(Args ¤t_command_args, + uint32_t index) override { // No repeat for "process launch"... - return ""; + return std::string(""); } protected: @@ -409,12 +414,6 @@ protected: ModuleSP old_exec_module_sp = target->GetExecutableModule(); ArchSpec old_arch_spec = target->GetArchitecture(); - if (command.GetArgumentCount()) { - result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: %s\n", - m_cmd_name.c_str(), m_cmd_syntax.c_str()); - return false; - } - StreamString stream; ProcessSP process_sp; const auto error = target->Attach(m_options.attach_info, &stream); @@ -516,7 +515,7 @@ protected: ~CommandOptions() override = default; Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, - ExecutionContext *execution_context) override { + ExecutionContext *exe_ctx) override { Status error; const int short_option = m_getopt_table[option_idx].val; switch (short_option) { @@ -526,7 +525,10 @@ protected: "invalid value for ignore option: \"%s\", should be a number.", option_arg.str().c_str()); break; - + case 'b': + m_run_to_bkpt_args.AppendArgument(option_arg); + m_any_bkpts_specified = true; + break; default: llvm_unreachable("Unimplemented option"); } @@ -535,27 +537,25 @@ protected: void OptionParsingStarting(ExecutionContext *execution_context) override { m_ignore = 0; + m_run_to_bkpt_args.Clear(); + m_any_bkpts_specified = false; } llvm::ArrayRef<OptionDefinition> GetDefinitions() override { return llvm::makeArrayRef(g_process_continue_options); } - uint32_t m_ignore; + uint32_t m_ignore = 0; + Args m_run_to_bkpt_args; + bool m_any_bkpts_specified = false; }; + bool DoExecute(Args &command, CommandReturnObject &result) override { Process *process = m_exe_ctx.GetProcessPtr(); bool synchronous_execution = m_interpreter.GetSynchronous(); StateType state = process->GetState(); if (state == eStateStopped) { - if (command.GetArgumentCount() != 0) { - result.AppendErrorWithFormat( - "The '%s' command does not take any arguments.\n", - m_cmd_name.c_str()); - return false; - } - if (m_options.m_ignore > 0) { ThreadSP sel_thread_sp(GetDefaultThread()->shared_from_this()); if (sel_thread_sp) { @@ -579,6 +579,130 @@ protected: } } } + + Target *target = m_exe_ctx.GetTargetPtr(); + BreakpointIDList run_to_bkpt_ids; + // Don't pass an empty run_to_breakpoint list, as Verify will look for the + // default breakpoint. + if (m_options.m_run_to_bkpt_args.GetArgumentCount() > 0) + CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( + m_options.m_run_to_bkpt_args, target, result, &run_to_bkpt_ids, + BreakpointName::Permissions::disablePerm); + if (!result.Succeeded()) { + return false; + } + result.Clear(); + if (m_options.m_any_bkpts_specified && run_to_bkpt_ids.GetSize() == 0) { + result.AppendError("continue-to breakpoints did not specify any actual " + "breakpoints or locations"); + return false; + } + + // First figure out which breakpoints & locations were specified by the + // user: + size_t num_run_to_bkpt_ids = run_to_bkpt_ids.GetSize(); + std::vector<break_id_t> bkpts_disabled; + std::vector<BreakpointID> locs_disabled; + if (num_run_to_bkpt_ids != 0) { + // Go through the ID's specified, and separate the breakpoints from are + // the breakpoint.location specifications since the latter require + // special handling. We also figure out whether there's at least one + // specifier in the set that is enabled. + BreakpointList &bkpt_list = target->GetBreakpointList(); + std::unordered_set<break_id_t> bkpts_seen; + std::unordered_set<break_id_t> bkpts_with_locs_seen; + BreakpointIDList with_locs; + bool any_enabled = false; + + for (size_t idx = 0; idx < num_run_to_bkpt_ids; idx++) { + BreakpointID bkpt_id = run_to_bkpt_ids.GetBreakpointIDAtIndex(idx); + break_id_t bp_id = bkpt_id.GetBreakpointID(); + break_id_t loc_id = bkpt_id.GetLocationID(); + BreakpointSP bp_sp + = bkpt_list.FindBreakpointByID(bp_id); + // Note, VerifyBreakpointOrLocationIDs checks for existence, so we + // don't need to do it again here. + if (bp_sp->IsEnabled()) { + if (loc_id == LLDB_INVALID_BREAK_ID) { + // A breakpoint (without location) was specified. Make sure that + // at least one of the locations is enabled. + size_t num_locations = bp_sp->GetNumLocations(); + for (size_t loc_idx = 0; loc_idx < num_locations; loc_idx++) { + BreakpointLocationSP loc_sp + = bp_sp->GetLocationAtIndex(loc_idx); + if (loc_sp->IsEnabled()) { + any_enabled = true; + break; + } + } + } else { + // A location was specified, check if it was enabled: + BreakpointLocationSP loc_sp = bp_sp->FindLocationByID(loc_id); + if (loc_sp->IsEnabled()) + any_enabled = true; + } + + // Then sort the bp & bp.loc entries for later use: + if (bkpt_id.GetLocationID() == LLDB_INVALID_BREAK_ID) + bkpts_seen.insert(bkpt_id.GetBreakpointID()); + else { + bkpts_with_locs_seen.insert(bkpt_id.GetBreakpointID()); + with_locs.AddBreakpointID(bkpt_id); + } + } + } + // Do all the error checking here so once we start disabling we don't + // have to back out half-way through. + + // Make sure at least one of the specified breakpoints is enabled. + if (!any_enabled) { + result.AppendError("at least one of the continue-to breakpoints must " + "be enabled."); + return false; + } + + // Also, if you specify BOTH a breakpoint and one of it's locations, + // we flag that as an error, since it won't do what you expect, the + // breakpoint directive will mean "run to all locations", which is not + // what the location directive means... + for (break_id_t bp_id : bkpts_with_locs_seen) { + if (bkpts_seen.count(bp_id)) { + result.AppendErrorWithFormatv("can't specify both a breakpoint and " + "one of its locations: {0}", bp_id); + } + } + + // Now go through the breakpoints in the target, disabling all the ones + // that the user didn't mention: + for (BreakpointSP bp_sp : bkpt_list.Breakpoints()) { + break_id_t bp_id = bp_sp->GetID(); + // Handle the case where no locations were specified. Note we don't + // have to worry about the case where a breakpoint and one of its + // locations are both in the lists, we've already disallowed that. + if (!bkpts_with_locs_seen.count(bp_id)) { + if (!bkpts_seen.count(bp_id) && bp_sp->IsEnabled()) { + bkpts_disabled.push_back(bp_id); + bp_sp->SetEnabled(false); + } + continue; + } + // Next, handle the case where a location was specified: + // Run through all the locations of this breakpoint and disable + // the ones that aren't on our "with locations" BreakpointID list: + size_t num_locations = bp_sp->GetNumLocations(); + BreakpointID tmp_id(bp_id, LLDB_INVALID_BREAK_ID); + for (size_t loc_idx = 0; loc_idx < num_locations; loc_idx++) { + BreakpointLocationSP loc_sp = bp_sp->GetLocationAtIndex(loc_idx); + tmp_id.SetBreakpointLocationID(loc_idx); + size_t position = 0; + if (!with_locs.FindBreakpointID(tmp_id, &position) + && loc_sp->IsEnabled()) { + locs_disabled.push_back(tmp_id); + loc_sp->SetEnabled(false); + } + } + } + } { // Scope for thread list mutex: std::lock_guard<std::recursive_mutex> guard( @@ -597,10 +721,39 @@ protected: StreamString stream; Status error; + // For now we can only do -b with synchronous: + bool old_sync = GetDebugger().GetAsyncExecution(); + + if (run_to_bkpt_ids.GetSize() != 0) { + GetDebugger().SetAsyncExecution(false); + synchronous_execution = true; + } if (synchronous_execution) error = process->ResumeSynchronous(&stream); else error = process->Resume(); + + if (run_to_bkpt_ids.GetSize() != 0) { + GetDebugger().SetAsyncExecution(old_sync); + } + + // Now re-enable the breakpoints we disabled: + BreakpointList &bkpt_list = target->GetBreakpointList(); + for (break_id_t bp_id : bkpts_disabled) { + BreakpointSP bp_sp = bkpt_list.FindBreakpointByID(bp_id); + if (bp_sp) + bp_sp->SetEnabled(true); + } + for (const BreakpointID &bkpt_id : locs_disabled) { + BreakpointSP bp_sp + = bkpt_list.FindBreakpointByID(bkpt_id.GetBreakpointID()); + if (bp_sp) { + BreakpointLocationSP loc_sp + = bp_sp->FindLocationByID(bkpt_id.GetLocationID()); + if (loc_sp) + loc_sp->SetEnabled(true); + } + } if (error.Success()) { // There is a race condition where this thread will return up the call @@ -777,7 +930,10 @@ public: CommandObjectProcessConnect(CommandInterpreter &interpreter) : CommandObjectParsed(interpreter, "process connect", "Connect to a remote debug service.", - "process connect <remote-url>", 0) {} + "process connect <remote-url>", 0) { + CommandArgumentData connect_arg{eArgTypeConnectURL, eArgRepeatPlain}; + m_arguments.push_back({connect_arg}); + } ~CommandObjectProcessConnect() override = default; @@ -902,7 +1058,10 @@ public: "process load <filename> [<filename> ...]", eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched | - eCommandProcessMustBePaused) {} + eCommandProcessMustBePaused) { + CommandArgumentData file_arg{eArgTypePath, eArgRepeatPlus}; + m_arguments.push_back({file_arg}); + } ~CommandObjectProcessLoad() override = default; @@ -977,7 +1136,10 @@ public: "returned by a previous call to \"process load\".", "process unload <index>", eCommandRequiresProcess | eCommandTryTargetAPILock | - eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {} + eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) { + CommandArgumentData load_idx_arg{eArgTypeUnsignedInteger, eArgRepeatPlain}; + m_arguments.push_back({load_idx_arg}); + } ~CommandObjectProcessUnload() override = default; @@ -1125,18 +1287,13 @@ protected: return false; } - if (command.GetArgumentCount() == 0) { - bool clear_thread_plans = true; - Status error(process->Halt(clear_thread_plans)); - if (error.Success()) { - result.SetStatus(eReturnStatusSuccessFinishResult); - } else { - result.AppendErrorWithFormat("Failed to halt process: %s\n", - error.AsCString()); - } + bool clear_thread_plans = true; + Status error(process->Halt(clear_thread_plans)); + if (error.Success()) { + result.SetStatus(eReturnStatusSuccessFinishResult); } else { - result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n", - m_cmd_name.c_str(), m_cmd_syntax.c_str()); + result.AppendErrorWithFormat("Failed to halt process: %s\n", + error.AsCString()); } return result.Succeeded(); } @@ -1164,17 +1321,12 @@ protected: return false; } - if (command.GetArgumentCount() == 0) { - Status error(process->Destroy(true)); - if (error.Success()) { - result.SetStatus(eReturnStatusSuccessFinishResult); - } else { - result.AppendErrorWithFormat("Failed to kill process: %s\n", - error.AsCString()); - } + Status error(process->Destroy(true)); + if (error.Success()) { + result.SetStatus(eReturnStatusSuccessFinishResult); } else { - result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n", - m_cmd_name.c_str(), m_cmd_syntax.c_str()); + result.AppendErrorWithFormat("Failed to kill process: %s\n", + error.AsCString()); } return result.Succeeded(); } @@ -1206,7 +1358,10 @@ public: "appropriate file type.", "process save-core [-s corefile-style -p plugin-name] FILE", eCommandRequiresProcess | eCommandTryTargetAPILock | - eCommandProcessMustBeLaunched) {} + eCommandProcessMustBeLaunched) { + CommandArgumentData file_arg{eArgTypePath, eArgRepeatPlain}; + m_arguments.push_back({file_arg}); + } ~CommandObjectProcessSaveCore() override = default; @@ -1214,7 +1369,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() : m_requested_save_core_style(eSaveCoreUnspecified) {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -1250,7 +1405,7 @@ public: } // Instance variables to hold the values for command options. - SaveCoreStyle m_requested_save_core_style; + SaveCoreStyle m_requested_save_core_style = eSaveCoreUnspecified; std::string m_requested_plugin_name; }; @@ -1317,7 +1472,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -1353,11 +1508,6 @@ protected: Stream &strm = result.GetOutputStream(); result.SetStatus(eReturnStatusSuccessFinishNoResult); - if (command.GetArgumentCount()) { - result.AppendError("'process status' takes no arguments"); - return result.Succeeded(); - } - // No need to check "process" for validity as eCommandRequiresProcess // ensures it is valid Process *process = m_exe_ctx.GetProcessPtr(); @@ -1432,6 +1582,12 @@ public: const int short_option = m_getopt_table[option_idx].val; switch (short_option) { + case 'c': + do_clear = true; + break; + case 'd': + dummy = true; + break; case 's': stop = std::string(option_arg); break; @@ -1441,6 +1597,9 @@ public: case 'p': pass = std::string(option_arg); break; + case 't': + only_target_values = true; + break; default: llvm_unreachable("Unimplemented option"); } @@ -1451,6 +1610,9 @@ public: stop.clear(); notify.clear(); pass.clear(); + only_target_values = false; + do_clear = false; + dummy = false; } llvm::ArrayRef<OptionDefinition> GetDefinitions() override { @@ -1462,6 +1624,9 @@ public: std::string stop; std::string notify; std::string pass; + bool only_target_values = false; + bool do_clear = false; + bool dummy = false; }; CommandObjectProcessHandle(CommandInterpreter &interpreter) @@ -1469,9 +1634,19 @@ public: "Manage LLDB handling of OS signals for the " "current target process. Defaults to showing " "current policy.", - nullptr, eCommandRequiresTarget) { - SetHelpLong("\nIf no signals are specified, update them all. If no update " - "option is specified, list the current values."); + nullptr) { + SetHelpLong("\nIf no signals are specified but one or more actions are, " + "and there is a live process, update them all. If no action " + "is specified, list the current values.\n" + "If you specify actions with no target (e.g. in an init file) " + "or in a target with no process " + "the values will get copied into subsequent targets, but " + "lldb won't be able to spell-check the options since it can't " + "know which signal set will later be in force." + "\nYou can see the signal modifications held by the target" + "by passing the -t option." + "\nYou can also clear the target modification for a signal" + "by passing the -c option"); CommandArgumentEntry arg; CommandArgumentData signal_arg; @@ -1554,15 +1729,13 @@ public: protected: bool DoExecute(Args &signal_args, CommandReturnObject &result) override { - Target *target_sp = &GetSelectedTarget(); + Target &target = GetSelectedOrDummyTarget(); - ProcessSP process_sp = target_sp->GetProcessSP(); - - if (!process_sp) { - result.AppendError("No current process; cannot handle signals until you " - "have a valid process.\n"); - return false; - } + // Any signals that are being set should be added to the Target's + // DummySignals so they will get applied on rerun, etc. + // If we have a process, however, we can do a more accurate job of vetting + // the user's options. + ProcessSP process_sp = target.GetProcessSP(); int stop_action = -1; // -1 means leave the current setting alone int pass_action = -1; // -1 means leave the current setting alone @@ -1588,35 +1761,99 @@ protected: "true or false.\n"); return false; } + + bool no_actions = (stop_action == -1 && pass_action == -1 + && notify_action == -1); + if (m_options.only_target_values && !no_actions) { + result.AppendError("-t is for reporting, not setting, target values."); + return false; + } size_t num_args = signal_args.GetArgumentCount(); - UnixSignalsSP signals_sp = process_sp->GetUnixSignals(); + UnixSignalsSP signals_sp; + if (process_sp) + signals_sp = process_sp->GetUnixSignals(); + int num_signals_set = 0; + // If we were just asked to print the target values, do that here and + // return: + if (m_options.only_target_values) { + target.PrintDummySignals(result.GetOutputStream(), signal_args); + result.SetStatus(eReturnStatusSuccessFinishResult); + return true; + } + + // This handles clearing values: + if (m_options.do_clear) { + target.ClearDummySignals(signal_args); + if (m_options.dummy) + GetDummyTarget().ClearDummySignals(signal_args); + result.SetStatus(eReturnStatusSuccessFinishNoResult); + return true; + } + + // This rest handles setting values: if (num_args > 0) { for (const auto &arg : signal_args) { - int32_t signo = signals_sp->GetSignalNumberFromName(arg.c_str()); - if (signo != LLDB_INVALID_SIGNAL_NUMBER) { - // Casting the actions as bools here should be okay, because - // VerifyCommandOptionValue guarantees the value is either 0 or 1. - if (stop_action != -1) - signals_sp->SetShouldStop(signo, stop_action); - if (pass_action != -1) { - bool suppress = !pass_action; - signals_sp->SetShouldSuppress(signo, suppress); + // Do the process first. If we have a process we can catch + // invalid signal names, which we do here. + if (signals_sp) { + int32_t signo = signals_sp->GetSignalNumberFromName(arg.c_str()); + if (signo != LLDB_INVALID_SIGNAL_NUMBER) { + // Casting the actions as bools here should be okay, because + // VerifyCommandOptionValue guarantees the value is either 0 or 1. + if (stop_action != -1) + signals_sp->SetShouldStop(signo, stop_action); + if (pass_action != -1) { + bool suppress = !pass_action; + signals_sp->SetShouldSuppress(signo, suppress); + } + if (notify_action != -1) + signals_sp->SetShouldNotify(signo, notify_action); + ++num_signals_set; + } else { + result.AppendErrorWithFormat("Invalid signal name '%s'\n", + arg.c_str()); + continue; } - if (notify_action != -1) - signals_sp->SetShouldNotify(signo, notify_action); - ++num_signals_set; } else { - result.AppendErrorWithFormat("Invalid signal name '%s'\n", - arg.c_str()); + // If there's no process we can't check, so we just set them all. + // But since the map signal name -> signal number across all platforms + // is not 1-1, we can't sensibly set signal actions by number before + // we have a process. Check that here: + int32_t signo; + if (llvm::to_integer(arg.c_str(), signo)) { + result.AppendErrorWithFormat("Can't set signal handling by signal " + "number with no process"); + return false; + } + num_signals_set = num_args; } + auto set_lazy_bool = [] (int action) -> LazyBool { + LazyBool lazy; + if (action == -1) + lazy = eLazyBoolCalculate; + else if (action) + lazy = eLazyBoolYes; + else + lazy = eLazyBoolNo; + return lazy; + }; + + // If there were no actions, we're just listing, don't add the dummy: + if (!no_actions) + target.AddDummySignal(arg.ref(), + set_lazy_bool(pass_action), + set_lazy_bool(notify_action), + set_lazy_bool(stop_action)); } } else { // No signal specified, if any command options were specified, update ALL - // signals. - if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1)) { + // signals. But we can't do this without a process since we don't know + // all the possible signals that might be valid for this target. + if (((notify_action != -1) || (stop_action != -1) || (pass_action != -1)) + && process_sp) { if (m_interpreter.Confirm( "Do you really want to update all the signals?", false)) { int32_t signo = signals_sp->GetFirstSignalNumber(); @@ -1635,11 +1872,15 @@ protected: } } - PrintSignalInformation(result.GetOutputStream(), signal_args, - num_signals_set, signals_sp); + if (signals_sp) + PrintSignalInformation(result.GetOutputStream(), signal_args, + num_signals_set, signals_sp); + else + target.PrintDummySignals(result.GetOutputStream(), + signal_args); if (num_signals_set > 0) - result.SetStatus(eReturnStatusSuccessFinishNoResult); + result.SetStatus(eReturnStatusSuccessFinishResult); else result.SetStatus(eReturnStatusFailed); diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectQuit.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectQuit.cpp index c6e2e21de6b6..650cfca2c050 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectQuit.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectQuit.cpp @@ -20,7 +20,10 @@ using namespace lldb_private; CommandObjectQuit::CommandObjectQuit(CommandInterpreter &interpreter) : CommandObjectParsed(interpreter, "quit", "Quit the LLDB debugger.", - "quit [exit-code]") {} + "quit [exit-code]") { + CommandArgumentData exit_code_arg{eArgTypeUnsignedInteger, eArgRepeatPlain}; + m_arguments.push_back({exit_code_arg}); +} CommandObjectQuit::~CommandObjectQuit() = default; diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.cpp index 7ddc5c0c7e08..857193036e39 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.cpp @@ -10,6 +10,9 @@ #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" +#include "llvm/Support/Errc.h" +#include "llvm/Support/Error.h" + using namespace lldb; using namespace lldb_private; @@ -25,46 +28,63 @@ CommandObjectRegexCommand::CommandObjectRegexCommand( // Destructor CommandObjectRegexCommand::~CommandObjectRegexCommand() = default; +llvm::Expected<std::string> CommandObjectRegexCommand::SubstituteVariables( + llvm::StringRef input, + const llvm::SmallVectorImpl<llvm::StringRef> &replacements) { + std::string buffer; + llvm::raw_string_ostream output(buffer); + + llvm::SmallVector<llvm::StringRef, 4> parts; + input.split(parts, '%'); + + output << parts[0]; + for (llvm::StringRef part : drop_begin(parts)) { + size_t idx = 0; + if (part.consumeInteger(10, idx)) + output << '%'; + else if (idx < replacements.size()) + output << replacements[idx]; + else + return llvm::make_error<llvm::StringError>( + llvm::formatv("%{0} is out of range: not enough arguments specified", + idx), + llvm::errc::invalid_argument); + output << part; + } + + return output.str(); +} + bool CommandObjectRegexCommand::DoExecute(llvm::StringRef command, CommandReturnObject &result) { EntryCollection::const_iterator pos, end = m_entries.end(); for (pos = m_entries.begin(); pos != end; ++pos) { llvm::SmallVector<llvm::StringRef, 4> matches; if (pos->regex.Execute(command, &matches)) { - std::string new_command(pos->command); - char percent_var[8]; - size_t idx, percent_var_idx; - for (uint32_t match_idx = 1; match_idx <= m_max_matches; ++match_idx) { - if (match_idx < matches.size()) { - const std::string match_str = matches[match_idx].str(); - const int percent_var_len = - ::snprintf(percent_var, sizeof(percent_var), "%%%u", match_idx); - for (idx = 0; (percent_var_idx = new_command.find( - 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(); - } - } + llvm::Expected<std::string> new_command = + SubstituteVariables(pos->command, matches); + if (!new_command) { + result.SetError(new_command.takeError()); + return false; } + // Interpret the new command and return this as the result! if (m_interpreter.GetExpandRegexAliases()) - result.GetOutputStream().Printf("%s\n", new_command.c_str()); - // 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); + result.GetOutputStream().Printf("%s\n", new_command->c_str()); + // We don't have to pass an override_context here, as the command that + // called us should have set up the context appropriately. + return m_interpreter.HandleCommand(new_command->c_str(), + eLazyBoolNo, result); } } result.SetStatus(eReturnStatusFailed); if (!GetSyntax().empty()) result.AppendError(GetSyntax()); else - result.GetOutputStream() << "Command contents '" << command - << "' failed to match any " - "regular expression in the '" - << m_cmd_name << "' regex "; + result.GetErrorStream() << "Command contents '" << command + << "' failed to match any " + "regular expression in the '" + << m_cmd_name << "' regex "; return false; } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.h index 2f65c2cd815d..b2a375c63a76 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.h @@ -39,6 +39,11 @@ public: protected: bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override; + /// Substitute variables of the format %\d+ in the input string. + static llvm::Expected<std::string> SubstituteVariables( + llvm::StringRef input, + const llvm::SmallVectorImpl<llvm::StringRef> &replacements); + struct Entry { RegularExpression regex; std::string command; diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectReproducer.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectReproducer.cpp index 7e0ea65e148e..8d12decba974 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectReproducer.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectReproducer.cpp @@ -182,19 +182,9 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - if (!command.empty()) { - result.AppendErrorWithFormat("'%s' takes no arguments", - m_cmd_name.c_str()); - return false; - } - auto &r = Reproducer::Instance(); if (auto generator = r.GetGenerator()) { generator->Keep(); - if (llvm::Error e = repro::Finalize(r.GetReproducerPath())) { - SetError(result, std::move(e)); - return result.Succeeded(); - } } else { result.AppendErrorWithFormat("Unable to get the reproducer generator"); return false; @@ -227,7 +217,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -264,12 +254,6 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - if (!command.empty()) { - result.AppendErrorWithFormat("'%s' takes no arguments", - m_cmd_name.c_str()); - return false; - } - auto &r = Reproducer::Instance(); if (!r.IsCapturing()) { @@ -313,12 +297,6 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - if (!command.empty()) { - result.AppendErrorWithFormat("'%s' takes no arguments", - m_cmd_name.c_str()); - return false; - } - auto &r = Reproducer::Instance(); if (r.IsCapturing()) { result.GetOutputStream() << "Reproducer is in capture mode.\n"; @@ -355,7 +333,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -398,12 +376,6 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - if (!command.empty()) { - result.AppendErrorWithFormat("'%s' takes no arguments", - m_cmd_name.c_str()); - return false; - } - llvm::Optional<Loader> loader_storage; Loader *loader = GetLoaderFromPathOrCurrent(loader_storage, result, m_options.file); @@ -429,7 +401,7 @@ protected: // Dump the VFS to a buffer. std::string str; raw_string_ostream os(str); - static_cast<vfs::RedirectingFileSystem &>(*vfs).dump(os); + static_cast<vfs::RedirectingFileSystem &>(*vfs).print(os); os.flush(); // Return the string. @@ -587,101 +559,6 @@ private: CommandOptions m_options; }; -class CommandObjectReproducerVerify : public CommandObjectParsed { -public: - CommandObjectReproducerVerify(CommandInterpreter &interpreter) - : CommandObjectParsed(interpreter, "reproducer verify", - "Verify the contents of a reproducer. " - "If no reproducer is specified during replay, it " - "verifies the content of the current reproducer.", - nullptr) {} - - ~CommandObjectReproducerVerify() override = default; - - Options *GetOptions() override { return &m_options; } - - class CommandOptions : public Options { - public: - CommandOptions() {} - - ~CommandOptions() override = default; - - Status SetOptionValue(uint32_t option_idx, StringRef option_arg, - ExecutionContext *execution_context) override { - Status error; - const int short_option = m_getopt_table[option_idx].val; - - switch (short_option) { - case 'f': - file.SetFile(option_arg, FileSpec::Style::native); - FileSystem::Instance().Resolve(file); - break; - default: - llvm_unreachable("Unimplemented option"); - } - - return error; - } - - void OptionParsingStarting(ExecutionContext *execution_context) override { - file.Clear(); - } - - ArrayRef<OptionDefinition> GetDefinitions() override { - return makeArrayRef(g_reproducer_verify_options); - } - - FileSpec file; - }; - -protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { - if (!command.empty()) { - result.AppendErrorWithFormat("'%s' takes no arguments", - m_cmd_name.c_str()); - return false; - } - - llvm::Optional<Loader> loader_storage; - Loader *loader = - GetLoaderFromPathOrCurrent(loader_storage, result, m_options.file); - if (!loader) - return false; - - bool errors = false; - auto error_callback = [&](llvm::StringRef error) { - errors = true; - result.AppendError(error); - }; - - bool warnings = false; - auto warning_callback = [&](llvm::StringRef warning) { - warnings = true; - result.AppendWarning(warning); - }; - - auto note_callback = [&](llvm::StringRef warning) { - result.AppendMessage(warning); - }; - - Verifier verifier(loader); - verifier.Verify(error_callback, warning_callback, note_callback); - - if (warnings || errors) { - result.AppendMessage("reproducer verification failed"); - result.SetStatus(eReturnStatusFailed); - } else { - result.AppendMessage("reproducer verification succeeded"); - result.SetStatus(eReturnStatusSuccessFinishResult); - } - - return result.Succeeded(); - } - -private: - CommandOptions m_options; -}; - CommandObjectReproducer::CommandObjectReproducer( CommandInterpreter &interpreter) : CommandObjectMultiword( @@ -704,8 +581,6 @@ CommandObjectReproducer::CommandObjectReproducer( new CommandObjectReproducerStatus(interpreter))); LoadSubCommand("dump", CommandObjectSP(new CommandObjectReproducerDump(interpreter))); - LoadSubCommand("verify", CommandObjectSP( - new CommandObjectReproducerVerify(interpreter))); LoadSubCommand("xcrash", CommandObjectSP( new CommandObjectReproducerXCrash(interpreter))); } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectScript.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectScript.h index 97fc05421bd0..9d164e864a8b 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectScript.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectScript.h @@ -21,7 +21,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~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/CommandObjectSettings.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectSettings.cpp index 391e728d9d8a..e4162e56dc2c 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectSettings.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectSettings.cpp @@ -86,7 +86,7 @@ insert-before or insert-after."); class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -102,6 +102,9 @@ insert-before or insert-after."); case 'g': m_global = true; break; + case 'e': + m_exists = true; + break; default: llvm_unreachable("Unimplemented option"); } @@ -112,6 +115,7 @@ insert-before or insert-after."); void OptionParsingStarting(ExecutionContext *execution_context) override { m_global = false; m_force = false; + m_exists = false; } llvm::ArrayRef<OptionDefinition> GetDefinitions() override { @@ -120,7 +124,8 @@ insert-before or insert-after."); // Instance variables to hold the values for command options. bool m_global = false; - bool m_force; + bool m_force = false; + bool m_exists = false; }; void @@ -219,13 +224,12 @@ protected: var_name, var_value); } - if (error.Fail()) { + if (error.Fail() && !m_options.m_exists) { result.AppendError(error.AsCString()); return false; - } else { - result.SetStatus(eReturnStatusSuccessFinishResult); } + result.SetStatus(eReturnStatusSuccessFinishResult); return result.Succeeded(); } @@ -325,7 +329,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -423,7 +427,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.cpp index 6c6706f4a98b..f87981859844 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.cpp @@ -36,7 +36,7 @@ using namespace lldb_private; class CommandObjectSourceInfo : public CommandObjectParsed { class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -538,14 +538,6 @@ protected: } bool DoExecute(Args &command, CommandReturnObject &result) override { - const size_t argc = command.GetArgumentCount(); - - if (argc != 0) { - result.AppendErrorWithFormat("'%s' takes no arguments, only flags.\n", - GetCommandName().str().c_str()); - return false; - } - Target *target = m_exe_ctx.GetTargetPtr(); if (target == nullptr) { target = GetDebugger().GetSelectedTarget().get(); @@ -623,7 +615,7 @@ protected: class CommandObjectSourceList : public CommandObjectParsed { class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -728,8 +720,8 @@ public: Options *GetOptions() override { return &m_options; } - const char *GetRepeatCommand(Args ¤t_command_args, - uint32_t index) override { + llvm::Optional<std::string> GetRepeatCommand(Args ¤t_command_args, + uint32_t index) override { // This is kind of gross, but the command hasn't been parsed yet so we // can't look at the option values for this invocation... I have to scan // the arguments directly. @@ -738,13 +730,13 @@ public: return e.ref() == "-r" || e.ref() == "--reverse"; }); if (iter == current_command_args.end()) - return m_cmd_name.c_str(); + return m_cmd_name; if (m_reverse_name.empty()) { m_reverse_name = m_cmd_name; m_reverse_name.append(" -r"); } - return m_reverse_name.c_str(); + return m_reverse_name; } protected: @@ -755,7 +747,7 @@ protected: SourceInfo(ConstString name, const LineEntry &line_entry) : function(name), line_entry(line_entry) {} - SourceInfo() {} + SourceInfo() = default; bool IsValid() const { return (bool)function && line_entry.IsValid(); } @@ -924,14 +916,6 @@ protected: } bool DoExecute(Args &command, CommandReturnObject &result) override { - const size_t argc = command.GetArgumentCount(); - - if (argc != 0) { - result.AppendErrorWithFormat("'%s' takes no arguments, only flags.\n", - GetCommandName().str().c_str()); - return false; - } - Target *target = m_exe_ctx.GetTargetPtr(); if (!m_options.symbol_name.empty()) { diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp index 157065bde10e..2b71f1bc7bc8 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp @@ -47,8 +47,11 @@ #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadSpec.h" #include "lldb/Utility/Args.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/State.h" #include "lldb/Utility/Timer.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-private-enumerations.h" #include "llvm/ADT/ScopeExit.h" #include "llvm/Support/FileSystem.h" @@ -83,8 +86,8 @@ static void DumpTargetInfo(uint32_t target_idx, Target *target, } PlatformSP platform_sp(target->GetPlatform()); if (platform_sp) - strm.Printf("%splatform=%s", properties++ > 0 ? ", " : " ( ", - platform_sp->GetName().GetCString()); + strm.Format("{0}platform={1}", properties++ > 0 ? ", " : " ( ", + platform_sp->GetName()); ProcessSP process_sp(target->GetProcessSP()); bool show_process_status = false; @@ -135,7 +138,7 @@ static uint32_t DumpTargetList(TargetList &target_list, // Note that the negation in the argument name causes a slightly confusing // mapping of the enum values. -static constexpr OptionEnumValueElement g_dependents_enumaration[] = { +static constexpr OptionEnumValueElement g_dependents_enumeration[] = { { eLoadDependentsDefault, "default", @@ -296,12 +299,6 @@ protected: const char *file_path = command.GetArgumentAtIndex(0); LLDB_SCOPED_TIMERF("(lldb) target create '%s'", file_path); - FileSpec file_spec; - - if (file_path) { - file_spec.SetFile(file_path, FileSpec::Style::native); - FileSystem::Instance().Resolve(file_spec); - } bool must_set_platform_path = false; @@ -330,6 +327,18 @@ protected: PlatformSP platform_sp = target_sp->GetPlatform(); + FileSpec file_spec; + if (file_path) { + file_spec.SetFile(file_path, FileSpec::Style::native); + FileSystem::Instance().Resolve(file_spec); + + // Try to resolve the exe based on PATH and/or platform-specific + // suffixes, but only if using the host platform. + if (platform_sp && platform_sp->IsHost() && + !FileSystem::Instance().Exists(file_spec)) + FileSystem::Instance().ResolveExecutableLocation(file_spec); + } + if (remote_file) { if (platform_sp) { // I have a remote file.. two possible cases @@ -356,10 +365,29 @@ protected: return false; } } else { - // make up a local file - result.AppendError("remote --> local transfer without local " + // If the remote file exists, we can debug reading that out of + // memory. If the platform is already connected to an lldb-server + // then we can at least check the file exists remotely. Otherwise + // we'll just have to trust that it will be there when we do + // process connect. + // I don't do this for the host platform because it seems odd to + // support supplying a remote file but no local file for a local + // debug session. + if (platform_sp->IsHost()) { + result.AppendError("Supply a local file, not a remote file, " + "when debugging on the host."); + return false; + } + if (platform_sp->IsConnected() && !platform_sp->GetFileExists(remote_file)) { + result.AppendError("remote --> local transfer without local " "path is not implemented yet"); - return false; + return false; + } + // Since there's only a remote file, we need to set the executable + // file spec to the remote one. + ProcessLaunchInfo launch_info = target_sp->GetProcessLaunchInfo(); + launch_info.SetExecutableFile(FileSpec(remote_file), true); + target_sp->SetProcessLaunchInfo(launch_info); } } } else { @@ -459,18 +487,14 @@ public: protected: bool DoExecute(Args &args, CommandReturnObject &result) override { - if (args.GetArgumentCount() == 0) { - Stream &strm = result.GetOutputStream(); + Stream &strm = result.GetOutputStream(); - bool show_stopped_process_status = false; - if (DumpTargetList(GetDebugger().GetTargetList(), - show_stopped_process_status, strm) == 0) { - strm.PutCString("No targets.\n"); - } - result.SetStatus(eReturnStatusSuccessFinishResult); - } else { - result.AppendError("the 'target list' command takes no arguments\n"); + bool show_stopped_process_status = false; + if (DumpTargetList(GetDebugger().GetTargetList(), + show_stopped_process_status, strm) == 0) { + strm.PutCString("No targets.\n"); } + result.SetStatus(eReturnStatusSuccessFinishResult); return result.Succeeded(); } }; @@ -483,6 +507,8 @@ public: : CommandObjectParsed( interpreter, "target select", "Select a target as the current target by target index.", nullptr) { + CommandArgumentData target_arg{eArgTypeTargetID, eArgRepeatPlain}; + m_arguments.push_back({target_arg}); } ~CommandObjectTargetSelect() override = default; @@ -547,6 +573,8 @@ public: m_option_group.Append(&m_all_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); m_option_group.Append(&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); m_option_group.Finalize(); + CommandArgumentData target_arg{eArgTypeTargetID, eArgRepeatStar}; + m_arguments.push_back({target_arg}); } ~CommandObjectTargetDelete() override = default; @@ -970,11 +998,8 @@ protected: } } - if (m_interpreter.TruncationWarningNecessary()) { - result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(), - m_cmd_name.c_str()); - m_interpreter.TruncationWarningGiven(); - } + m_interpreter.PrintWarningsIfNecessary(result.GetOutputStream(), + m_cmd_name); return result.Succeeded(); } @@ -1034,7 +1059,7 @@ protected: const char *to = command.GetArgumentAtIndex(i + 1); if (from[0] && to[0]) { - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + Log *log = GetLog(LLDBLog::Host); if (log) { LLDB_LOGF(log, "target modules search path adding ImageSearchPath " @@ -1205,10 +1230,6 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { Target *target = &GetSelectedTarget(); - if (command.GetArgumentCount() != 0) { - result.AppendError("list takes no arguments\n"); - return result.Succeeded(); - } target->GetImageSearchPathList().Dump(&result.GetOutputStream()); result.SetStatus(eReturnStatusSuccessFinishResult); @@ -1428,7 +1449,8 @@ static bool DumpModuleSymbolFile(Stream &strm, Module *module) { } static void DumpAddress(ExecutionContextScope *exe_scope, - const Address &so_addr, bool verbose, Stream &strm) { + const Address &so_addr, bool verbose, bool all_ranges, + Stream &strm) { strm.IndentMore(); strm.Indent(" Address: "); so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress); @@ -1443,7 +1465,8 @@ static void DumpAddress(ExecutionContextScope *exe_scope, // Print out detailed address information when verbose is enabled if (verbose) { strm.EOL(); - so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext); + so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext, + Address::DumpStyleInvalid, UINT32_MAX, all_ranges); } strm.IndentLess(); } @@ -1451,7 +1474,7 @@ static void DumpAddress(ExecutionContextScope *exe_scope, static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm, Module *module, uint32_t resolve_mask, lldb::addr_t raw_addr, lldb::addr_t offset, - bool verbose) { + bool verbose, bool all_ranges) { if (module) { lldb::addr_t addr = raw_addr - offset; Address so_addr; @@ -1469,7 +1492,7 @@ static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm, ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope(); - DumpAddress(exe_scope, so_addr, verbose, strm); + DumpAddress(exe_scope, so_addr, verbose, all_ranges, strm); // strm.IndentMore(); // strm.Indent (" Address: "); // so_addr.Dump (&strm, exe_scope, @@ -1501,7 +1524,7 @@ static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm, static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, - bool verbose) { + bool verbose, bool all_ranges) { if (!module) return 0; @@ -1534,7 +1557,7 @@ static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter, if (symbol && symbol->ValueIsAddress()) { DumpAddress( interpreter.GetExecutionContext().GetBestExecutionContextScope(), - symbol->GetAddressRef(), verbose, strm); + symbol->GetAddressRef(), verbose, all_ranges, strm); } } strm.IndentLess(); @@ -1544,7 +1567,7 @@ static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter, static void DumpSymbolContextList(ExecutionContextScope *exe_scope, Stream &strm, SymbolContextList &sc_list, - bool verbose) { + bool verbose, bool all_ranges) { strm.IndentMore(); const uint32_t num_matches = sc_list.GetSize(); @@ -1556,7 +1579,7 @@ static void DumpSymbolContextList(ExecutionContextScope *exe_scope, sc.GetAddressRange(eSymbolContextEverything, 0, true, range); - DumpAddress(exe_scope, range.GetBaseAddress(), verbose, strm); + DumpAddress(exe_scope, range.GetBaseAddress(), verbose, all_ranges, strm); } } strm.IndentLess(); @@ -1566,7 +1589,7 @@ static size_t LookupFunctionInModule(CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, const ModuleFunctionSearchOptions &options, - bool verbose) { + bool verbose, bool all_ranges) { if (module && name && name[0]) { SymbolContextList sc_list; size_t num_matches = 0; @@ -1587,7 +1610,7 @@ static size_t LookupFunctionInModule(CommandInterpreter &interpreter, strm.PutCString(":\n"); DumpSymbolContextList( interpreter.GetExecutionContext().GetBestExecutionContextScope(), - strm, sc_list, verbose); + strm, sc_list, verbose, all_ranges); } return num_matches; } @@ -1692,7 +1715,7 @@ static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter, Stream &strm, Module *module, const FileSpec &file_spec, uint32_t line, bool check_inlines, - bool verbose) { + bool verbose, bool all_ranges) { if (module && file_spec) { SymbolContextList sc_list; const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec( @@ -1709,7 +1732,7 @@ static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter, strm.PutCString(":\n"); DumpSymbolContextList( interpreter.GetExecutionContext().GetBestExecutionContextScope(), - strm, sc_list, verbose); + strm, sc_list, verbose, all_ranges); return num_matches; } } @@ -1932,7 +1955,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -2427,6 +2450,8 @@ public: LLDB_OPT_SET_1); m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); m_option_group.Finalize(); + CommandArgumentData module_arg{eArgTypePath, eArgRepeatStar}; + m_arguments.push_back({module_arg}); } ~CommandObjectTargetModulesAdd() override = default; @@ -2460,7 +2485,8 @@ protected: if (m_symbol_file.GetOptionValue().OptionWasSet()) module_spec.GetSymbolFileSpec() = m_symbol_file.GetOptionValue().GetCurrentValue(); - if (Symbols::DownloadObjectAndSymbolFile(module_spec)) { + Status error; + if (Symbols::DownloadObjectAndSymbolFile(module_spec, error)) { ModuleSP module_sp( target->GetOrCreateModule(module_spec, true /* notify */)); if (module_sp) { @@ -2496,6 +2522,7 @@ protected: result.AppendErrorWithFormat( "Unable to locate the executable or symbol file with UUID %s", strm.GetData()); + result.SetError(error); return false; } } else { @@ -2837,7 +2864,7 @@ class CommandObjectTargetModulesList : public CommandObjectParsed { public: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -2879,8 +2906,10 @@ public: CommandObjectTargetModulesList(CommandInterpreter &interpreter) : CommandObjectParsed( interpreter, "target modules list", - "List current executable and dependent shared library images.", - "target modules list [<cmd-options>]") {} + "List current executable and dependent shared library images.") { + CommandArgumentData module_arg{eArgTypeShlibName, eArgRepeatStar}; + m_arguments.push_back({module_arg}); + } ~CommandObjectTargetModulesList() override = default; @@ -3179,7 +3208,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -3597,6 +3626,10 @@ public: case 'r': m_use_regex = true; break; + + case '\x01': + m_all_ranges = true; + break; default: llvm_unreachable("Unimplemented option"); } @@ -3613,10 +3646,20 @@ public: m_line_number = 0; m_use_regex = false; m_include_inlines = true; + m_all_ranges = false; m_verbose = false; m_print_all = false; } + Status OptionParsingFinished(ExecutionContext *execution_context) override { + Status status; + if (m_all_ranges && !m_verbose) { + status.SetErrorString("--show-variable-ranges must be used in " + "conjunction with --verbose."); + } + return status; + } + llvm::ArrayRef<OptionDefinition> GetDefinitions() override { return llvm::makeArrayRef(g_target_modules_lookup_options); } @@ -3631,6 +3674,7 @@ public: bool m_use_regex; // Name lookups in m_str are regular expressions. bool m_include_inlines; // Check for inline entries when looking up by // file/line. + bool m_all_ranges; // Print all ranges or single range. bool m_verbose; // Enable verbose lookup info bool m_print_all; // Print all matches, even in cases where there's a best // match. @@ -3713,7 +3757,8 @@ public: (m_options.m_verbose ? static_cast<int>(eSymbolContextVariable) : 0), - m_options.m_addr, m_options.m_offset, m_options.m_verbose)) { + m_options.m_addr, m_options.m_offset, m_options.m_verbose, + m_options.m_all_ranges)) { result.SetStatus(eReturnStatusSuccessFinishResult); return true; } @@ -3724,7 +3769,8 @@ public: if (!m_options.m_str.empty()) { if (LookupSymbolInModule(m_interpreter, result.GetOutputStream(), module, m_options.m_str.c_str(), - m_options.m_use_regex, m_options.m_verbose)) { + m_options.m_use_regex, m_options.m_verbose, + m_options.m_all_ranges)) { result.SetStatus(eReturnStatusSuccessFinishResult); return true; } @@ -3736,7 +3782,8 @@ public: if (LookupFileAndLineInModule( m_interpreter, result.GetOutputStream(), module, m_options.m_file, m_options.m_line_number, - m_options.m_include_inlines, m_options.m_verbose)) { + m_options.m_include_inlines, m_options.m_verbose, + m_options.m_all_ranges)) { result.SetStatus(eReturnStatusSuccessFinishResult); return true; } @@ -3754,7 +3801,8 @@ public: if (LookupFunctionInModule(m_interpreter, result.GetOutputStream(), module, m_options.m_str.c_str(), m_options.m_use_regex, function_options, - m_options.m_verbose)) { + m_options.m_verbose, + m_options.m_all_ranges)) { result.SetStatus(eReturnStatusSuccessFinishResult); return true; } @@ -3774,7 +3822,7 @@ public: default: m_options.GenerateOptionUsage( - result.GetErrorStream(), this, + result.GetErrorStream(), *this, GetCommandInterpreter().GetDebugger().GetTerminalWidth()); syntax_error = true; break; @@ -3969,6 +4017,8 @@ public: m_option_group.Append(&m_current_stack_option, LLDB_OPT_SET_2, LLDB_OPT_SET_2); m_option_group.Finalize(); + CommandArgumentData module_arg{eArgTypeShlibName, eArgRepeatPlain}; + m_arguments.push_back({module_arg}); } ~CommandObjectTargetSymbolsAdd() override = default; @@ -4142,10 +4192,13 @@ protected: bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec, CommandReturnObject &result, bool &flush) { - if (Symbols::DownloadObjectAndSymbolFile(module_spec)) { + Status error; + if (Symbols::DownloadObjectAndSymbolFile(module_spec, error)) { if (module_spec.GetSymbolFileSpec()) return AddModuleSymbols(m_exe_ctx.GetTargetPtr(), module_spec, flush, result); + } else { + result.SetError(error); } return false; } @@ -4814,7 +4867,10 @@ public: CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter) : CommandObjectParsed(interpreter, "target stop-hook delete", "Delete a stop-hook.", - "target stop-hook delete [<idx>]") {} + "target stop-hook delete [<idx>]") { + CommandArgumentData hook_arg{eArgTypeStopHookID, eArgRepeatStar}; + m_arguments.push_back({hook_arg}); + } ~CommandObjectTargetStopHookDelete() override = default; @@ -4868,6 +4924,8 @@ public: bool enable, const char *name, const char *help, const char *syntax) : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) { + CommandArgumentData hook_arg{eArgTypeStopHookID, eArgRepeatStar}; + m_arguments.push_back({hook_arg}); } ~CommandObjectTargetStopHookEnableDisable() override = default; @@ -4923,8 +4981,7 @@ class CommandObjectTargetStopHookList : public CommandObjectParsed { public: CommandObjectTargetStopHookList(CommandInterpreter &interpreter) : CommandObjectParsed(interpreter, "target stop-hook list", - "List all stop-hooks.", - "target stop-hook list [<type>]") {} + "List all stop-hooks.", "target stop-hook list") {} ~CommandObjectTargetStopHookList() override = default; @@ -4996,11 +5053,6 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - if (!command.empty()) { - result.AppendError("target dump typesystem doesn't take arguments."); - return result.Succeeded(); - } - // Go over every scratch TypeSystem and dump to the command output. for (TypeSystem *ts : GetSelectedTarget().GetScratchTypeSystems()) ts->Dump(result.GetOutputStream().AsRawOstream()); diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.cpp index f6042937a4ff..993523e06736 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.cpp @@ -33,7 +33,7 @@ #include "lldb/Target/ThreadPlan.h" #include "lldb/Target/ThreadPlanStepInRange.h" #include "lldb/Target/Trace.h" -#include "lldb/Target/TraceInstructionDumper.h" +#include "lldb/Target/TraceDumper.h" #include "lldb/Utility/State.h" using namespace lldb; @@ -125,6 +125,58 @@ public: Options *GetOptions() override { return &m_options; } + llvm::Optional<std::string> GetRepeatCommand(Args ¤t_args, + uint32_t idx) override { + llvm::StringRef count_opt("--count"); + llvm::StringRef start_opt("--start"); + + // If no "count" was provided, we are dumping the entire backtrace, so + // there isn't a repeat command. So we search for the count option in + // the args, and if we find it, we make a copy and insert or modify the + // start option's value to start count indices greater. + + Args copy_args(current_args); + size_t num_entries = copy_args.GetArgumentCount(); + // These two point at the index of the option value if found. + size_t count_idx = 0; + size_t start_idx = 0; + size_t count_val = 0; + size_t start_val = 0; + + for (size_t idx = 0; idx < num_entries; idx++) { + llvm::StringRef arg_string = copy_args[idx].ref(); + if (arg_string.equals("-c") || count_opt.startswith(arg_string)) { + idx++; + if (idx == num_entries) + return llvm::None; + count_idx = idx; + if (copy_args[idx].ref().getAsInteger(0, count_val)) + return llvm::None; + } else if (arg_string.equals("-s") || start_opt.startswith(arg_string)) { + idx++; + if (idx == num_entries) + return llvm::None; + start_idx = idx; + if (copy_args[idx].ref().getAsInteger(0, start_val)) + return llvm::None; + } + } + if (count_idx == 0) + return llvm::None; + + std::string new_start_val = llvm::formatv("{0}", start_val + count_val); + if (start_idx == 0) { + copy_args.AppendArgument(start_opt); + copy_args.AppendArgument(new_start_val); + } else { + copy_args.ReplaceArgumentAtIndex(start_idx, new_start_val); + } + std::string repeat_command; + if (!copy_args.GetQuotedCommandString(repeat_command)) + return llvm::None; + return repeat_command; + } + protected: void DoExtendedBacktrace(Thread *thread, CommandReturnObject &result) { SystemRuntime *runtime = thread->GetProcess()->GetSystemRuntime(); @@ -932,8 +984,8 @@ protected: thread->GetStackFrameAtIndex(m_options.m_frame_idx).get(); if (frame == nullptr) { result.AppendErrorWithFormat( - "Frame index %u is out of range for thread %u.\n", - m_options.m_frame_idx, m_options.m_thread_idx); + "Frame index %u is out of range for thread id %" PRIu64 ".\n", + m_options.m_frame_idx, thread->GetID()); return false; } @@ -950,9 +1002,8 @@ protected: if (line_table == nullptr) { result.AppendErrorWithFormat("Failed to resolve the line table for " - "frame %u of thread index %u.\n", - m_options.m_frame_idx, - m_options.m_thread_idx); + "frame %u of thread id %" PRIu64 ".\n", + m_options.m_frame_idx, thread->GetID()); return false; } @@ -960,7 +1011,14 @@ protected: uint32_t index_ptr = 0, end_ptr; std::vector<addr_t> address_list; - // Find the beginning & end index of the + // Find the beginning & end index of the function, but first make + // sure it is valid: + if (!sc.function) { + result.AppendErrorWithFormat("Have debug information but no " + "function info - can't get until range."); + return false; + } + AddressRange fun_addr_range = sc.function->GetAddressRange(); Address fun_start_addr = fun_addr_range.GetBaseAddress(); line_table->FindLineEntryByAddress(fun_start_addr, function_start, @@ -1031,13 +1089,18 @@ protected: 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.AppendErrorWithFormat("Frame index %u of thread id %" PRIu64 + " has no debug information.\n", + m_options.m_frame_idx, thread->GetID()); return false; } - process->GetThreadList().SetSelectedThreadByID(m_options.m_thread_idx); + if (!process->GetThreadList().SetSelectedThreadByID(thread->GetID())) { + result.AppendErrorWithFormat( + "Failed to set the selected thread to thread id %" PRIu64 ".\n", + thread->GetID()); + return false; + } StreamString stream; Status error; @@ -1973,7 +2036,7 @@ public: unsigned i = 0; for (llvm::StringRef plugin_name = - PluginManager::GetTraceExporterPluginNameAtIndex(i++); + PluginManager::GetTraceExporterPluginNameAtIndex(i); !plugin_name.empty(); plugin_name = PluginManager::GetTraceExporterPluginNameAtIndex(i++)) { if (ThreadTraceExportCommandCreator command_creator = @@ -2040,8 +2103,7 @@ public: #define LLDB_OPTIONS_thread_trace_dump_instructions #include "CommandOptions.inc" -class CommandObjectTraceDumpInstructions - : public CommandObjectIterateOverThreads { +class CommandObjectTraceDumpInstructions : public CommandObjectParsed { public: class CommandOptions : public Options { public: @@ -2066,6 +2128,10 @@ public: m_count = count; break; } + case 'a': { + m_count = std::numeric_limits<decltype(m_count)>::max(); + break; + } case 's': { int32_t skip; if (option_arg.empty() || option_arg.getAsInteger(0, skip) || skip < 0) @@ -2073,19 +2139,50 @@ public: "invalid integer value for option '%s'", option_arg.str().c_str()); else - m_skip = skip; + m_dumper_options.skip = skip; + break; + } + case 'i': { + uint64_t id; + if (option_arg.empty() || option_arg.getAsInteger(0, id)) + error.SetErrorStringWithFormat( + "invalid integer value for option '%s'", + option_arg.str().c_str()); + else + m_dumper_options.id = id; + break; + } + case 'F': { + m_output_file.emplace(option_arg); break; } case 'r': { - m_raw = true; + m_dumper_options.raw = true; break; } case 'f': { - m_forwards = true; + m_dumper_options.forwards = true; break; } case 't': { - m_show_tsc = true; + m_dumper_options.show_tsc = true; + break; + } + case 'e': { + m_dumper_options.show_events = true; + break; + } + case 'j': { + m_dumper_options.json = true; + break; + } + case 'J': { + m_dumper_options.pretty_print_json = true; + m_dumper_options.json = true; + break; + } + case 'C': { + m_continue = true; break; } default: @@ -2096,10 +2193,9 @@ public: void OptionParsingStarting(ExecutionContext *execution_context) override { m_count = kDefaultCount; - m_skip = 0; - m_raw = false; - m_forwards = false; - m_show_tsc = false; + m_continue = false; + m_output_file = llvm::None; + m_dumper_options = {}; } llvm::ArrayRef<OptionDefinition> GetDefinitions() override { @@ -2110,92 +2206,113 @@ public: // Instance variables to hold the values for command options. size_t m_count; - size_t m_skip; - bool m_raw; - bool m_forwards; - bool m_show_tsc; + size_t m_continue; + llvm::Optional<FileSpec> m_output_file; + TraceDumperOptions m_dumper_options; }; CommandObjectTraceDumpInstructions(CommandInterpreter &interpreter) - : CommandObjectIterateOverThreads( + : CommandObjectParsed( interpreter, "thread trace dump instructions", - "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.", + "Dump the traced instructions for one thread. If no " + "thread is specified, show the current thread.", nullptr, - eCommandRequiresProcess | eCommandTryTargetAPILock | - eCommandProcessMustBeLaunched | eCommandProcessMustBePaused | - eCommandProcessMustBeTraced), - m_create_repeat_command_just_invoked(false) {} + eCommandRequiresProcess | eCommandRequiresThread | + eCommandTryTargetAPILock | eCommandProcessMustBeLaunched | + eCommandProcessMustBePaused | eCommandProcessMustBeTraced) { + CommandArgumentData thread_arg{eArgTypeThreadIndex, eArgRepeatOptional}; + m_arguments.push_back({thread_arg}); + } ~CommandObjectTraceDumpInstructions() override = default; Options *GetOptions() override { return &m_options; } - const char *GetRepeatCommand(Args ¤t_command_args, - uint32_t index) override { - current_command_args.GetCommandString(m_repeat_command); - m_create_repeat_command_just_invoked = true; - return m_repeat_command.c_str(); + llvm::Optional<std::string> GetRepeatCommand(Args ¤t_command_args, + uint32_t index) override { + std::string cmd; + current_command_args.GetCommandString(cmd); + if (cmd.find(" --continue") == std::string::npos) + cmd += " --continue"; + return cmd; } protected: - bool DoExecute(Args &args, CommandReturnObject &result) override { - if (!IsRepeatCommand()) - m_dumpers.clear(); - - bool status = CommandObjectIterateOverThreads::DoExecute(args, result); + ThreadSP GetThread(Args &args, CommandReturnObject &result) { + if (args.GetArgumentCount() == 0) + return m_exe_ctx.GetThreadSP(); - m_create_repeat_command_just_invoked = false; - return status; - } + const char *arg = args.GetArgumentAtIndex(0); + uint32_t thread_idx; - bool IsRepeatCommand() { - return !m_repeat_command.empty() && !m_create_repeat_command_just_invoked; + if (!llvm::to_integer(arg, thread_idx)) { + result.AppendErrorWithFormat("invalid thread specification: \"%s\"\n", + arg); + return nullptr; + } + ThreadSP thread_sp = + m_exe_ctx.GetProcessRef().GetThreadList().FindThreadByIndexID( + thread_idx); + if (!thread_sp) + result.AppendErrorWithFormat("no thread with index: \"%s\"\n", arg); + return thread_sp; } - bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override { - Stream &s = result.GetOutputStream(); + bool DoExecute(Args &args, CommandReturnObject &result) override { + ThreadSP thread_sp = GetThread(args, result); + if (!thread_sp) { + result.AppendError("invalid thread\n"); + return false; + } - const TraceSP &trace_sp = m_exe_ctx.GetTargetSP()->GetTrace(); - ThreadSP thread_sp = - m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid); + if (m_options.m_continue && m_last_id) { + // We set up the options to continue one instruction past where + // the previous iteration stopped. + m_options.m_dumper_options.skip = 1; + m_options.m_dumper_options.id = m_last_id; + } - 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); - }; + llvm::Expected<TraceCursorUP> cursor_or_error = + m_exe_ctx.GetTargetSP()->GetTrace()->CreateNewCursor(*thread_sp); - int initial_index = setUpCursor(); + if (!cursor_or_error) { + result.AppendError(llvm::toString(cursor_or_error.takeError())); + return false; + } + TraceCursorUP &cursor_up = *cursor_or_error; - auto dumper = std::make_unique<TraceInstructionDumper>( - std::move(cursor_up), initial_index, m_options.m_raw, - m_options.m_show_tsc); + if (m_options.m_dumper_options.id && + !cursor_up->HasId(*m_options.m_dumper_options.id)) { + result.AppendError("invalid instruction id\n"); + return false; + } - // 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(); + llvm::Optional<StreamFile> out_file; + if (m_options.m_output_file) { + out_file.emplace(m_options.m_output_file->GetPath().c_str(), + File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate, + lldb::eFilePermissionsFileDefault); + } - m_dumpers[thread_sp->GetID()] = std::move(dumper); + if (m_options.m_continue && !m_last_id) { + // We need to stop processing data when we already ran out of instructions + // in a previous command. We can fake this by setting the cursor past the + // end of the trace. + cursor_up->Seek(1, TraceCursor::SeekType::End); } - m_dumpers[thread_sp->GetID()]->DumpInstructions(s, m_options.m_count); + TraceDumper dumper(std::move(cursor_up), + out_file ? *out_file : result.GetOutputStream(), + m_options.m_dumper_options); + + m_last_id = dumper.DumpInstructions(m_options.m_count); return true; } CommandOptions m_options; - - // Repeat command helpers - std::string m_repeat_command; - bool m_create_repeat_command_just_invoked; - std::map<lldb::tid_t, std::unique_ptr<TraceInstructionDumper>> m_dumpers; + // Last traversed id used to continue a repeat command. None means + // that all the trace has been consumed. + llvm::Optional<lldb::user_id_t> m_last_id; }; // CommandObjectTraceDumpInfo @@ -2249,7 +2366,7 @@ public: : 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 " + "threads are specified, show the current thread. Use the " "thread-index \"all\" to see all threads.", nullptr, eCommandRequiresProcess | eCommandTryTargetAPILock | diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.cpp index d330da7e684e..504d5fa0118d 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.cpp @@ -19,7 +19,20 @@ using namespace llvm; CommandObjectIterateOverThreads::CommandObjectIterateOverThreads( CommandInterpreter &interpreter, const char *name, const char *help, const char *syntax, uint32_t flags) - : CommandObjectParsed(interpreter, name, help, syntax, flags) {} + : CommandObjectParsed(interpreter, name, help, syntax, flags) { + // These commands all take thread ID's as arguments. + CommandArgumentData thread_arg{eArgTypeThreadIndex, eArgRepeatStar}; + m_arguments.push_back({thread_arg}); +} + +CommandObjectMultipleThreads::CommandObjectMultipleThreads( + CommandInterpreter &interpreter, const char *name, const char *help, + const char *syntax, uint32_t flags) + : CommandObjectParsed(interpreter, name, help, syntax, flags) { + // These commands all take thread ID's as arguments. + CommandArgumentData thread_arg{eArgTypeThreadIndex, eArgRepeatStar}; + m_arguments.push_back({thread_arg}); +} bool CommandObjectIterateOverThreads::DoExecute(Args &command, CommandReturnObject &result) { diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.h index 289ffdfc1894..c8f51eabc043 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.h @@ -80,7 +80,9 @@ protected: /// an action on multiple threads at once instead of iterating over each thread. class CommandObjectMultipleThreads : public CommandObjectParsed { public: - using CommandObjectParsed::CommandObjectParsed; + CommandObjectMultipleThreads(CommandInterpreter &interpreter, + const char *name, const char *help, + const char *syntax, uint32_t flags); bool DoExecute(Args &command, CommandReturnObject &result) override; diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.cpp index 53f1b0a32e60..17aded9ed2a0 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.cpp @@ -72,9 +72,13 @@ public: }; CommandObjectTraceLoad(CommandInterpreter &interpreter) - : CommandObjectParsed(interpreter, "trace load", - "Load a processor trace session from a JSON file.", - "trace load") {} + : CommandObjectParsed( + interpreter, "trace load", + "Load a post-mortem processor trace session from a trace bundle.", + "trace load") { + CommandArgumentData session_file_arg{eArgTypePath, eArgRepeatPlain}; + m_arguments.push_back({session_file_arg}); + } ~CommandObjectTraceLoad() override = default; @@ -83,43 +87,27 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { if (command.size() != 1) { - result.AppendError( - "a single path to a JSON file containing a trace session" - "is required"); + result.AppendError("a single path to a JSON file containing a the " + "description of the trace bundle is required"); return false; } - auto end_with_failure = [&result](llvm::Error err) -> bool { - result.AppendErrorWithFormat("%s\n", - llvm::toString(std::move(err)).c_str()); - return false; - }; + const FileSpec trace_description_file(command[0].ref()); - FileSpec json_file(command[0].ref()); + llvm::Expected<lldb::TraceSP> trace_or_err = + Trace::LoadPostMortemTraceFromFile(GetDebugger(), + trace_description_file); - auto buffer_or_error = llvm::MemoryBuffer::getFile(json_file.GetPath()); - if (!buffer_or_error) { - return end_with_failure(llvm::createStringError( - std::errc::invalid_argument, "could not open input file: %s - %s.", - json_file.GetPath().c_str(), - buffer_or_error.getError().message().c_str())); + if (!trace_or_err) { + result.AppendErrorWithFormat( + "%s\n", llvm::toString(trace_or_err.takeError()).c_str()); + return false; } - llvm::Expected<json::Value> session_file = - json::parse(buffer_or_error.get()->getBuffer().str()); - if (!session_file) - return end_with_failure(session_file.takeError()); - - if (Expected<lldb::TraceSP> traceOrErr = - Trace::FindPluginForPostMortemProcess( - GetDebugger(), *session_file, - json_file.GetDirectory().AsCString())) { - lldb::TraceSP trace_sp = traceOrErr.get(); - if (m_options.m_verbose && trace_sp) - result.AppendMessageWithFormatv("loading trace with plugin {0}\n", - trace_sp->GetPluginName()); - } else - return end_with_failure(traceOrErr.takeError()); + if (m_options.m_verbose) { + result.AppendMessageWithFormatv("loading trace with plugin {0}\n", + trace_or_err.get()->GetPluginName()); + } result.SetStatus(eReturnStatusSuccessFinishResult); return true; @@ -238,7 +226,10 @@ public: : CommandObjectParsed(interpreter, "trace schema", "Show the schema of the given trace plugin.", "trace schema <plug-in>. Use the plug-in name " - "\"all\" to see all schemas.\n") {} + "\"all\" to see all schemas.\n") { + CommandArgumentData plugin_arg{eArgTypeNone, eArgRepeatPlain}; + m_arguments.push_back({plugin_arg}); + } ~CommandObjectTraceSchema() override = default; diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectType.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectType.cpp index f9e1d0f91fb7..3ad3571b390c 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectType.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectType.cpp @@ -286,7 +286,7 @@ class CommandObjectTypeSynthAdd : public CommandObjectParsed, private: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -498,7 +498,7 @@ class CommandObjectTypeFormatAdd : public CommandObjectParsed { private: class CommandOptions : public OptionGroup { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -707,7 +707,7 @@ class CommandObjectTypeFormatterDelete : public CommandObjectParsed { protected: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -872,7 +872,7 @@ class CommandObjectTypeFormatterClear : public CommandObjectParsed { private: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -914,7 +914,10 @@ public: uint32_t formatter_kind_mask, const char *name, const char *help) : CommandObjectParsed(interpreter, name, help, nullptr), - m_formatter_kind_mask(formatter_kind_mask) {} + m_formatter_kind_mask(formatter_kind_mask) { + CommandArgumentData category_arg{eArgTypeName, eArgRepeatOptional}; + m_arguments.push_back({category_arg}); + } ~CommandObjectTypeFormatterClear() override = default; @@ -1337,9 +1340,9 @@ bool CommandObjectTypeSummaryAdd::Execute_ScriptSummary( m_options.m_flags, funct_name_str.c_str(), code.c_str()); } else { // Use an IOHandler to grab Python code from the user - ScriptAddOptions *options = - new ScriptAddOptions(m_options.m_flags, m_options.m_regex, - m_options.m_name, m_options.m_category); + auto options = std::make_unique<ScriptAddOptions>( + m_options.m_flags, m_options.m_regex, m_options.m_name, + m_options.m_category); for (auto &entry : command.entries()) { if (entry.ref().empty()) { @@ -1351,10 +1354,10 @@ bool CommandObjectTypeSummaryAdd::Execute_ScriptSummary( } m_interpreter.GetPythonCommandsFromIOHandler( - " ", // Prompt - *this, // IOHandlerDelegate - options); // Baton for the "io_handler" that will be passed back into - // our IOHandlerDelegate functions + " ", // Prompt + *this, // IOHandlerDelegate + options.release()); // Baton for the "io_handler" that will be passed + // back into our IOHandlerDelegate functions result.SetStatus(eReturnStatusSuccessFinishNoResult); return result.Succeeded(); @@ -1815,7 +1818,7 @@ protected: class CommandObjectTypeCategoryEnable : public CommandObjectParsed { class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -1992,7 +1995,7 @@ protected: class CommandObjectTypeCategoryDisable : public CommandObjectParsed { class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -2252,7 +2255,7 @@ public: bool CommandObjectTypeSynthAdd::Execute_HandwritePython( Args &command, CommandReturnObject &result) { - SynthAddOptions *options = new SynthAddOptions( + auto options = std::make_unique<SynthAddOptions>( m_options.m_skip_pointers, m_options.m_skip_references, m_options.m_cascade, m_options.m_regex, m_options.m_category); @@ -2266,10 +2269,10 @@ bool CommandObjectTypeSynthAdd::Execute_HandwritePython( } m_interpreter.GetPythonCommandsFromIOHandler( - " ", // Prompt - *this, // IOHandlerDelegate - options); // Baton for the "io_handler" that will be passed back into our - // IOHandlerDelegate functions + " ", // Prompt + *this, // IOHandlerDelegate + options.release()); // Baton for the "io_handler" that will be passed back + // into our IOHandlerDelegate functions result.SetStatus(eReturnStatusSuccessFinishNoResult); return result.Succeeded(); } @@ -2405,7 +2408,7 @@ private: typedef std::vector<std::string> option_vector; public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -2661,7 +2664,7 @@ protected: class CommandOptions : public OptionGroup { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectVersion.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectVersion.cpp index e15faba5661e..9b3c9e67a1a7 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectVersion.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectVersion.cpp @@ -23,11 +23,7 @@ CommandObjectVersion::CommandObjectVersion(CommandInterpreter &interpreter) CommandObjectVersion::~CommandObjectVersion() = default; bool CommandObjectVersion::DoExecute(Args &args, CommandReturnObject &result) { - if (args.GetArgumentCount() == 0) { - result.AppendMessageWithFormat("%s\n", lldb_private::GetVersion()); - result.SetStatus(eReturnStatusSuccessFinishResult); - } else { - result.AppendError("the version command takes no arguments."); - } + result.AppendMessageWithFormat("%s\n", lldb_private::GetVersion()); + result.SetStatus(eReturnStatusSuccessFinishResult); return true; } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.cpp index 9701553bdda9..6805ff7f50ae 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.cpp @@ -164,7 +164,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -454,7 +454,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -577,7 +577,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -702,7 +702,7 @@ public: class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; @@ -929,7 +929,7 @@ protected: // We're in business. // Find out the size of this variable. size = m_option_watchpoint.watch_size == 0 - ? valobj_sp->GetByteSize().getValueOr(0) + ? valobj_sp->GetByteSize().value_or(0) : m_option_watchpoint.watch_size; } compiler_type = valobj_sp->GetCompilerType(); diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpointCommand.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpointCommand.cpp index a429e568c61a..0cc83275d7ae 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpointCommand.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpointCommand.cpp @@ -313,7 +313,7 @@ are no syntax errors may indicate that a function was declared but never called. class CommandOptions : public Options { public: - CommandOptions() {} + CommandOptions() = default; ~CommandOptions() override = default; diff --git a/contrib/llvm-project/lldb/source/Commands/Options.td b/contrib/llvm-project/lldb/source/Commands/Options.td index 269c937296d5..7755daa878be 100644 --- a/contrib/llvm-project/lldb/source/Commands/Options.td +++ b/contrib/llvm-project/lldb/source/Commands/Options.td @@ -22,6 +22,9 @@ let Command = "settings set" in { Desc<"Apply the new value to the global default value.">; def setset_force : Option<"force", "f">, Desc<"Force an empty value to be accepted as the default.">; + def setset_exists : Option<"exists", "e">, + Desc<"Set the setting if it exists, but do not cause the command to raise " + "an error if it does not exist.">; } let Command = "settings write" in { @@ -92,7 +95,7 @@ let Command = "breakpoint modify" in { def breakpoint_modify_command : Option<"command", "C">, Group<4>, Arg<"Command">, Desc<"A command to run when the breakpoint is hit, can be provided more " - "than once, the commands will get run in order left to right.">; + "than once, the commands will be run in left-to-right order.">; } let Command = "breakpoint dummy" in { @@ -129,28 +132,28 @@ let Command = "breakpoint set" in { "no matter where the binary eventually loads. Alternately, if you also " "specify the module - with the -s option - then the address will be " "treated as a file address in that module, and resolved accordingly. " - "Again, this will allow lldb to track that offset on subsequent reloads. " - " The module need not have been loaded at the time you specify this " + "Again, this will allow lldb to track that offset on subsequent reloads. " + "The module need not have been loaded at the time you specify this " "breakpoint, and will get resolved when the module is loaded.">; def breakpoint_set_name : Option<"name", "n">, Group<3>, Arg<"FunctionName">, Completion<"Symbol">, Required, Desc<"Set the breakpoint by function name. Can be repeated multiple times " - "to makeone breakpoint for multiple names">; + "to make one breakpoint for multiple names.">; def breakpoint_set_source_regexp_function : Option<"source-regexp-function", "X">, Group<9>, Arg<"FunctionName">, Completion<"Symbol">, Desc<"When used with '-p' limits the source regex to source contained in " - "the namedfunctions. Can be repeated multiple times.">; + "the named functions. Can be repeated multiple times.">; def breakpoint_set_fullname : Option<"fullname", "F">, Group<4>, Arg<"FullName">, Required, Completion<"Symbol">, Desc<"Set the breakpoint by fully qualified function names. For C++ this " "means namespaces and all arguments, and for Objective-C this means a full " - "functionprototype with class and selector. Can be repeated multiple times" + "function prototype with class and selector. Can be repeated multiple times" " to make one breakpoint for multiple names.">; def breakpoint_set_selector : Option<"selector", "S">, Group<5>, Arg<"Selector">, Required, - Desc<"Set the breakpoint by ObjC selector name. Can be repeated multiple " - "times to make one breakpoint for multiple Selectors.">; + Desc<"Set the breakpoint by Objective-C selector name. Can be repeated " + "multiple times to make one breakpoint for multiple Selectors.">; def breakpoint_set_method : Option<"method", "M">, Group<6>, Arg<"Method">, Required, Desc<"Set the breakpoint by C++ method names. Can be repeated " "multiple times to make one breakpoint for multiple methods.">; @@ -160,8 +163,8 @@ let Command = "breakpoint set" in { def breakpoint_set_basename : Option<"basename", "b">, Group<8>, Arg<"FunctionName">, Required, Completion<"Symbol">, Desc<"Set the breakpoint by function basename (C++ namespaces and arguments" - " will beignored). Can be repeated multiple times to make one breakpoint " - "for multiplesymbols.">; + " will be ignored). Can be repeated multiple times to make one breakpoint " + "for multiple symbols.">; def breakpoint_set_source_pattern_regexp : Option<"source-pattern-regexp", "p">, Group<9>, Arg<"RegularExpression">, Required, Desc<"Set the breakpoint by specifying a regular expression which" @@ -332,7 +335,7 @@ let Command = "disassemble" in { Arg<"AddressOrExpression">, Desc<"Disassemble function containing this address.">; def disassemble_options_force : Option<"force", "\\x01">, Groups<[2,3,4,5,7]>, - Desc<"Force dissasembly of large functions.">; + Desc<"Force disassembly of large functions.">; } let Command = "expression" in { @@ -407,7 +410,7 @@ let Command = "frame recognizer add" in { Desc<"If true, only apply this recognizer to frames whose PC currently points to the " "first instruction of the specified function. If false, the recognizer " "will always be applied, regardless of the current position within the specified function. The " - "implementor should keep in mind that some features, e.g. accessing function argument " + "implementer should keep in mind that some features, e.g. accessing function argument " "values via $arg<N>, are not guaranteed to work reliably in this case, so extra care must " "be taken to make the recognizer operate correctly. Defaults to true.">; } @@ -425,11 +428,13 @@ let Command = "history" in { Desc<"Clears the current command history.">; } -let Command = "log" in { +let Command = "log enable" in { def log_file : Option<"file", "f">, Group<1>, Arg<"Filename">, Desc<"Set the destination file to log to.">; - def log_threadsafe : Option<"threadsafe", "t">, Group<1>, - Desc<"Enable thread safe logging to avoid interweaved log lines.">; + def log_handler : Option<"log-handler", "h">, Group<1>, + EnumArg<"LogHandler", "LogHandlerType()">, Desc<"Specify a log handler which determines where log messages are written.">; + def log_buffer_size : Option<"buffer", "b">, Group<1>, Arg<"UnsignedInteger">, + Desc<"Set the log to be buffered, using the specified buffer size, if supported by the log handler.">; def log_verbose : Option<"verbose", "v">, Group<1>, Desc<"Enable verbose logging.">; def log_sequence : Option<"sequence", "s">, Group<1>, @@ -451,6 +456,11 @@ let Command = "log" in { Desc<"Prepend the names of files and function that generate the logs.">; } +let Command = "log dump" in { + def log_dump_file : Option<"file", "f">, Group<1>, Arg<"Filename">, + Desc<"Set the destination file to dump to.">; +} + let Command = "reproducer dump" in { def reproducer_provider : Option<"provider", "p">, Group<1>, EnumArg<"None", "ReproducerProviderType()">, @@ -488,8 +498,6 @@ let Command = "memory read" in { "display data.">; def memory_read_force : Option<"force", "r">, Groups<[1,2,3]>, Desc<"Necessary if reading over target.max-memory-read-size bytes.">; - def memory_read_show_tags : Option<"show-tags", "\\x01">, Group<1>, - Desc<"Include memory tags in output (does not apply to binary output).">; } let Command = "memory find" in { @@ -512,6 +520,12 @@ let Command = "memory write" in { Desc<"Start writing bytes from an offset within the input file.">; } +let Command = "memory region" in { + def memory_region_all : Option<"all", "a">, Group<2>, Required, + Desc<"Show all memory regions. This is equivalent to starting from address " + "0 and repeating the command. Unmapped areas are included.">; +} + let Command = "memory tag write" in { def memory_write_end_addr : Option<"end-addr", "e">, Group<1>, Arg<"AddressOrExpression">, Desc< @@ -711,9 +725,13 @@ let Command = "process attach" in { } let Command = "process continue" in { - def process_continue_ignore_count : Option<"ignore-count", "i">, + def process_continue_ignore_count : Option<"ignore-count", "i">, Group<1>, Arg<"UnsignedInteger">, Desc<"Ignore <N> crossings of the breakpoint (if it" " exists) for the currently selected thread.">; + def process_continue_run_to_bkpt : Option<"continue-to-bkpt", "b">, Group<2>, + Arg<"BreakpointIDRange">, Desc<"Specify a breakpoint to continue to, temporarily " + "ignoring other breakpoints. Can be specified more than once. " + "The continue action will be done synchronously if this option is specified.">; } let Command = "process detach" in { @@ -735,6 +753,8 @@ let Command = "process load" in { } let Command = "process handle" in { + def process_handle_clear : Option<"clear", "c">, Group<2>, + Desc<"Removes the signals listed from the Target signal handlers">; def process_handle_stop : Option<"stop", "s">, Group<1>, Arg<"Boolean">, Desc<"Whether or not the process should be stopped if the signal is " "received.">; @@ -743,6 +763,10 @@ let Command = "process handle" in { "received.">; def process_handle_pass : Option<"pass", "p">, Group<1>, Arg<"Boolean">, Desc<"Whether or not the signal should be passed to the process.">; + def process_handle_only_target : Option<"target", "t">, Group<1>, + Desc<"Show only the signals with behaviors modified in this target">; + def process_handle_dummy : Option<"dummy", "d">, Group<2>, + Desc<"Also clear the values in the dummy target so they won't be inherited by new targets.">; } let Command = "process status" in { @@ -860,7 +884,7 @@ let Command = "source list" in { let Command = "target dependents" in { def dependents_no_dependents : Option<"no-dependents", "d">, Group<1>, - OptionalEnumArg<"Value", "OptionEnumValues(g_dependents_enumaration)">, + OptionalEnumArg<"Value", "OptionEnumValues(g_dependents_enumeration)">, Desc<"Whether or not to load dependents when creating a target. If the " "option is not specified, the value is implicitly 'default'. If the " "option is specified but without a value, the value is implicitly " @@ -957,6 +981,9 @@ let Command = "target modules lookup" in { def target_modules_lookup_type : Option<"type", "t">, Group<6>, Arg<"Name">, Required, Desc<"Lookup a type by name in the debug symbols in one or more " "target modules.">; + def target_modules_lookup_variables_ranges : Option<"show-variable-ranges", + "\\x01">, GroupRange<1, 6>, Desc<"Dump valid ranges of variables (must be " + "used in conjunction with --verbose">; def target_modules_lookup_verbose : Option<"verbose", "v">, Desc<"Enable verbose lookup information.">; def target_modules_lookup_all : Option<"all", "A">, Desc<"Print all matches, " @@ -1091,7 +1118,8 @@ let Command = "thread plan list" in { } let Command = "thread trace dump instructions" in { - def thread_trace_dump_instructions_forwards: Option<"forwards", "f">, Group<1>, + 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.">; @@ -1099,17 +1127,41 @@ let Command = "thread trace dump instructions" in { Arg<"Count">, 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>, + def thread_trace_dump_instructions_all : Option<"all", "a">, Group<1>, + Desc<"From the starting point of the trace, dump all instructions " + "available.">; + def thread_trace_dump_instructions_id: Option<"id", "i">, Group<1>, + Arg<"Index">, + Desc<"Custom starting instruction id from where to start traversing. This " + "id can be provided in decimal or hexadecimal representation.">; + def thread_trace_dump_instructions_skip: Option<"skip", "s">, Group<1>, Arg<"Index">, - 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">, + Desc<"How many trace items (instructions, errors and events) to skip from " + "the starting position of the trace before starting the traversal.">; + 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_file : Option<"file", "F">, Group<1>, + Arg<"Filename">, + Desc<"Dump the instruction to a file instead of the standard output.">; + def thread_trace_dump_instructions_json: Option<"json", "j">, + Group<1>, + Desc<"Dump in simple JSON format.">; + def thread_trace_dump_instructions_pretty_print: Option<"pretty-json", "J">, + Group<1>, + Desc<"Dump in JSON format but pretty printing the output for easier readability.">; + def thread_trace_dump_instructions_show_tsc : Option<"tsc", "t">, Group<1>, + Desc<"For each instruction, print the corresponding timestamp counter if " + "available.">; + def thread_trace_dump_instructions_show_events : Option<"events", "e">, Group<1>, - Desc<"Dump only instruction address without disassembly nor symbol information.">; - def thread_trace_dump_instructions_show_tsc : Option<"tsc", "t">, + Desc<"Dump the events that happened during the execution of the target.">; + def thread_trace_dump_instructions_continue: Option<"continue", "C">, Group<1>, - Desc<"For each instruction, print the corresponding timestamp counter if available.">; + Desc<"Continue dumping instructions right where the previous invocation of " + "this command was left, or from the beginning if this is the first " + "invocation. The --skip argument is discarded and the other arguments are " + "preserved from the previous invocation when possible.">; } let Command = "thread trace dump info" in { diff --git a/contrib/llvm-project/lldb/source/Core/Address.cpp b/contrib/llvm-project/lldb/source/Core/Address.cpp index 122bed924b42..b84e1ac8e169 100644 --- a/contrib/llvm-project/lldb/source/Core/Address.cpp +++ b/contrib/llvm-project/lldb/source/Core/Address.cpp @@ -22,6 +22,7 @@ #include "lldb/Symbol/Type.h" #include "lldb/Symbol/Variable.h" #include "lldb/Symbol/VariableList.h" +#include "lldb/Target/ABI.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/Process.h" @@ -232,7 +233,7 @@ static size_t ReadCStringFromMemory(ExecutionContextScope *exe_scope, Address::Address(lldb::addr_t abs_addr) : m_section_wp(), m_offset(abs_addr) {} Address::Address(addr_t address, const SectionList *section_list) - : m_section_wp(), m_offset(LLDB_INVALID_ADDRESS) { + : m_section_wp() { ResolveAddressUsingFileSections(address, section_list); } @@ -403,7 +404,8 @@ bool Address::GetDescription(Stream &s, Target &target, } bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, - DumpStyle fallback_style, uint32_t addr_size) const { + DumpStyle fallback_style, uint32_t addr_size, + bool all_ranges) const { // If the section was nullptr, only load address is going to work unless we // are trying to deref a pointer SectionSP section_sp(GetSection()); @@ -720,27 +722,42 @@ bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, bool get_parent_variables = true; bool stop_if_block_is_inlined_function = false; VariableList variable_list; - sc.block->AppendVariables(can_create, get_parent_variables, - stop_if_block_is_inlined_function, - [](Variable *) { return true; }, - &variable_list); - + addr_t file_addr = GetFileAddress(); + sc.block->AppendVariables( + can_create, get_parent_variables, + stop_if_block_is_inlined_function, + [&](Variable *var) { + return var && var->LocationIsValidForAddress(*this); + }, + &variable_list); + ABISP abi = + ABI::FindPlugin(ProcessSP(), module_sp->GetArchitecture()); for (const VariableSP &var_sp : variable_list) { - if (var_sp && var_sp->LocationIsValidForAddress(*this)) { - s->Indent(); - s->Printf(" Variable: id = {0x%8.8" PRIx64 "}, name = \"%s\"", - var_sp->GetID(), var_sp->GetName().GetCString()); - Type *type = var_sp->GetType(); - if (type) - s->Printf(", type = \"%s\"", type->GetName().GetCString()); - else - s->PutCString(", type = <unknown>"); - s->PutCString(", location = "); - var_sp->DumpLocationForAddress(s, *this); - s->PutCString(", decl = "); - var_sp->GetDeclaration().DumpStopContext(s, false); - s->EOL(); - } + s->Indent(); + s->Printf(" Variable: id = {0x%8.8" PRIx64 "}, name = \"%s\"", + var_sp->GetID(), var_sp->GetName().GetCString()); + Type *type = var_sp->GetType(); + if (type) + s->Printf(", type = \"%s\"", type->GetName().GetCString()); + else + s->PutCString(", type = <unknown>"); + s->PutCString(", valid ranges = "); + if (var_sp->GetScopeRange().IsEmpty()) + s->PutCString("<block>"); + else if (all_ranges) { + for (auto range : var_sp->GetScopeRange()) + DumpAddressRange(s->AsRawOstream(), range.GetRangeBase(), + range.GetRangeEnd(), addr_size); + } else if (auto *range = + var_sp->GetScopeRange().FindEntryThatContains( + file_addr)) + DumpAddressRange(s->AsRawOstream(), range->GetRangeBase(), + range->GetRangeEnd(), addr_size); + s->PutCString(", location = "); + var_sp->DumpLocations(s, all_ranges ? LLDB_INVALID_ADDRESS : *this); + s->PutCString(", decl = "); + var_sp->GetDeclaration().DumpStopContext(s, false); + s->EOL(); } } } diff --git a/contrib/llvm-project/lldb/source/Core/AddressResolverFileLine.cpp b/contrib/llvm-project/lldb/source/Core/AddressResolverFileLine.cpp index fb61a6100b0e..8152a57644fa 100644 --- a/contrib/llvm-project/lldb/source/Core/AddressResolverFileLine.cpp +++ b/contrib/llvm-project/lldb/source/Core/AddressResolverFileLine.cpp @@ -14,8 +14,8 @@ #include "lldb/Symbol/LineEntry.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" #include "lldb/lldb-enumerations.h" @@ -40,7 +40,7 @@ AddressResolverFileLine::SearchCallback(SearchFilter &filter, SymbolContextList sc_list; CompileUnit *cu = context.comp_unit; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); // TODO: Handle SourceLocationSpec column information cu->ResolveSymbolContext(m_src_location_spec, eSymbolContextEverything, @@ -61,7 +61,7 @@ AddressResolverFileLine::SearchCallback(SearchFilter &filter, line_start.GetFileAddress(), m_src_location_spec.GetFileSpec().GetFilename().AsCString( "<Unknown>"), - m_src_location_spec.GetLine().getValueOr(0)); + m_src_location_spec.GetLine().value_or(0)); } } } @@ -76,5 +76,5 @@ void AddressResolverFileLine::GetDescription(Stream *s) { 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)); + m_src_location_spec.GetLine().value_or(0)); } diff --git a/contrib/llvm-project/lldb/source/Core/Communication.cpp b/contrib/llvm-project/lldb/source/Core/Communication.cpp index 0ad2751f24f0..f41ce46ede88 100644 --- a/contrib/llvm-project/lldb/source/Core/Communication.cpp +++ b/contrib/llvm-project/lldb/source/Core/Communication.cpp @@ -13,9 +13,9 @@ #include "lldb/Utility/Connection.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Event.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Listener.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" #include "lldb/Utility/Status.h" #include "llvm/ADT/None.h" @@ -47,8 +47,7 @@ Communication::Communication(const char *name) { - LLDB_LOG(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_OBJECT | - LIBLLDB_LOG_COMMUNICATION), + LLDB_LOG(GetLog(LLDBLog::Object | LLDBLog::Communication), "{0} Communication::Communication (name = {1})", this, name); SetEventName(eBroadcastBitDisconnected, "disconnected"); @@ -62,8 +61,7 @@ Communication::Communication(const char *name) } Communication::~Communication() { - LLDB_LOG(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_OBJECT | - LIBLLDB_LOG_COMMUNICATION), + LLDB_LOG(GetLog(LLDBLog::Object | LLDBLog::Communication), "{0} Communication::~Communication (name = {1})", this, GetBroadcasterName().AsCString()); Clear(); @@ -78,7 +76,7 @@ void Communication::Clear() { ConnectionStatus Communication::Connect(const char *url, Status *error_ptr) { Clear(); - LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMUNICATION), + LLDB_LOG(GetLog(LLDBLog::Communication), "{0} Communication::Connect (url = {1})", this, url); lldb::ConnectionSP connection_sp(m_connection_sp); @@ -90,8 +88,8 @@ ConnectionStatus Communication::Connect(const char *url, Status *error_ptr) { } ConnectionStatus Communication::Disconnect(Status *error_ptr) { - LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMUNICATION), - "{0} Communication::Disconnect ()", this); + LLDB_LOG(GetLog(LLDBLog::Communication), "{0} Communication::Disconnect ()", + this); assert((!m_read_thread_enabled || m_read_thread_did_exit) && "Disconnecting while the read thread is running is racy!"); @@ -125,7 +123,7 @@ bool Communication::HasConnection() const { size_t Communication::Read(void *dst, size_t dst_len, const Timeout<std::micro> &timeout, ConnectionStatus &status, Status *error_ptr) { - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMUNICATION); + Log *log = GetLog(LLDBLog::Communication); LLDB_LOG( log, "this = {0}, dst = {1}, dst_len = {2}, timeout = {3}, connection = {4}", @@ -175,7 +173,7 @@ size_t Communication::Write(const void *src, size_t src_len, lldb::ConnectionSP connection_sp(m_connection_sp); std::lock_guard<std::mutex> guard(m_write_mutex); - LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMUNICATION), + LLDB_LOG(GetLog(LLDBLog::Communication), "{0} Communication::Write (src = {1}, src_len = {2}" ") connection = {3}", this, src, (uint64_t)src_len, connection_sp.get()); @@ -206,7 +204,7 @@ bool Communication::StartReadThread(Status *error_ptr) { if (m_read_thread.IsJoinable()) return true; - LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMUNICATION), + LLDB_LOG(GetLog(LLDBLog::Communication), "{0} Communication::StartReadThread ()", this); const std::string thread_name = @@ -215,15 +213,14 @@ bool Communication::StartReadThread(Status *error_ptr) { m_read_thread_enabled = true; m_read_thread_did_exit = false; auto maybe_thread = ThreadLauncher::LaunchThread( - thread_name, Communication::ReadThread, this); + thread_name, [this] { return ReadThread(); }); if (maybe_thread) { m_read_thread = *maybe_thread; } else { if (error_ptr) *error_ptr = Status(maybe_thread.takeError()); else { - LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST), - "failed to launch host thread: {}", + LLDB_LOG(GetLog(LLDBLog::Host), "failed to launch host thread: {}", llvm::toString(maybe_thread.takeError())); } } @@ -238,7 +235,7 @@ bool Communication::StopReadThread(Status *error_ptr) { if (!m_read_thread.IsJoinable()) return true; - LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMUNICATION), + LLDB_LOG(GetLog(LLDBLog::Communication), "{0} Communication::StopReadThread ()", this); m_read_thread_enabled = false; @@ -280,7 +277,7 @@ size_t Communication::GetCachedBytes(void *dst, size_t dst_len) { void Communication::AppendBytesToCache(const uint8_t *bytes, size_t len, bool broadcast, ConnectionStatus status) { - LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMUNICATION), + LLDB_LOG(GetLog(LLDBLog::Communication), "{0} Communication::AppendBytesToCache (src = {1}, src_len = {2}, " "broadcast = {3})", this, bytes, (uint64_t)len, broadcast); @@ -314,12 +311,10 @@ size_t Communication::ReadFromConnection(void *dst, size_t dst_len, bool Communication::ReadThreadIsRunning() { return m_read_thread_enabled; } -lldb::thread_result_t Communication::ReadThread(lldb::thread_arg_t p) { - Communication *comm = (Communication *)p; +lldb::thread_result_t Communication::ReadThread() { + Log *log = GetLog(LLDBLog::Communication); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMUNICATION)); - - LLDB_LOGF(log, "%p Communication::ReadThread () thread starting...", p); + LLDB_LOG(log, "Communication({0}) thread starting...", this); uint8_t buf[1024]; @@ -327,11 +322,11 @@ lldb::thread_result_t Communication::ReadThread(lldb::thread_arg_t p) { ConnectionStatus status = eConnectionStatusSuccess; bool done = false; bool disconnect = false; - while (!done && comm->m_read_thread_enabled) { - size_t bytes_read = comm->ReadFromConnection( + while (!done && m_read_thread_enabled) { + size_t bytes_read = ReadFromConnection( buf, sizeof(buf), std::chrono::seconds(5), status, &error); if (bytes_read > 0 || status == eConnectionStatusEndOfFile) - comm->AppendBytesToCache(buf, bytes_read, true, status); + AppendBytesToCache(buf, bytes_read, true, status); switch (status) { case eConnectionStatusSuccess: @@ -339,12 +334,12 @@ lldb::thread_result_t Communication::ReadThread(lldb::thread_arg_t p) { case eConnectionStatusEndOfFile: done = true; - disconnect = comm->GetCloseOnEOF(); + disconnect = GetCloseOnEOF(); break; case eConnectionStatusError: // Check GetError() for details if (error.GetType() == eErrorTypePOSIX && error.GetError() == EIO) { // EIO on a pipe is usually caused by remote shutdown - disconnect = comm->GetCloseOnEOF(); + disconnect = GetCloseOnEOF(); done = true; } if (error.Fail()) @@ -355,7 +350,7 @@ lldb::thread_result_t Communication::ReadThread(lldb::thread_arg_t p) { // SynchronizeWithReadThread() // The connection returns eConnectionStatusInterrupted only when there is // no input pending to be read, so we can signal that. - comm->BroadcastEvent(eBroadcastBitNoMorePendingInput); + BroadcastEvent(eBroadcastBitNoMorePendingInput); break; case eConnectionStatusNoConnection: // No connection case eConnectionStatusLostConnection: // Lost connection while connected to @@ -369,27 +364,26 @@ lldb::thread_result_t Communication::ReadThread(lldb::thread_arg_t p) { break; } } - log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMUNICATION); - if (log) - LLDB_LOGF(log, "%p Communication::ReadThread () thread exiting...", p); + log = GetLog(LLDBLog::Communication); + LLDB_LOG(log, "Communication({0}) thread exiting...", this); // Handle threads wishing to synchronize with us. { // Prevent new ones from showing up. - comm->m_read_thread_did_exit = true; + m_read_thread_did_exit = true; // Unblock any existing thread waiting for the synchronization signal. - comm->BroadcastEvent(eBroadcastBitNoMorePendingInput); + BroadcastEvent(eBroadcastBitNoMorePendingInput); // Wait for the thread to finish... - std::lock_guard<std::mutex> guard(comm->m_synchronize_mutex); + std::lock_guard<std::mutex> guard(m_synchronize_mutex); // ... and disconnect. if (disconnect) - comm->Disconnect(); + Disconnect(); } // Let clients know that this thread is exiting - comm->BroadcastEvent(eBroadcastBitReadThreadDidExit); + BroadcastEvent(eBroadcastBitReadThreadDidExit); return {}; } diff --git a/contrib/llvm-project/lldb/source/Core/CoreProperties.td b/contrib/llvm-project/lldb/source/Core/CoreProperties.td index c965b51a1d6d..46eeb1b5ed70 100644 --- a/contrib/llvm-project/lldb/source/Core/CoreProperties.td +++ b/contrib/llvm-project/lldb/source/Core/CoreProperties.td @@ -33,6 +33,10 @@ let Definition = "modulelist" in { Global, DefaultUnsignedValue<7>, Desc<"The expiration time in days for a file. When a file hasn't been accessed for the specified amount of days, it is removed from the cache. A value of 0 disables the expiration-based pruning.">; + def LoadSymbolOnDemand: Property<"load-on-demand", "Boolean">, + Global, + DefaultFalse, + Desc<"Enable on demand symbol loading in LLDB. LLDB will load debug info on demand for each module based on various conditions (e.g. matched breakpoint, resolved stack frame addresses and matched global variables/function symbols in symbol table) to improve performance. Please refer to docs/use/ondemand.rst for details.">; } let Definition = "debugger" in { @@ -98,19 +102,19 @@ let Definition = "debugger" in { def StopShowColumnAnsiPrefix: Property<"stop-show-column-ansi-prefix", "String">, Global, DefaultStringValue<"${ansi.underline}">, - Desc<"When displaying the column marker in a color-enabled (i.e. ANSI) terminal, use the ANSI terminal code specified in this format at the immediately before the column to be marked.">; + Desc<"When displaying the column marker in a color-enabled terminal, use the ANSI terminal code specified in this format at the immediately before the column to be marked.">; def StopShowColumnAnsiSuffix: Property<"stop-show-column-ansi-suffix", "String">, Global, DefaultStringValue<"${ansi.normal}">, - Desc<"When displaying the column marker in a color-enabled (i.e. ANSI) terminal, use the ANSI terminal code specified in this format immediately after the column to be marked.">; + Desc<"When displaying the column marker in a color-enabled terminal, use the ANSI terminal code specified in this format immediately after the column to be marked.">; def StopShowLineMarkerAnsiPrefix: Property<"stop-show-line-ansi-prefix", "String">, Global, DefaultStringValue<"${ansi.fg.yellow}">, - Desc<"When displaying the line marker in a color-enabled (i.e. ANSI) terminal, use the ANSI terminal code specified in this format at the immediately before the line to be marked.">; + Desc<"When displaying the line marker in a color-enabled terminal, use the ANSI terminal code specified in this format at the immediately before the line to be marked.">; def StopShowLineMarkerAnsiSuffix: Property<"stop-show-line-ansi-suffix", "String">, Global, DefaultStringValue<"${ansi.normal}">, - Desc<"When displaying the line marker in a color-enabled (i.e. ANSI) terminal, use the ANSI terminal code specified in this format immediately after the line to be marked.">; + Desc<"When displaying the line marker in a color-enabled terminal, use the ANSI terminal code specified in this format immediately after the line to be marked.">; def TerminalWidth: Property<"term-width", "SInt64">, Global, DefaultUnsignedValue<80>, @@ -131,6 +135,18 @@ let Definition = "debugger" in { Global, DefaultTrue, Desc<"Whether to use Ansi color codes or not.">; + def ShowProgress: Property<"show-progress", "Boolean">, + Global, + DefaultTrue, + Desc<"Whether to show progress or not if the debugger's output is an interactive color-enabled terminal.">; + def ShowProgressAnsiPrefix: Property<"show-progress-ansi-prefix", "String">, + Global, + DefaultStringValue<"${ansi.faint}">, + Desc<"When displaying progress in a color-enabled terminal, use the ANSI terminal code specified in this format immediately before the progress message.">; + def ShowProgressAnsiSuffix: Property<"show-progress-ansi-suffix", "String">, + Global, + DefaultStringValue<"${ansi.normal}">, + Desc<"When displaying progress in a color-enabled terminal, use the ANSI terminal code specified in this format immediately after the progress message.">; def UseSourceCache: Property<"use-source-cache", "Boolean">, Global, DefaultTrue, @@ -163,4 +179,12 @@ let Definition = "debugger" in { Global, DefaultFalse, Desc<"If true, LLDB will show suggestions to complete the command the user typed. Suggestions may be accepted using Ctrl-F.">; + def ShowAutosuggestionAnsiPrefix: Property<"show-autosuggestion-ansi-prefix", "String">, + Global, + DefaultStringValue<"${ansi.faint}">, + Desc<"When displaying suggestion in a color-enabled terminal, use the ANSI terminal code specified in this format immediately before the suggestion.">; + def ShowAutosuggestionAnsiSuffix: Property<"show-autosuggestion-ansi-suffix", "String">, + Global, + DefaultStringValue<"${ansi.normal}">, + Desc<"When displaying suggestion in a color-enabled terminal, use the ANSI terminal code specified in this format immediately after the suggestion.">; } diff --git a/contrib/llvm-project/lldb/source/Core/DataFileCache.cpp b/contrib/llvm-project/lldb/source/Core/DataFileCache.cpp index 3f52b925ef46..b38adfda169a 100644 --- a/contrib/llvm-project/lldb/source/Core/DataFileCache.cpp +++ b/contrib/llvm-project/lldb/source/Core/DataFileCache.cpp @@ -12,22 +12,21 @@ #include "lldb/Host/FileSystem.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Utility/DataEncoder.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" #include "llvm/Support/CachePruning.h" #include "llvm/Support/MemoryBuffer.h" -using namespace llvm; using namespace lldb_private; -DataFileCache::DataFileCache(StringRef path) { +DataFileCache::DataFileCache(llvm::StringRef path) { m_cache_dir.SetPath(path); // Prune the cache based off of the LLDB settings each time we create a cache // object. ModuleListProperties &properties = ModuleList::GetGlobalModuleListProperties(); - CachePruningPolicy policy; + llvm::CachePruningPolicy policy; // Only scan once an hour. If we have lots of debug sessions we don't want // to scan this directory too often. A timestamp file is written to the // directory to ensure different processes don't scan the directory too often. @@ -52,19 +51,19 @@ DataFileCache::DataFileCache(StringRef path) { if (m_take_ownership) m_mem_buff_up = std::move(m); }; - Expected<FileCache> cache_or_err = + llvm::Expected<llvm::FileCache> cache_or_err = llvm::localCache("LLDBModuleCache", "lldb-module", path, add_buffer); if (cache_or_err) m_cache_callback = std::move(*cache_or_err); else { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES)); + Log *log = GetLog(LLDBLog::Modules); LLDB_LOG_ERROR(log, cache_or_err.takeError(), "failed to create lldb index cache directory: {0}"); } } std::unique_ptr<llvm::MemoryBuffer> -DataFileCache::GetCachedData(StringRef key) { +DataFileCache::GetCachedData(llvm::StringRef key) { std::lock_guard<std::mutex> guard(m_mutex); const unsigned task = 1; @@ -73,13 +72,14 @@ DataFileCache::GetCachedData(StringRef key) { // call the "add_buffer" lambda function from the constructor which will in // turn take ownership of the member buffer that is passed to the callback and // put it into a member variable. - Expected<AddStreamFn> add_stream_or_err = m_cache_callback(task, key); + llvm::Expected<llvm::AddStreamFn> add_stream_or_err = + m_cache_callback(task, key); m_take_ownership = false; // At this point we either already called the "add_buffer" lambda with // the data or we haven't. We can tell if we got the cached data by checking // the add_stream function pointer value below. if (add_stream_or_err) { - AddStreamFn &add_stream = *add_stream_or_err; + llvm::AddStreamFn &add_stream = *add_stream_or_err; // If the "add_stream" is nullptr, then the data was cached and we already // called the "add_buffer" lambda. If it is valid, then if we were to call // the add_stream function it would cause a cache file to get generated @@ -89,7 +89,7 @@ DataFileCache::GetCachedData(StringRef key) { if (!add_stream) return std::move(m_mem_buff_up); } else { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES)); + Log *log = GetLog(LLDBLog::Modules); LLDB_LOG_ERROR(log, add_stream_or_err.takeError(), "failed to get the cache add stream callback for key: {0}"); } @@ -97,18 +97,20 @@ DataFileCache::GetCachedData(StringRef key) { return std::unique_ptr<llvm::MemoryBuffer>(); } -bool DataFileCache::SetCachedData(StringRef key, llvm::ArrayRef<uint8_t> data) { +bool DataFileCache::SetCachedData(llvm::StringRef key, + llvm::ArrayRef<uint8_t> data) { std::lock_guard<std::mutex> guard(m_mutex); const unsigned task = 2; // If we call this function and the data is cached, it will call the // add_buffer lambda function from the constructor which will ignore the // data. - Expected<AddStreamFn> add_stream_or_err = m_cache_callback(task, key); + llvm::Expected<llvm::AddStreamFn> add_stream_or_err = + m_cache_callback(task, key); // If we reach this code then we either already called the callback with // the data or we haven't. We can tell if we had the cached data by checking // the CacheAddStream function pointer value below. if (add_stream_or_err) { - AddStreamFn &add_stream = *add_stream_or_err; + llvm::AddStreamFn &add_stream = *add_stream_or_err; // If the "add_stream" is nullptr, then the data was cached. If it is // valid, then if we call the add_stream function with a task it will // cause the file to get generated, but we only want to check if the data @@ -117,20 +119,20 @@ bool DataFileCache::SetCachedData(StringRef key, llvm::ArrayRef<uint8_t> data) { // provided, but we won't take ownership of the memory buffer as we just // want to write the data. if (add_stream) { - Expected<std::unique_ptr<CachedFileStream>> file_or_err = + llvm::Expected<std::unique_ptr<llvm::CachedFileStream>> file_or_err = add_stream(task); if (file_or_err) { - CachedFileStream *cfs = file_or_err->get(); + llvm::CachedFileStream *cfs = file_or_err->get(); cfs->OS->write((const char *)data.data(), data.size()); return true; } else { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES)); + Log *log = GetLog(LLDBLog::Modules); LLDB_LOG_ERROR(log, file_or_err.takeError(), "failed to get the cache file stream for key: {0}"); } } } else { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES)); + Log *log = GetLog(LLDBLog::Modules); LLDB_LOG_ERROR(log, add_stream_or_err.takeError(), "failed to get the cache add stream callback for key: {0}"); } @@ -197,21 +199,21 @@ enum SignatureEncoding { eSignatureEnd = 255u, }; -bool CacheSignature::Encode(DataEncoder &encoder) { +bool CacheSignature::Encode(DataEncoder &encoder) const { if (!IsValid()) return false; // Invalid signature, return false! - if (m_uuid.hasValue()) { + if (m_uuid) { llvm::ArrayRef<uint8_t> uuid_bytes = m_uuid->GetBytes(); encoder.AppendU8(eSignatureUUID); encoder.AppendU8(uuid_bytes.size()); encoder.AppendData(uuid_bytes); } - if (m_mod_time.hasValue()) { + if (m_mod_time) { encoder.AppendU8(eSignatureModTime); encoder.AppendU32(*m_mod_time); } - if (m_obj_mod_time.hasValue()) { + if (m_obj_mod_time) { encoder.AppendU8(eSignatureObjectModTime); encoder.AppendU32(*m_obj_mod_time); } @@ -219,7 +221,7 @@ bool CacheSignature::Encode(DataEncoder &encoder) { return true; } -bool CacheSignature::Decode(const DataExtractor &data, +bool CacheSignature::Decode(const lldb_private::DataExtractor &data, lldb::offset_t *offset_ptr) { Clear(); while (uint8_t sig_encoding = data.GetU8(offset_ptr)) { @@ -238,10 +240,14 @@ bool CacheSignature::Decode(const DataExtractor &data, case eSignatureObjectModTime: { uint32_t mod_time = data.GetU32(offset_ptr); if (mod_time > 0) - m_mod_time = mod_time; + m_obj_mod_time = mod_time; } break; case eSignatureEnd: - return true; + // The definition of is valid changed to only be valid if the UUID is + // valid so make sure that if we attempt to decode an old cache file + // that we will fail to decode the cache file if the signature isn't + // considered valid. + return IsValid(); default: break; } @@ -284,7 +290,7 @@ bool ConstStringTable::Encode(DataEncoder &encoder) { return true; } -bool StringTableReader::Decode(const DataExtractor &data, +bool StringTableReader::Decode(const lldb_private::DataExtractor &data, lldb::offset_t *offset_ptr) { llvm::StringRef identifier((const char *)data.GetData(offset_ptr, 4), 4); if (identifier != kStringTableIdentifier) @@ -296,12 +302,12 @@ bool StringTableReader::Decode(const DataExtractor &data, const char *bytes = (const char *)data.GetData(offset_ptr, length); if (bytes == nullptr) return false; - m_data = StringRef(bytes, length); + m_data = llvm::StringRef(bytes, length); return true; } -StringRef StringTableReader::Get(uint32_t offset) const { +llvm::StringRef StringTableReader::Get(uint32_t offset) const { if (offset >= m_data.size()) - return StringRef(); - return StringRef(m_data.data() + offset); + return llvm::StringRef(); + return llvm::StringRef(m_data.data() + offset); } diff --git a/contrib/llvm-project/lldb/source/Core/Debugger.cpp b/contrib/llvm-project/lldb/source/Core/Debugger.cpp index 49cc21b65951..f17cd8856a6d 100644 --- a/contrib/llvm-project/lldb/source/Core/Debugger.cpp +++ b/contrib/llvm-project/lldb/source/Core/Debugger.cpp @@ -9,6 +9,7 @@ #include "lldb/Core/Debugger.h" #include "lldb/Breakpoint/Breakpoint.h" +#include "lldb/Core/DebuggerEvents.h" #include "lldb/Core/FormatEntity.h" #include "lldb/Core/Mangled.h" #include "lldb/Core/ModuleList.h" @@ -43,13 +44,13 @@ #include "lldb/Target/ThreadList.h" #include "lldb/Utility/AnsiTerminal.h" #include "lldb/Utility/Event.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Listener.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Reproducer.h" #include "lldb/Utility/ReproducerProvider.h" #include "lldb/Utility/State.h" #include "lldb/Utility/Stream.h" -#include "lldb/Utility/StreamCallback.h" #include "lldb/Utility/StreamString.h" #if defined(_WIN32) @@ -64,6 +65,7 @@ #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Process.h" +#include "llvm/Support/ThreadPool.h" #include "llvm/Support/Threading.h" #include "llvm/Support/raw_ostream.h" @@ -377,12 +379,44 @@ bool Debugger::SetUseColor(bool b) { return ret; } +bool Debugger::GetShowProgress() const { + const uint32_t idx = ePropertyShowProgress; + return m_collection_sp->GetPropertyAtIndexAsBoolean( + nullptr, idx, g_debugger_properties[idx].default_uint_value != 0); +} + +bool Debugger::SetShowProgress(bool show_progress) { + const uint32_t idx = ePropertyShowProgress; + return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, + show_progress); +} + +llvm::StringRef Debugger::GetShowProgressAnsiPrefix() const { + const uint32_t idx = ePropertyShowProgressAnsiPrefix; + return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, ""); +} + +llvm::StringRef Debugger::GetShowProgressAnsiSuffix() const { + const uint32_t idx = ePropertyShowProgressAnsiSuffix; + return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, ""); +} + bool Debugger::GetUseAutosuggestion() const { const uint32_t idx = ePropertyShowAutosuggestion; return m_collection_sp->GetPropertyAtIndexAsBoolean( nullptr, idx, g_debugger_properties[idx].default_uint_value != 0); } +llvm::StringRef Debugger::GetAutosuggestionAnsiPrefix() const { + const uint32_t idx = ePropertyShowAutosuggestionAnsiPrefix; + return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, ""); +} + +llvm::StringRef Debugger::GetAutosuggestionAnsiSuffix() const { + const uint32_t idx = ePropertyShowAutosuggestionAnsiSuffix; + return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, ""); +} + bool Debugger::GetUseSourceCache() const { const uint32_t idx = ePropertyUseSourceCache; return m_collection_sp->GetPropertyAtIndexAsBoolean( @@ -635,9 +669,9 @@ void Debugger::Destroy(DebuggerSP &debugger_sp) { CommandReturnObject result(debugger_sp->GetUseColor()); cmd_interpreter.SaveTranscript(result); if (result.Succeeded()) - debugger_sp->GetOutputStream() << result.GetOutputData() << '\n'; + (*debugger_sp->GetAsyncOutputStream()) << result.GetOutputData() << '\n'; else - debugger_sp->GetErrorStream() << result.GetErrorData() << '\n'; + (*debugger_sp->GetAsyncErrorStream()) << result.GetErrorData() << '\n'; } debugger_sp->Clear(); @@ -723,8 +757,8 @@ Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) m_forward_listener_sp(), m_clear_once() { m_instance_name.SetString(llvm::formatv("debugger_{0}", GetID()).str()); if (log_callback) - m_log_callback_stream_sp = - std::make_shared<StreamCallback>(log_callback, baton); + m_callback_handler_sp = + std::make_shared<CallbackLogHandler>(log_callback, baton); m_command_interpreter_up->Initialize(); // Always add our default platform to the platform list PlatformSP default_platform_sp(Platform::GetHostPlatform()); @@ -865,7 +899,8 @@ Status Debugger::SetInputString(const char *data) { return result; } - write(fds[WRITE], data, size); + int r = write(fds[WRITE], data, size); + (void)r; // Close the write end of the pipe, so that the command interpreter will exit // when it consumes all the data. llvm::sys::Process::SafelyCloseFileDescriptor(fds[WRITE]); @@ -1041,9 +1076,12 @@ bool Debugger::CheckTopIOHandlerTypes(IOHandler::Type top_type, } void Debugger::PrintAsync(const char *s, size_t len, bool is_stdout) { - lldb_private::StreamFile &stream = - is_stdout ? GetOutputStream() : GetErrorStream(); - m_io_handler_stack.PrintAsync(&stream, s, len); + bool printed = m_io_handler_stack.PrintAsync(s, len, is_stdout); + if (!printed) { + lldb::StreamFileSP stream = + is_stdout ? m_output_stream_sp : m_error_stream_sp; + stream->Write(s, len); + } } ConstString Debugger::GetTopIOHandlerControlSequence(char ch) { @@ -1163,11 +1201,11 @@ bool Debugger::PopIOHandler(const IOHandlerSP &pop_reader_sp) { } StreamSP Debugger::GetAsyncOutputStream() { - return std::make_shared<StreamAsynchronousIO>(*this, true); + return std::make_shared<StreamAsynchronousIO>(*this, true, GetUseColor()); } StreamSP Debugger::GetAsyncErrorStream() { - return std::make_shared<StreamAsynchronousIO>(*this, false); + return std::make_shared<StreamAsynchronousIO>(*this, false, GetUseColor()); } size_t Debugger::GetNumDebuggers() { @@ -1253,38 +1291,8 @@ void Debugger::SetLoggingCallback(lldb::LogOutputCallback log_callback, // For simplicity's sake, I am not going to deal with how to close down any // open logging streams, I just redirect everything from here on out to the // callback. - m_log_callback_stream_sp = - 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; + m_callback_handler_sp = + std::make_shared<CallbackLogHandler>(log_callback, baton); } static void PrivateReportProgress(Debugger &debugger, uint64_t progress_id, @@ -1295,9 +1303,9 @@ static void PrivateReportProgress(Debugger &debugger, uint64_t progress_id, 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))); + EventSP event_sp(new Event( + event_type, new ProgressEventData(progress_id, message, completed, total, + is_debugger_specific))); debugger.GetBroadcaster().BroadcastEvent(event_sp); } @@ -1305,7 +1313,7 @@ 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()) { + if (debugger_id) { // It is debugger specific, grab it and deliver the event if the debugger // still exists. DebuggerSP debugger_sp = FindDebuggerWithID(*debugger_id); @@ -1325,27 +1333,116 @@ void Debugger::ReportProgress(uint64_t progress_id, const std::string &message, } } +static void PrivateReportDiagnostic(Debugger &debugger, + DiagnosticEventData::Type type, + std::string message, + bool debugger_specific) { + uint32_t event_type = 0; + switch (type) { + case DiagnosticEventData::Type::Warning: + event_type = Debugger::eBroadcastBitWarning; + break; + case DiagnosticEventData::Type::Error: + event_type = Debugger::eBroadcastBitError; + break; + } + + Broadcaster &broadcaster = debugger.GetBroadcaster(); + if (!broadcaster.EventTypeHasListeners(event_type)) { + // Diagnostics are too important to drop. If nobody is listening, print the + // diagnostic directly to the debugger's error stream. + DiagnosticEventData event_data(type, std::move(message), debugger_specific); + StreamSP stream = debugger.GetAsyncErrorStream(); + event_data.Dump(stream.get()); + return; + } + EventSP event_sp = std::make_shared<Event>( + event_type, + new DiagnosticEventData(type, std::move(message), debugger_specific)); + broadcaster.BroadcastEvent(event_sp); +} + +void Debugger::ReportDiagnosticImpl(DiagnosticEventData::Type type, + std::string message, + llvm::Optional<lldb::user_id_t> debugger_id, + std::once_flag *once) { + auto ReportDiagnosticLambda = [&]() { + // Check if this progress is for a specific debugger. + if (debugger_id) { + // It is debugger specific, grab it and deliver the event if the debugger + // still exists. + DebuggerSP debugger_sp = FindDebuggerWithID(*debugger_id); + if (debugger_sp) + PrivateReportDiagnostic(*debugger_sp, type, std::move(message), 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); + for (const auto &debugger : *g_debugger_list_ptr) + PrivateReportDiagnostic(*debugger, type, message, false); + } + }; + + if (once) + std::call_once(*once, ReportDiagnosticLambda); + else + ReportDiagnosticLambda(); +} + +void Debugger::ReportWarning(std::string message, + llvm::Optional<lldb::user_id_t> debugger_id, + std::once_flag *once) { + ReportDiagnosticImpl(DiagnosticEventData::Type::Warning, std::move(message), + debugger_id, once); +} + +void Debugger::ReportError(std::string message, + llvm::Optional<lldb::user_id_t> debugger_id, + std::once_flag *once) { + + ReportDiagnosticImpl(DiagnosticEventData::Type::Error, std::move(message), + debugger_id, once); +} + +static std::shared_ptr<LogHandler> +CreateLogHandler(LogHandlerKind log_handler_kind, int fd, bool should_close, + size_t buffer_size) { + switch (log_handler_kind) { + case eLogHandlerStream: + return std::make_shared<StreamLogHandler>(fd, should_close, buffer_size); + case eLogHandlerCircular: + return std::make_shared<RotatingLogHandler>(buffer_size); + case eLogHandlerSystem: + return std::make_shared<SystemLogHandler>(); + case eLogHandlerCallback: + return {}; + } + return {}; +} + bool Debugger::EnableLog(llvm::StringRef channel, llvm::ArrayRef<const char *> categories, llvm::StringRef log_file, uint32_t log_options, + size_t buffer_size, LogHandlerKind log_handler_kind, llvm::raw_ostream &error_stream) { - const bool should_close = true; - const bool unbuffered = true; - std::shared_ptr<llvm::raw_ostream> log_stream_sp; - if (m_log_callback_stream_sp) { - log_stream_sp = m_log_callback_stream_sp; + std::shared_ptr<LogHandler> log_handler_sp; + if (m_callback_handler_sp) { + log_handler_sp = m_callback_handler_sp; // For now when using the callback mode you always get thread & timestamp. log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME; } else if (log_file.empty()) { - log_stream_sp = std::make_shared<llvm::raw_fd_ostream>( - GetOutputFile().GetDescriptor(), !should_close, unbuffered); + log_handler_sp = + CreateLogHandler(log_handler_kind, GetOutputFile().GetDescriptor(), + /*should_close=*/false, buffer_size); } else { - auto pos = m_log_streams.find(log_file); - if (pos != m_log_streams.end()) - log_stream_sp = pos->second.lock(); - if (!log_stream_sp) { + auto pos = m_stream_handlers.find(log_file); + if (pos != m_stream_handlers.end()) + log_handler_sp = pos->second.lock(); + if (!log_handler_sp) { File::OpenOptions flags = File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate; if (log_options & LLDB_LOG_OPTION_APPEND) @@ -1360,18 +1457,18 @@ bool Debugger::EnableLog(llvm::StringRef channel, return false; } - log_stream_sp = std::make_shared<llvm::raw_fd_ostream>( - (*file)->GetDescriptor(), should_close, unbuffered); - m_log_streams[log_file] = log_stream_sp; + log_handler_sp = + CreateLogHandler(log_handler_kind, (*file)->GetDescriptor(), + /*should_close=*/true, buffer_size); + m_stream_handlers[log_file] = log_handler_sp; } } - assert(log_stream_sp); + assert(log_handler_sp); if (log_options == 0) - log_options = - LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE; + log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME; - return Log::EnableLogChannel(log_stream_sp, log_options, channel, categories, + return Log::EnableLogChannel(log_handler_sp, log_options, channel, categories, error_stream); } @@ -1575,7 +1672,7 @@ void Debugger::CancelForwardEvents(const ListenerSP &listener_sp) { m_forward_listener_sp.reset(); } -void Debugger::DefaultEventHandler() { +lldb::thread_result_t Debugger::DefaultEventHandler() { ListenerSP listener_sp(GetListener()); ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass()); ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass()); @@ -1604,6 +1701,10 @@ void Debugger::DefaultEventHandler() { CommandInterpreter::eBroadcastBitAsynchronousOutputData | CommandInterpreter::eBroadcastBitAsynchronousErrorData); + listener_sp->StartListeningForEvents( + &m_broadcaster, + eBroadcastBitProgress | eBroadcastBitWarning | eBroadcastBitError); + // Let the thread that spawned us know that we have started up and that we // are now listening to all required events so no events get missed m_sync_broadcaster.BroadcastEvent(eBroadcastBitEventThreadIsListening); @@ -1653,6 +1754,13 @@ void Debugger::DefaultEventHandler() { } } } + } else if (broadcaster == &m_broadcaster) { + if (event_type & Debugger::eBroadcastBitProgress) + HandleProgressEvent(event_sp); + else if (event_type & Debugger::eBroadcastBitWarning) + HandleDiagnosticEvent(event_sp); + else if (event_type & Debugger::eBroadcastBitError) + HandleDiagnosticEvent(event_sp); } } @@ -1661,10 +1769,6 @@ void Debugger::DefaultEventHandler() { } } } -} - -lldb::thread_result_t Debugger::EventHandlerThread(lldb::thread_arg_t arg) { - ((Debugger *)arg)->DefaultEventHandler(); return {}; } @@ -1686,14 +1790,14 @@ bool Debugger::StartEventHandlerThread() { // Use larger 8MB stack for this thread llvm::Expected<HostThread> event_handler_thread = - ThreadLauncher::LaunchThread(thread_name, EventHandlerThread, this, - g_debugger_event_thread_stack_bytes); + ThreadLauncher::LaunchThread( + thread_name, [this] { return DefaultEventHandler(); }, + g_debugger_event_thread_stack_bytes); if (event_handler_thread) { m_event_handler_thread = *event_handler_thread; } else { - LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST), - "failed to launch host thread: {}", + LLDB_LOG(GetLog(LLDBLog::Host), "failed to launch host thread: {}", llvm::toString(event_handler_thread.takeError())); } @@ -1716,25 +1820,106 @@ void Debugger::StopEventHandlerThread() { } } -lldb::thread_result_t Debugger::IOHandlerThread(lldb::thread_arg_t arg) { - Debugger *debugger = (Debugger *)arg; - debugger->RunIOHandlers(); - debugger->StopEventHandlerThread(); +lldb::thread_result_t Debugger::IOHandlerThread() { + RunIOHandlers(); + StopEventHandlerThread(); return {}; } +void Debugger::HandleProgressEvent(const lldb::EventSP &event_sp) { + auto *data = ProgressEventData::GetEventDataFromEvent(event_sp.get()); + if (!data) + return; + + // Do some bookkeeping for the current event, regardless of whether we're + // going to show the progress. + const uint64_t id = data->GetID(); + if (m_current_event_id) { + if (id != *m_current_event_id) + return; + if (data->GetCompleted()) + m_current_event_id.reset(); + } else { + m_current_event_id = id; + } + + // Decide whether we actually are going to show the progress. This decision + // can change between iterations so check it inside the loop. + if (!GetShowProgress()) + return; + + // Determine whether the current output file is an interactive terminal with + // color support. We assume that if we support ANSI escape codes we support + // vt100 escape codes. + File &file = GetOutputFile(); + if (!file.GetIsInteractive() || !file.GetIsTerminalWithColors()) + return; + + StreamSP output = GetAsyncOutputStream(); + + // Print over previous line, if any. + output->Printf("\r"); + + if (data->GetCompleted()) { + // Clear the current line. + output->Printf("\x1B[2K"); + output->Flush(); + return; + } + + // Trim the progress message if it exceeds the window's width and print it. + std::string message = data->GetMessage(); + if (data->IsFinite()) + message = llvm::formatv("[{0}/{1}] {2}", data->GetCompleted(), + data->GetTotal(), message) + .str(); + + // Trim the progress message if it exceeds the window's width and print it. + const uint32_t term_width = GetTerminalWidth(); + const uint32_t ellipsis = 3; + if (message.size() + ellipsis >= term_width) + message = message.substr(0, term_width - ellipsis); + + const bool use_color = GetUseColor(); + llvm::StringRef ansi_prefix = GetShowProgressAnsiPrefix(); + if (!ansi_prefix.empty()) + output->Printf( + "%s", ansi::FormatAnsiTerminalCodes(ansi_prefix, use_color).c_str()); + + output->Printf("%s...", message.c_str()); + + llvm::StringRef ansi_suffix = GetShowProgressAnsiSuffix(); + if (!ansi_suffix.empty()) + output->Printf( + "%s", ansi::FormatAnsiTerminalCodes(ansi_suffix, use_color).c_str()); + + // Clear until the end of the line. + output->Printf("\x1B[K\r"); + + // Flush the output. + output->Flush(); +} + +void Debugger::HandleDiagnosticEvent(const lldb::EventSP &event_sp) { + auto *data = DiagnosticEventData::GetEventDataFromEvent(event_sp.get()); + if (!data) + return; + + StreamSP stream = GetAsyncErrorStream(); + data->Dump(stream.get()); +} + bool Debugger::HasIOHandlerThread() { return m_io_handler_thread.IsJoinable(); } bool Debugger::StartIOHandlerThread() { if (!m_io_handler_thread.IsJoinable()) { llvm::Expected<HostThread> io_handler_thread = ThreadLauncher::LaunchThread( - "lldb.debugger.io-handler", IOHandlerThread, this, + "lldb.debugger.io-handler", [this] { return IOHandlerThread(); }, 8 * 1024 * 1024); // Use larger 8MB stack for this thread if (io_handler_thread) { m_io_handler_thread = *io_handler_thread; } else { - LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST), - "failed to launch host thread: {}", + LLDB_LOG(GetLog(LLDBLog::Host), "failed to launch host thread: {}", llvm::toString(io_handler_thread.takeError())); } } @@ -1807,3 +1992,13 @@ Status Debugger::RunREPL(LanguageType language, const char *repl_options) { return err; } + +llvm::ThreadPool &Debugger::GetThreadPool() { + // NOTE: intentional leak to avoid issues with C++ destructor chain + static llvm::ThreadPool *g_thread_pool = nullptr; + static llvm::once_flag g_once_flag; + llvm::call_once(g_once_flag, []() { + g_thread_pool = new llvm::ThreadPool(llvm::optimal_concurrency()); + }); + return *g_thread_pool; +} diff --git a/contrib/llvm-project/lldb/source/Core/DebuggerEvents.cpp b/contrib/llvm-project/lldb/source/Core/DebuggerEvents.cpp new file mode 100644 index 000000000000..19693e91ab23 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Core/DebuggerEvents.cpp @@ -0,0 +1,81 @@ +//===-- DebuggerEvents.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/DebuggerEvents.h" +#include "llvm/Support/WithColor.h" + +using namespace lldb_private; + +template <typename T> +static const T *GetEventDataFromEventImpl(const Event *event_ptr) { + if (event_ptr) + if (const EventData *event_data = event_ptr->GetData()) + if (event_data->GetFlavor() == T::GetFlavorString()) + return static_cast<const T *>(event_ptr->GetData()); + return nullptr; +} + +ConstString ProgressEventData::GetFlavorString() { + static ConstString g_flavor("ProgressEventData"); + return g_flavor; +} + +ConstString ProgressEventData::GetFlavor() const { + return ProgressEventData::GetFlavorString(); +} + +void 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 ProgressEventData * +ProgressEventData::GetEventDataFromEvent(const Event *event_ptr) { + return GetEventDataFromEventImpl<ProgressEventData>(event_ptr); +} + +llvm::StringRef DiagnosticEventData::GetPrefix() const { + switch (m_type) { + case Type::Warning: + return "warning"; + case Type::Error: + return "error"; + } + llvm_unreachable("Fully covered switch above!"); +} + +void DiagnosticEventData::Dump(Stream *s) const { + llvm::HighlightColor color = m_type == Type::Warning + ? llvm::HighlightColor::Warning + : llvm::HighlightColor::Error; + llvm::WithColor(s->AsRawOstream(), color, llvm::ColorMode::Enable) + << GetPrefix(); + *s << ": " << GetMessage() << '\n'; + s->Flush(); +} + +ConstString DiagnosticEventData::GetFlavorString() { + static ConstString g_flavor("DiagnosticEventData"); + return g_flavor; +} + +ConstString DiagnosticEventData::GetFlavor() const { + return DiagnosticEventData::GetFlavorString(); +} + +const DiagnosticEventData * +DiagnosticEventData::GetEventDataFromEvent(const Event *event_ptr) { + return GetEventDataFromEventImpl<DiagnosticEventData>(event_ptr); +} diff --git a/contrib/llvm-project/lldb/source/Core/DumpDataExtractor.cpp b/contrib/llvm-project/lldb/source/Core/DumpDataExtractor.cpp index 211e16a2e033..4ef1df1aeb0f 100644 --- a/contrib/llvm-project/lldb/source/Core/DumpDataExtractor.cpp +++ b/contrib/llvm-project/lldb/source/Core/DumpDataExtractor.cpp @@ -118,7 +118,7 @@ static lldb::offset_t DumpAPInt(Stream *s, const DataExtractor &data, lldb::offset_t offset, lldb::offset_t byte_size, bool is_signed, unsigned radix) { llvm::Optional<llvm::APInt> apint = GetAPInt(data, &offset, byte_size); - if (apint.hasValue()) { + if (apint) { std::string apint_str = toString(apint.getValue(), radix, is_signed); switch (radix) { case 2: @@ -670,7 +670,7 @@ lldb::offset_t lldb_private::DumpDataExtractor( (llvm::APFloat::getSizeInBits(semantics) + 7) / 8; llvm::Optional<llvm::APInt> apint = GetAPInt(DE, &offset, semantics_byte_size); - if (apint.hasValue()) { + if (apint) { llvm::APFloat apfloat(semantics, apint.getValue()); apfloat.toString(sv, format_precision, format_max_padding); if (!sv.empty()) { diff --git a/contrib/llvm-project/lldb/source/Core/DynamicLoader.cpp b/contrib/llvm-project/lldb/source/Core/DynamicLoader.cpp index 1c7b9125e4d1..96e0d4ec6555 100644 --- a/contrib/llvm-project/lldb/source/Core/DynamicLoader.cpp +++ b/contrib/llvm-project/lldb/source/Core/DynamicLoader.cpp @@ -145,72 +145,30 @@ DynamicLoader::GetSectionListFromModule(const ModuleSP module) const { return sections; } -ModuleSP DynamicLoader::LoadModuleAtAddress(const FileSpec &file, - addr_t link_map_addr, - addr_t base_addr, - bool base_addr_is_offset) { +ModuleSP DynamicLoader::FindModuleViaTarget(const FileSpec &file) { Target &target = m_process->GetTarget(); - ModuleList &modules = target.GetImages(); ModuleSpec module_spec(file, target.GetArchitecture()); - ModuleSP module_sp; - if ((module_sp = modules.FindFirstModule(module_spec))) { - UpdateLoadedSections(module_sp, link_map_addr, base_addr, - base_addr_is_offset); + if (ModuleSP module_sp = target.GetImages().FindFirstModule(module_spec)) return module_sp; - } - if ((module_sp = target.GetOrCreateModule(module_spec, - true /* notify */))) { - UpdateLoadedSections(module_sp, link_map_addr, base_addr, - base_addr_is_offset); + if (ModuleSP module_sp = target.GetOrCreateModule(module_spec, false)) return module_sp; - } - - bool check_alternative_file_name = true; - if (base_addr_is_offset) { - // Try to fetch the load address of the file from the process as we need - // absolute load address to read the file out of the memory instead of a - // load bias. - bool is_loaded = false; - lldb::addr_t load_addr; - Status error = m_process->GetFileLoadAddress(file, is_loaded, load_addr); - if (error.Success() && is_loaded) { - check_alternative_file_name = false; - base_addr = load_addr; - } - } - - // We failed to find the module based on its name. Lets try to check if we - // can find a different name based on the memory region info. - if (check_alternative_file_name) { - MemoryRegionInfo memory_info; - Status error = m_process->GetMemoryRegionInfo(base_addr, memory_info); - if (error.Success() && memory_info.GetMapped() && - memory_info.GetRange().GetRangeBase() == base_addr && - !(memory_info.GetName().IsEmpty())) { - ModuleSpec new_module_spec(FileSpec(memory_info.GetName().GetStringRef()), - target.GetArchitecture()); - - if ((module_sp = modules.FindFirstModule(new_module_spec))) { - UpdateLoadedSections(module_sp, link_map_addr, base_addr, false); - return module_sp; - } - if ((module_sp = target.GetOrCreateModule(new_module_spec, - true /* notify */))) { - UpdateLoadedSections(module_sp, link_map_addr, base_addr, false); - return module_sp; - } - } - } + return nullptr; +} - if ((module_sp = m_process->ReadModuleFromMemory(file, base_addr))) { - UpdateLoadedSections(module_sp, link_map_addr, base_addr, false); - target.GetImages().AppendIfNeeded(module_sp); +ModuleSP DynamicLoader::LoadModuleAtAddress(const FileSpec &file, + addr_t link_map_addr, + addr_t base_addr, + bool base_addr_is_offset) { + if (ModuleSP module_sp = FindModuleViaTarget(file)) { + UpdateLoadedSections(module_sp, link_map_addr, base_addr, + base_addr_is_offset); + return module_sp; } - return module_sp; + return nullptr; } int64_t DynamicLoader::ReadUnsignedIntWithSizeInBytes(addr_t addr, diff --git a/contrib/llvm-project/lldb/source/Core/FileSpecList.cpp b/contrib/llvm-project/lldb/source/Core/FileSpecList.cpp index 1a1cf284ea07..8eec8f499352 100644 --- a/contrib/llvm-project/lldb/source/Core/FileSpecList.cpp +++ b/contrib/llvm-project/lldb/source/Core/FileSpecList.cpp @@ -16,7 +16,6 @@ #include <cstdint> using namespace lldb_private; -using namespace std; FileSpecList::FileSpecList() : m_files() {} diff --git a/contrib/llvm-project/lldb/source/Core/FormatEntity.cpp b/contrib/llvm-project/lldb/source/Core/FormatEntity.cpp index 6e6255b903bb..6e7f44e461fa 100644 --- a/contrib/llvm-project/lldb/source/Core/FormatEntity.cpp +++ b/contrib/llvm-project/lldb/source/Core/FormatEntity.cpp @@ -44,8 +44,8 @@ #include "lldb/Utility/CompletionRequest.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/LLDBLog.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" @@ -263,11 +263,10 @@ constexpr Definition g_root = Entry::DefinitionWithChildren( FormatEntity::Entry::Entry(llvm::StringRef s) : string(s.data(), s.size()), printf_format(), children(), - type(Type::String), fmt(lldb::eFormatDefault), number(0), deref(false) {} + type(Type::String) {} FormatEntity::Entry::Entry(char ch) - : string(1, ch), printf_format(), children(), type(Type::String), - fmt(lldb::eFormatDefault), number(0), deref(false) {} + : string(1, ch), printf_format(), children(), type(Type::String) {} void FormatEntity::Entry::AppendChar(char ch) { if (children.empty() || children.back().type != Entry::Type::String) @@ -509,7 +508,7 @@ static bool ScanBracketedRange(llvm::StringRef subpath, size_t &close_bracket_index, const char *&var_name_final_if_array_range, int64_t &index_lower, int64_t &index_higher) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS)); + Log *log = GetLog(LLDBLog::DataFormatters); close_bracket_index = llvm::StringRef::npos; const size_t open_bracket_index = subpath.find('['); if (open_bracket_index == llvm::StringRef::npos) { @@ -618,7 +617,7 @@ static bool DumpRegister(Stream &s, StackFrame *frame, RegisterKind reg_kind, static ValueObjectSP ExpandIndexedExpression(ValueObject *valobj, size_t index, bool deref_pointer) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS)); + Log *log = GetLog(LLDBLog::DataFormatters); const char *ptr_deref_format = "[%d]"; std::string ptr_deref_buffer(10, 0); ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index); @@ -676,7 +675,7 @@ static bool DumpValue(Stream &s, const SymbolContext *sc, if (valobj == nullptr) return false; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS)); + Log *log = GetLog(LLDBLog::DataFormatters); Format custom_format = eFormatInvalid; ValueObject::ValueObjectRepresentationStyle val_obj_display = entry.string.empty() diff --git a/contrib/llvm-project/lldb/source/Core/IOHandler.cpp b/contrib/llvm-project/lldb/source/Core/IOHandler.cpp index c35b17990842..db388ab48275 100644 --- a/contrib/llvm-project/lldb/source/Core/IOHandler.cpp +++ b/contrib/llvm-project/lldb/source/Core/IOHandler.cpp @@ -17,6 +17,7 @@ #include "lldb/Core/StreamFile.h" #include "lldb/Host/Config.h" #include "lldb/Host/File.h" +#include "lldb/Utility/AnsiTerminal.h" #include "lldb/Utility/Predicate.h" #include "lldb/Utility/ReproducerProvider.h" #include "lldb/Utility/Status.h" @@ -121,14 +122,19 @@ void IOHandler::SetPopped(bool b) { m_popped.SetValue(b, eBroadcastOnChange); } void IOHandler::WaitForPop() { m_popped.WaitForValueEqualTo(true); } -void IOHandlerStack::PrintAsync(Stream *stream, const char *s, size_t len) { - if (stream) { - std::lock_guard<std::recursive_mutex> guard(m_mutex); - if (m_top) - m_top->PrintAsync(stream, s, len); - else - stream->Write(s, len); - } +void IOHandler::PrintAsync(const char *s, size_t len, bool is_stdout) { + std::lock_guard<std::recursive_mutex> guard(m_output_mutex); + lldb::StreamFileSP stream = is_stdout ? m_output_sp : m_error_sp; + stream->Write(s, len); + stream->Flush(); +} + +bool IOHandlerStack::PrintAsync(const char *s, size_t len, bool is_stdout) { + std::lock_guard<std::recursive_mutex> guard(m_mutex); + if (!m_top) + return false; + m_top->PrintAsync(s, len, is_stdout); + return true; } IOHandlerConfirm::IOHandlerConfirm(Debugger &debugger, llvm::StringRef prompt, @@ -261,9 +267,9 @@ IOHandlerEditline::IOHandlerEditline( m_input_sp && m_input_sp->GetIsRealTerminal(); if (use_editline) { - m_editline_up = std::make_unique<Editline>(editline_name, GetInputFILE(), - GetOutputFILE(), GetErrorFILE(), - m_color_prompts); + m_editline_up = std::make_unique<Editline>( + editline_name, GetInputFILE(), GetOutputFILE(), GetErrorFILE(), + GetOutputMutex(), m_color_prompts); m_editline_up->SetIsInputCompleteCallback( [this](Editline *editline, StringList &lines) { return this->IsInputCompleteCallback(editline, lines); @@ -273,10 +279,14 @@ IOHandlerEditline::IOHandlerEditline( this->AutoCompleteCallback(request); }); - if (debugger.GetUseAutosuggestion() && debugger.GetUseColor()) { + if (debugger.GetUseAutosuggestion()) { m_editline_up->SetSuggestionCallback([this](llvm::StringRef line) { return this->SuggestionCallback(line); }); + m_editline_up->SetSuggestionAnsiPrefix(ansi::FormatAnsiTerminalCodes( + debugger.GetAutosuggestionAnsiPrefix())); + m_editline_up->SetSuggestionAnsiSuffix(ansi::FormatAnsiTerminalCodes( + debugger.GetAutosuggestionAnsiSuffix())); } // See if the delegate supports fixing indentation const char *indent_chars = delegate.IOHandlerGetFixIndentationCharacters(); @@ -426,7 +436,7 @@ bool IOHandlerEditline::GetLine(std::string &line, bool &interrupted) { } if (got_line) { - line = got_line.getValue(); + line = *got_line; if (m_data_recorder) m_data_recorder->Record(line, true); } @@ -607,11 +617,13 @@ void IOHandlerEditline::GotEOF() { #endif } -void IOHandlerEditline::PrintAsync(Stream *stream, const char *s, size_t len) { +void IOHandlerEditline::PrintAsync(const char *s, size_t len, bool is_stdout) { #if LLDB_ENABLE_LIBEDIT - if (m_editline_up) - m_editline_up->PrintAsync(stream, s, len); - else + if (m_editline_up) { + std::lock_guard<std::recursive_mutex> guard(m_output_mutex); + lldb::StreamFileSP stream = is_stdout ? m_output_sp : m_error_sp; + m_editline_up->PrintAsync(stream.get(), s, len); + } else #endif { #ifdef _WIN32 @@ -628,11 +640,10 @@ void IOHandlerEditline::PrintAsync(Stream *stream, const char *s, size_t len) { SetConsoleCursorPosition(console_handle, coord); } #endif - IOHandler::PrintAsync(stream, s, len); + IOHandler::PrintAsync(s, len, is_stdout); #ifdef _WIN32 if (prompt) - IOHandler::PrintAsync(GetOutputStreamFileSP().get(), prompt, - strlen(prompt)); + IOHandler::PrintAsync(prompt, strlen(prompt), is_stdout); #endif } } diff --git a/contrib/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp b/contrib/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp index b37e84a13c5e..0151255631bf 100644 --- a/contrib/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp +++ b/contrib/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp @@ -28,6 +28,7 @@ #include "lldb/Core/StreamFile.h" #include "lldb/Core/ValueObjectUpdater.h" #include "lldb/Host/File.h" +#include "lldb/Utility/AnsiTerminal.h" #include "lldb/Utility/Predicate.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamString.h" @@ -341,7 +342,7 @@ public: protected: StringList m_text; - int m_first_visible_line; + int m_first_visible_line = 0; }; // A surface is an abstraction for something than can be drawn on. The surface @@ -352,7 +353,7 @@ class Surface { public: enum class Type { Window, Pad }; - Surface(Surface::Type type) : m_type(type), m_window(nullptr) {} + Surface(Surface::Type type) : m_type(type) {} WINDOW *get() { return m_window; } @@ -495,7 +496,7 @@ public: if (use_blue_background) ::wattron(m_window, COLOR_PAIR(WhiteOnBlue)); while (!string.empty()) { - size_t esc_pos = string.find('\x1b'); + size_t esc_pos = string.find(ANSI_ESC_START); if (esc_pos == StringRef::npos) { string = string.substr(skip_first_count); if (!string.empty()) { @@ -517,36 +518,36 @@ public: string = string.drop_front(esc_pos); } } - bool consumed = string.consume_front("\x1b"); + bool consumed = string.consume_front(ANSI_ESC_START); assert(consumed); UNUSED_IF_ASSERT_DISABLED(consumed); // This is written to match our Highlighter classes, which seem to // generate only foreground color escape sequences. If necessary, this // will need to be extended. - if (!string.consume_front("[")) { - llvm::errs() << "Missing '[' in color escape sequence.\n"; - continue; - } - // Only 8 basic foreground colors and reset, our Highlighter doesn't use - // anything else. + // Only 8 basic foreground colors, underline and reset, our Highlighter + // doesn't use anything else. int value; if (!!string.consumeInteger(10, value) || // Returns false on success. - !(value == 0 || (value >= 30 && value <= 37))) { + !(value == 0 || value == ANSI_CTRL_UNDERLINE || + (value >= ANSI_FG_COLOR_BLACK && value <= ANSI_FG_COLOR_WHITE))) { llvm::errs() << "No valid color code in color escape sequence.\n"; continue; } - if (!string.consume_front("m")) { - llvm::errs() << "Missing 'm' in color escape sequence.\n"; + if (!string.consume_front(ANSI_ESC_END)) { + llvm::errs() << "Missing '" << ANSI_ESC_END + << "' in color escape sequence.\n"; continue; } if (value == 0) { // Reset. wattr_set(m_window, saved_attr, saved_pair, nullptr); if (use_blue_background) ::wattron(m_window, COLOR_PAIR(WhiteOnBlue)); + } else if (value == ANSI_CTRL_UNDERLINE) { + ::wattron(m_window, A_UNDERLINE); } else { // Mapped directly to first 16 color pairs (black/blue background). - ::wattron(m_window, - COLOR_PAIR(value - 30 + 1 + (use_blue_background ? 8 : 0))); + ::wattron(m_window, COLOR_PAIR(value - ANSI_FG_COLOR_BLACK + 1 + + (use_blue_background ? 8 : 0))); } } wattr_set(m_window, saved_attr, saved_pair, nullptr); @@ -555,7 +556,7 @@ public: protected: Type m_type; - WINDOW *m_window; + WINDOW *m_window = nullptr; }; class Pad : public Surface { @@ -1076,8 +1077,7 @@ 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) { + : m_label(label), m_required(required) { if (content) m_content = content; } @@ -1325,9 +1325,9 @@ protected: std::string m_content; // The cursor position in the content string itself. Can be in the range // [0, GetContentLength()]. - int m_cursor_position; + int m_cursor_position = 0; // The index of the first visible character in the content. - int m_first_visibile_char; + int m_first_visibile_char = 0; // Optional error message. If empty, field is considered to have no error. std::string m_error; }; @@ -1515,7 +1515,7 @@ 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) {} + m_choices(choices) {} // 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 @@ -1609,7 +1609,7 @@ public: // Returns the index of the choice. int GetChoice() { return m_choice; } - void SetChoice(const std::string &choice) { + void SetChoice(llvm::StringRef choice) { for (int i = 0; i < GetNumberOfChoices(); i++) { if (choice == m_choices[i]) { m_choice = i; @@ -1623,9 +1623,9 @@ protected: int m_number_of_visible_choices; std::vector<std::string> m_choices; // The index of the selected choice. - int m_choice; + int m_choice = 0; // The index of the first visible choice in the field. - int m_first_visibile_choice; + int m_first_visibile_choice = 0; }; class PlatformPluginFieldDelegate : public ChoicesFieldDelegate { @@ -1634,7 +1634,7 @@ public: : ChoicesFieldDelegate("Platform Plugin", 3, GetPossiblePluginNames()) { PlatformSP platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); if (platform_sp) - SetChoice(platform_sp->GetName().AsCString()); + SetChoice(platform_sp->GetPluginName()); } std::vector<std::string> GetPossiblePluginNames() { @@ -1707,7 +1707,7 @@ public: 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_label(label), m_default_field(default_field), m_selection_type(SelectionType::NewButton) {} // Signify which element is selected. If a field or a remove button is @@ -2011,7 +2011,7 @@ protected: // created though a copy. T m_default_field; std::vector<T> m_fields; - int m_selection_index; + int m_selection_index = 0; // See SelectionType class enum. SelectionType m_selection_type; }; @@ -2283,7 +2283,7 @@ protected: class FormDelegate { public: - FormDelegate() {} + FormDelegate() = default; virtual ~FormDelegate() = default; @@ -2465,9 +2465,7 @@ 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) { + FormWindowDelegate(FormDelegateSP &delegate_sp) : m_delegate_sp(delegate_sp) { assert(m_delegate_sp->GetNumberOfActions() > 0); if (m_delegate_sp->GetNumberOfFields() > 0) m_selection_type = SelectionType::Field; @@ -2856,11 +2854,11 @@ public: protected: FormDelegateSP m_delegate_sp; // The index of the currently selected SelectionType. - int m_selection_index; + int m_selection_index = 0; // See SelectionType class enum. SelectionType m_selection_type; // The first visible line from the pad. - int m_first_visible_line; + int m_first_visible_line = 0; }; /////////////////////////// @@ -3647,7 +3645,7 @@ protected: class SearcherDelegate { public: - SearcherDelegate() {} + SearcherDelegate() = default; virtual ~SearcherDelegate() = default; @@ -3670,8 +3668,7 @@ typedef std::shared_ptr<SearcherDelegate> SearcherDelegateSP; class SearcherWindowDelegate : public WindowDelegate { public: SearcherWindowDelegate(SearcherDelegateSP &delegate_sp) - : m_delegate_sp(delegate_sp), m_text_field("Search", "", false), - m_selected_match(0), m_first_visible_match(0) { + : m_delegate_sp(delegate_sp), m_text_field("Search", "", false) { ; } @@ -3811,9 +3808,9 @@ protected: SearcherDelegateSP m_delegate_sp; TextFieldDelegate m_text_field; // The index of the currently selected match. - int m_selected_match; + int m_selected_match = 0; // The index of the first visible match. - int m_first_visible_match; + int m_first_visible_match = 0; }; ////////////////////////////// @@ -4266,8 +4263,7 @@ HandleCharResult Menu::WindowDelegateHandleChar(Window &window, int key) { class Application { public: - Application(FILE *in, FILE *out) - : m_window_sp(), m_screen(nullptr), m_in(in), m_out(out) {} + Application(FILE *in, FILE *out) : m_window_sp(), m_in(in), m_out(out) {} ~Application() { m_window_delegates.clear(); @@ -4475,7 +4471,7 @@ public: protected: WindowSP m_window_sp; WindowDelegates m_window_delegates; - SCREEN *m_screen; + SCREEN *m_screen = nullptr; FILE *m_in; FILE *m_out; bool m_update_screen = false; @@ -4541,7 +4537,8 @@ struct Row { if (parent) parent->DrawTreeForChild(window, this, 0); - if (might_have_children) { + if (might_have_children && + (!calculated_children || !GetChildren().empty())) { // It we can get UTF8 characters to work we should try to use the // "symbol" UTF8 string below // const char *symbol = ""; @@ -4619,9 +4616,8 @@ typedef std::shared_ptr<TreeDelegate> TreeDelegateSP; class TreeItem { 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_parent(parent), m_delegate(delegate), m_children(), + m_might_have_children(might_have_children) { if (m_parent == nullptr) m_is_expanded = m_delegate.TreeDelegateExpandRootByDefault(); } @@ -4816,23 +4812,21 @@ public: protected: TreeItem *m_parent; TreeDelegate &m_delegate; - void *m_user_data; - uint64_t m_identifier; + void *m_user_data = nullptr; + uint64_t m_identifier = 0; std::string m_text; - int m_row_idx; // Zero based visible row index, -1 if not visible or for the - // root item + int m_row_idx = -1; // Zero based visible row index, -1 if not visible or for + // the root item std::vector<TreeItem> m_children; bool m_might_have_children; - bool m_is_expanded; + bool m_is_expanded = false; }; class TreeWindowDelegate : public WindowDelegate { public: TreeWindowDelegate(Debugger &debugger, const TreeDelegateSP &delegate_sp) : m_debugger(debugger), m_delegate_sp(delegate_sp), - m_root(nullptr, *delegate_sp, true), m_selected_item(nullptr), - m_num_rows(0), m_selected_row_idx(0), m_first_visible_row(0), - m_min_x(0), m_min_y(0), m_max_x(0), m_max_y(0) {} + m_root(nullptr, *delegate_sp, true) {} int NumVisibleRows() const { return m_max_y - m_min_y; } @@ -4992,14 +4986,14 @@ protected: Debugger &m_debugger; TreeDelegateSP m_delegate_sp; TreeItem m_root; - TreeItem *m_selected_item; - int m_num_rows; - int m_selected_row_idx; - int m_first_visible_row; - int m_min_x; - int m_min_y; - int m_max_x; - int m_max_y; + TreeItem *m_selected_item = nullptr; + int m_num_rows = 0; + int m_selected_row_idx = 0; + int m_first_visible_row = 0; + int m_min_x = 0; + int m_min_y = 0; + int m_max_x = 0; + int m_max_y = 0; }; // A tree delegate that just draws the text member of the tree item, it doesn't @@ -5023,8 +5017,7 @@ class FrameTreeDelegate : public TreeDelegate { public: FrameTreeDelegate() : TreeDelegate() { FormatEntity::Parse( - "frame #${frame.index}: {${function.name}${function.pc-offset}}}", - m_format); + "#${frame.index}: {${function.name}${function.pc-offset}}}", m_format); } ~FrameTreeDelegate() override = default; @@ -5071,8 +5064,7 @@ protected: class ThreadTreeDelegate : public TreeDelegate { public: ThreadTreeDelegate(Debugger &debugger) - : TreeDelegate(), m_debugger(debugger), m_tid(LLDB_INVALID_THREAD_ID), - m_stop_id(UINT32_MAX) { + : TreeDelegate(), m_debugger(debugger) { FormatEntity::Parse("thread #${thread.index}: tid = ${thread.id}{, stop " "reason = ${thread.stop-reason}}", m_format); @@ -5161,16 +5153,15 @@ public: protected: Debugger &m_debugger; std::shared_ptr<FrameTreeDelegate> m_frame_delegate_sp; - lldb::user_id_t m_tid; - uint32_t m_stop_id; + lldb::user_id_t m_tid = LLDB_INVALID_THREAD_ID; + uint32_t m_stop_id = UINT32_MAX; FormatEntity::Entry m_format; }; class ThreadsTreeDelegate : public TreeDelegate { public: ThreadsTreeDelegate(Debugger &debugger) - : TreeDelegate(), m_thread_delegate_sp(), m_debugger(debugger), - m_stop_id(UINT32_MAX), m_update_selection(false) { + : TreeDelegate(), m_thread_delegate_sp(), m_debugger(debugger) { FormatEntity::Parse("process ${process.id}{, name = ${process.name}}", m_format); } @@ -5280,8 +5271,8 @@ public: protected: std::shared_ptr<ThreadTreeDelegate> m_thread_delegate_sp; Debugger &m_debugger; - uint32_t m_stop_id; - bool m_update_selection; + uint32_t m_stop_id = UINT32_MAX; + bool m_update_selection = false; FormatEntity::Entry m_format; }; @@ -5523,9 +5514,7 @@ class ValueObjectListDelegate : public WindowDelegate { public: ValueObjectListDelegate() : m_rows() {} - ValueObjectListDelegate(ValueObjectList &valobj_list) - : 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(ValueObjectList &valobj_list) : m_rows() { SetValues(valobj_list); } @@ -5836,9 +5825,11 @@ protected: ++m_num_rows; } - auto &children = row.GetChildren(); - if (row.expanded && !children.empty()) { - DisplayRows(window, children, options); + if (row.expanded) { + auto &children = row.GetChildren(); + if (!children.empty()) { + DisplayRows(window, children, options); + } } } } @@ -5859,11 +5850,13 @@ protected: return &row; else { --row_index; - auto &children = row.GetChildren(); - if (row.expanded && !children.empty()) { - Row *result = GetRowForRowIndexImpl(children, row_index); - if (result) - return result; + if (row.expanded) { + auto &children = row.GetChildren(); + if (!children.empty()) { + Row *result = GetRowForRowIndexImpl(children, row_index); + if (result) + return result; + } } } } @@ -5882,8 +5875,7 @@ protected: class FrameVariablesWindowDelegate : public ValueObjectListDelegate { public: FrameVariablesWindowDelegate(Debugger &debugger) - : ValueObjectListDelegate(), m_debugger(debugger), - m_frame_block(nullptr) {} + : ValueObjectListDelegate(), m_debugger(debugger) {} ~FrameVariablesWindowDelegate() override = default; @@ -5944,7 +5936,7 @@ public: protected: Debugger &m_debugger; - Block *m_frame_block; + Block *m_frame_block = nullptr; }; class RegistersWindowDelegate : public ValueObjectListDelegate { @@ -6198,7 +6190,7 @@ static const char *CursesKeyToCString(int ch) { HelpDialogDelegate::HelpDialogDelegate(const char *text, KeyHelp *key_help_array) - : m_text(), m_first_visible_line(0) { + : m_text() { if (text && text[0]) { m_text.SplitIntoLines(text); m_text.AppendString(""); @@ -6415,8 +6407,11 @@ public: if (exe_ctx.HasThreadScope()) { Process *process = exe_ctx.GetProcessPtr(); if (process && process->IsAlive() && - StateIsStoppedState(process->GetState(), true)) - exe_ctx.GetThreadRef().StepOut(); + StateIsStoppedState(process->GetState(), true)) { + Thread *thread = exe_ctx.GetThreadPtr(); + uint32_t frame_idx = thread->GetSelectedFrameIndex(); + exe_ctx.GetThreadRef().StepOut(frame_idx); + } } } return MenuActionResult::Handled; @@ -6762,11 +6757,7 @@ class SourceFileWindowDelegate : public WindowDelegate { 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_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) {} + m_disassembly_sp(), m_disassembly_range(), m_title() {} ~SourceFileWindowDelegate() override = default; @@ -6994,9 +6985,6 @@ public: } } - const attr_t selected_highlight_attr = A_REVERSE; - const attr_t pc_highlight_attr = COLOR_PAIR(BlackOnBlue); - for (size_t i = 0; i < num_visible_lines; ++i) { const uint32_t curr_line = m_first_visible_line + i; if (curr_line < num_source_lines) { @@ -7004,14 +6992,13 @@ public: window.MoveCursor(1, line_y); const bool is_pc_line = curr_line == m_pc_line; const bool line_is_selected = m_selected_line == curr_line; - // Highlight the line as the PC line first, then if the selected - // line isn't the same as the PC line, highlight it differently + // Highlight the line as the PC line first (done by passing + // argument to OutputColoredStringTruncated()), then if the selected + // line isn't the same as the PC line, highlight it differently. attr_t highlight_attr = 0; attr_t bp_attr = 0; - if (is_pc_line) - highlight_attr = pc_highlight_attr; - else if (line_is_selected) - highlight_attr = selected_highlight_attr; + if (line_is_selected && !is_pc_line) + highlight_attr = A_REVERSE; if (bp_lines.find(curr_line + 1) != bp_lines.end()) bp_attr = COLOR_PAIR(BlackOnWhite); @@ -7035,14 +7022,19 @@ public: window.AttributeOn(highlight_attr); StreamString lineStream; - m_file_sp->DisplaySourceLines(curr_line + 1, {}, 0, 0, &lineStream); + + llvm::Optional<size_t> column; + if (is_pc_line && m_sc.line_entry.IsValid() && m_sc.line_entry.column) + column = m_sc.line_entry.column - 1; + m_file_sp->DisplaySourceLines(curr_line + 1, column, 0, 0, + &lineStream); StringRef line = lineStream.GetString(); if (line.endswith("\n")) line = line.drop_back(); bool wasWritten = window.OutputColoredStringTruncated( - 1, line, m_first_visible_column, line_is_selected); - if (line_is_selected && !wasWritten) { - // Draw an empty space to show the selected line if empty, + 1, line, m_first_visible_column, is_pc_line); + if (!wasWritten && (line_is_selected || is_pc_line)) { + // Draw an empty space to show the selected/PC line if empty, // or draw '<' if nothing is visible because of scrolling too much // to the right. window.PutCStringTruncated( @@ -7377,7 +7369,9 @@ public: m_debugger.GetCommandInterpreter().GetExecutionContext(); if (exe_ctx.HasThreadScope() && StateIsStoppedState(exe_ctx.GetProcessRef().GetState(), true)) { - exe_ctx.GetThreadRef().StepOut(); + Thread *thread = exe_ctx.GetThreadPtr(); + uint32_t frame_idx = thread->GetSelectedFrameIndex(); + exe_ctx.GetThreadRef().StepOut(frame_idx); } } return eKeyHandled; @@ -7524,22 +7518,22 @@ protected: Debugger &m_debugger; SymbolContext m_sc; SourceManager::FileSP m_file_sp; - SymbolContextScope *m_disassembly_scope; + SymbolContextScope *m_disassembly_scope = nullptr; lldb::DisassemblerSP m_disassembly_sp; AddressRange m_disassembly_range; StreamString m_title; - lldb::user_id_t m_tid; - int m_line_width; - uint32_t m_selected_line; // The selected line - uint32_t m_pc_line; // The line with the PC - uint32_t m_stop_id; - uint32_t m_frame_idx; - int m_first_visible_line; - int m_first_visible_column; - int m_min_x; - int m_min_y; - int m_max_x; - int m_max_y; + lldb::user_id_t m_tid = LLDB_INVALID_THREAD_ID; + int m_line_width = 4; + uint32_t m_selected_line = 0; // The selected line + uint32_t m_pc_line = 0; // The line with the PC + uint32_t m_stop_id = 0; + uint32_t m_frame_idx = UINT32_MAX; + int m_first_visible_line = 0; + int m_first_visible_column = 0; + int m_min_x = 0; + int m_min_y = 0; + int m_max_x = 0; + int m_max_y = 0; }; DisplayOptions ValueObjectListDelegate::g_options = {true}; @@ -7682,14 +7676,6 @@ void IOHandlerCursesGUI::Activate() { status_window_sp->SetDelegate( WindowDelegateSP(new StatusBarWindowDelegate(m_debugger))); - // Show the main help window once the first time the curses GUI is - // launched - static bool g_showed_help = false; - if (!g_showed_help) { - g_showed_help = true; - main_window_sp->CreateHelpSubwindow(); - } - // All colors with black background. init_pair(1, COLOR_BLACK, COLOR_BLACK); init_pair(2, COLOR_RED, COLOR_BLACK); @@ -7729,7 +7715,9 @@ IOHandlerCursesGUI::~IOHandlerCursesGUI() = default; void IOHandlerCursesGUI::Cancel() {} -bool IOHandlerCursesGUI::Interrupt() { return false; } +bool IOHandlerCursesGUI::Interrupt() { + return m_debugger.GetCommandInterpreter().IOHandlerInterrupt(*this); +} void IOHandlerCursesGUI::GotEOF() {} diff --git a/contrib/llvm-project/lldb/source/Core/Mangled.cpp b/contrib/llvm-project/lldb/source/Core/Mangled.cpp index b8e405544b33..0c4d9f78c440 100644 --- a/contrib/llvm-project/lldb/source/Core/Mangled.cpp +++ b/contrib/llvm-project/lldb/source/Core/Mangled.cpp @@ -13,8 +13,8 @@ #include "lldb/Target/Language.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataEncoder.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Stream.h" #include "lldb/lldb-enumerations.h" @@ -130,7 +130,7 @@ static char *GetMSVCDemangledStr(const char *M) { llvm::MSDF_NoAccessSpecifier | llvm::MSDF_NoCallingConvention | llvm::MSDF_NoMemberType | llvm::MSDF_NoVariableType)); - if (Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE)) { + if (Log *log = GetLog(LLDBLog::Demangle)) { if (demangled_cstr && demangled_cstr[0]) LLDB_LOGF(log, "demangled msvc: %s -> \"%s\"", M, demangled_cstr); else @@ -157,7 +157,7 @@ static char *GetItaniumDemangledStr(const char *M) { "Expected demangled_size to return length including trailing null"); } - if (Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE)) { + if (Log *log = GetLog(LLDBLog::Demangle)) { if (demangled_cstr) LLDB_LOGF(log, "demangled itanium: %s -> \"%s\"", M, demangled_cstr); else @@ -168,9 +168,9 @@ static char *GetItaniumDemangledStr(const char *M) { } static char *GetRustV0DemangledStr(const char *M) { - char *demangled_cstr = llvm::rustDemangle(M, nullptr, nullptr, nullptr); + char *demangled_cstr = llvm::rustDemangle(M); - if (Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE)) { + if (Log *log = GetLog(LLDBLog::Demangle)) { if (demangled_cstr && demangled_cstr[0]) LLDB_LOG(log, "demangled rustv0: {0} -> \"{1}\"", M, demangled_cstr); else @@ -183,7 +183,7 @@ static char *GetRustV0DemangledStr(const char *M) { static char *GetDLangDemangledStr(const char *M) { char *demangled_cstr = llvm::dlangDemangle(M); - if (Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE)) { + if (Log *log = GetLog(LLDBLog::Demangle)) { if (demangled_cstr && demangled_cstr[0]) LLDB_LOG(log, "demangled dlang: {0} -> \"{1}\"", M, demangled_cstr); else diff --git a/contrib/llvm-project/lldb/source/Core/Module.cpp b/contrib/llvm-project/lldb/source/Core/Module.cpp index feecf984f7bf..41c21e1dc326 100644 --- a/contrib/llvm-project/lldb/source/Core/Module.cpp +++ b/contrib/llvm-project/lldb/source/Core/Module.cpp @@ -39,8 +39,8 @@ #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" @@ -129,8 +129,7 @@ Module *Module::GetAllocatedModuleAtIndex(size_t idx) { } Module::Module(const ModuleSpec &module_spec) - : m_object_offset(0), m_file_has_changed(false), - m_first_file_changed_log(false) { + : m_file_has_changed(false), m_first_file_changed_log(false) { // Scope for locker below... { std::lock_guard<std::recursive_mutex> guard( @@ -138,8 +137,7 @@ Module::Module(const ModuleSpec &module_spec) GetModuleCollection().push_back(this); } - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_OBJECT | - LIBLLDB_LOG_MODULES)); + Log *log(GetLog(LLDBLog::Object | LLDBLog::Modules)); if (log != nullptr) LLDB_LOGF(log, "%p Module::Module((%s) '%s%s%s%s')", static_cast<void *>(this), @@ -251,8 +249,7 @@ Module::Module(const FileSpec &file_spec, const ArchSpec &arch, if (object_name) m_object_name = *object_name; - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_OBJECT | - LIBLLDB_LOG_MODULES)); + Log *log(GetLog(LLDBLog::Object | LLDBLog::Modules)); if (log != nullptr) LLDB_LOGF(log, "%p Module::Module((%s) '%s%s%s%s')", static_cast<void *>(this), m_arch.GetArchitectureName(), @@ -281,8 +278,7 @@ Module::~Module() { assert(pos != end); modules.erase(pos); } - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_OBJECT | - LIBLLDB_LOG_MODULES)); + Log *log(GetLog(LLDBLog::Object | LLDBLog::Modules)); if (log != nullptr) LLDB_LOGF(log, "%p Module::~Module((%s) '%s%s%s%s')", static_cast<void *>(this), m_arch.GetArchitectureName(), @@ -308,15 +304,15 @@ ObjectFile *Module::GetMemoryObjectFile(const lldb::ProcessSP &process_sp, std::lock_guard<std::recursive_mutex> guard(m_mutex); if (process_sp) { m_did_load_objfile = true; - auto data_up = std::make_unique<DataBufferHeap>(size_to_read, 0); + std::shared_ptr<DataBufferHeap> data_sp = + std::make_shared<DataBufferHeap>(size_to_read, 0); Status readmem_error; const size_t bytes_read = - process_sp->ReadMemory(header_addr, data_up->GetBytes(), - data_up->GetByteSize(), readmem_error); + process_sp->ReadMemory(header_addr, data_sp->GetBytes(), + data_sp->GetByteSize(), readmem_error); if (bytes_read < size_to_read) - data_up->SetByteSize(bytes_read); - if (data_up->GetByteSize() > 0) { - DataBufferSP data_sp(data_up.release()); + data_sp->SetByteSize(bytes_read); + if (data_sp->GetByteSize() > 0) { m_objfile_sp = ObjectFile::FindPlugin(shared_from_this(), process_sp, header_addr, data_sp); if (m_objfile_sp) { @@ -479,6 +475,7 @@ uint32_t Module::ResolveSymbolContextForAddress( resolve_scope & eSymbolContextBlock || resolve_scope & eSymbolContextLineEntry || resolve_scope & eSymbolContextVariable) { + symfile->SetLoadDebugInfoEnabled(); resolved_flags |= symfile->ResolveSymbolContext(so_addr, resolve_scope, sc); } @@ -639,9 +636,7 @@ void Module::FindCompileUnits(const FileSpec &path, Module::LookupInfo::LookupInfo(ConstString name, FunctionNameType name_type_mask, LanguageType language) - : m_name(name), m_lookup_name(), m_language(language), - m_name_type_mask(eFunctionNameTypeNone), - m_match_name_after_lookup(false) { + : m_name(name), m_lookup_name(), m_language(language) { const char *name_cstr = name.GetCString(); llvm::StringRef basename; llvm::StringRef context; @@ -744,13 +739,25 @@ void Module::LookupInfo::Prune(SymbolContextList &sc_list, while (i < sc_list.GetSize()) { if (!sc_list.GetContextAtIndex(i, sc)) break; - ConstString full_name(sc.GetFunctionName()); - if (full_name && - ::strstr(full_name.GetCString(), m_name.GetCString()) == nullptr) { - sc_list.RemoveContextAtIndex(i); - } else { - ++i; + + llvm::StringRef user_name = m_name.GetStringRef(); + bool keep_it = true; + Language *language = Language::FindPlugin(sc.GetLanguage()); + // If the symbol has a language, then let the language make the match. + // Otherwise just check that the demangled name contains the user name. + if (language) + keep_it = language->DemangledNameContainsPath(m_name.GetStringRef(), + sc.GetFunctionName()); + else { + llvm::StringRef full_name = sc.GetFunctionName().GetStringRef(); + // We always keep unnamed symbols: + if (!full_name.empty()) + keep_it = full_name.contains(user_name); } + if (keep_it) + ++i; + else + sc_list.RemoveContextAtIndex(i); } } @@ -1028,7 +1035,9 @@ void Module::FindTypes( llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, TypeMap &types) { - LLDB_SCOPED_TIMER(); + // If a scoped timer is needed, place it in a SymbolFile::FindTypes override. + // A timer here is too high volume for some cases, for example when calling + // FindTypes on each object file. if (SymbolFile *symbols = GetSymbolFile()) symbols->FindTypes(pattern, languages, searched_symbol_files, types); } @@ -1098,27 +1107,6 @@ void Module::GetDescription(llvm::raw_ostream &s, s << llvm::formatv("({0})", object_name); } -void Module::ReportError(const char *format, ...) { - if (format && format[0]) { - StreamString strm; - strm.PutCString("error: "); - GetDescription(strm.AsRawOstream(), lldb::eDescriptionLevelBrief); - strm.PutChar(' '); - va_list args; - va_start(args, format); - strm.PrintfVarArg(format, args); - va_end(args); - - const int format_len = strlen(format); - if (format_len > 0) { - const char last_char = format[format_len - 1]; - if (last_char != '\n' && last_char != '\r') - strm.EOL(); - } - Host::SystemLog(Host::eSystemLogError, "%s", strm.GetData()); - } -} - bool Module::FileHasChanged() const { // We have provided the DataBuffer for this module to avoid accessing the // filesystem. We never want to reload those files. @@ -1130,13 +1118,38 @@ bool Module::FileHasChanged() const { return m_file_has_changed; } +void Module::ReportWarningOptimization( + llvm::Optional<lldb::user_id_t> debugger_id) { + ConstString file_name = GetFileSpec().GetFilename(); + if (file_name.IsEmpty()) + return; + + StreamString ss; + ss << file_name.GetStringRef() + << " was compiled with optimization - stepping may behave " + "oddly; variables may not be available."; + Debugger::ReportWarning(std::string(ss.GetString()), debugger_id, + &m_optimization_warning); +} + +void Module::ReportWarningUnsupportedLanguage( + LanguageType language, llvm::Optional<lldb::user_id_t> debugger_id) { + StreamString ss; + ss << "This version of LLDB has no plugin for the language \"" + << Language::GetNameForLanguageType(language) + << "\". " + "Inspection of frame variables will be limited."; + Debugger::ReportWarning(std::string(ss.GetString()), debugger_id, + &m_language_warning); +} + void Module::ReportErrorIfModifyDetected(const char *format, ...) { if (!m_first_file_changed_log) { if (FileHasChanged()) { m_first_file_changed_log = true; if (format) { StreamString strm; - strm.PutCString("error: the object file "); + strm.PutCString("the object file "); GetDescription(strm.AsRawOstream(), lldb::eDescriptionLevelFull); strm.PutCString(" has been modified\n"); @@ -1152,17 +1165,31 @@ void Module::ReportErrorIfModifyDetected(const char *format, ...) { strm.EOL(); } strm.PutCString("The debug session should be aborted as the original " - "debug information has been overwritten.\n"); - Host::SystemLog(Host::eSystemLogError, "%s", strm.GetData()); + "debug information has been overwritten."); + Debugger::ReportError(std::string(strm.GetString())); } } } } +void Module::ReportError(const char *format, ...) { + if (format && format[0]) { + StreamString strm; + GetDescription(strm.AsRawOstream(), lldb::eDescriptionLevelBrief); + strm.PutChar(' '); + + va_list args; + va_start(args, format); + strm.PrintfVarArg(format, args); + va_end(args); + + Debugger::ReportError(std::string(strm.GetString())); + } +} + void Module::ReportWarning(const char *format, ...) { if (format && format[0]) { StreamString strm; - strm.PutCString("warning: "); GetDescription(strm.AsRawOstream(), lldb::eDescriptionLevelFull); strm.PutChar(' '); @@ -1171,13 +1198,7 @@ void Module::ReportWarning(const char *format, ...) { strm.PrintfVarArg(format, args); va_end(args); - const int format_len = strlen(format); - if (format_len > 0) { - const char last_char = format[format_len - 1]; - if (last_char != '\n' && last_char != '\r') - strm.EOL(); - } - Host::SystemLog(Host::eSystemLogWarning, "%s", strm.GetData()); + Debugger::ReportWarning(std::string(strm.GetString())); } } @@ -1384,7 +1405,6 @@ void Module::PreloadSymbols() { // Now let the symbol file preload its data and the symbol table will be // available without needing to take the module lock. sym_file->PreloadSymbols(); - } void Module::SetSymbolFileFileSpec(const FileSpec &file) { @@ -1629,7 +1649,7 @@ void Module::RegisterXcodeSDK(llvm::StringRef sdk_name, bool Module::MergeArchitecture(const ArchSpec &arch_spec) { if (!arch_spec.IsValid()) return false; - LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_MODULES), + LLDB_LOGF(GetLog(LLDBLog::Object | LLDBLog::Modules), "module has arch %s, merging/replacing with arch %s", m_arch.GetTriple().getTriple().c_str(), arch_spec.GetTriple().getTriple().c_str()); @@ -1690,6 +1710,9 @@ DataFileCache *Module::GetIndexCache() { return nullptr; // NOTE: intentional leak so we don't crash if global destructor chain gets // called as other threads still use the result of this function - static DataFileCache *g_data_file_cache = new DataFileCache(ModuleList::GetGlobalModuleListProperties().GetLLDBIndexCachePath().GetPath()); + static DataFileCache *g_data_file_cache = + new DataFileCache(ModuleList::GetGlobalModuleListProperties() + .GetLLDBIndexCachePath() + .GetPath()); return g_data_file_cache; } diff --git a/contrib/llvm-project/lldb/source/Core/ModuleList.cpp b/contrib/llvm-project/lldb/source/Core/ModuleList.cpp index 48412137546d..1692a3710a3d 100644 --- a/contrib/llvm-project/lldb/source/Core/ModuleList.cpp +++ b/contrib/llvm-project/lldb/source/Core/ModuleList.cpp @@ -22,8 +22,8 @@ #include "lldb/Symbol/VariableList.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" #include "lldb/Utility/UUID.h" #include "lldb/lldb-defines.h" @@ -180,10 +180,15 @@ PathMappingList ModuleListProperties::GetSymlinkMappings() const { return m_symlink_paths; } +bool ModuleListProperties::GetLoadSymbolOnDemand() { + const uint32_t idx = ePropertyLoadSymbolOnDemand; + return m_collection_sp->GetPropertyAtIndexAsBoolean( + nullptr, idx, g_modulelist_properties[idx].default_uint_value != 0); +} + ModuleList::ModuleList() : m_modules(), m_modules_mutex() {} -ModuleList::ModuleList(const ModuleList &rhs) - : m_modules(), m_modules_mutex(), m_notifier(nullptr) { +ModuleList::ModuleList(const ModuleList &rhs) : m_modules(), m_modules_mutex() { std::lock_guard<std::recursive_mutex> lhs_guard(m_modules_mutex); std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_modules_mutex); m_modules = rhs.m_modules; @@ -807,7 +812,7 @@ ModuleList::GetSharedModule(const ModuleSpec &module_spec, ModuleSP &module_sp, if (old_modules) old_modules->push_back(module_sp); - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES)); + Log *log = GetLog(LLDBLog::Modules); if (log != nullptr) LLDB_LOGF( log, "%p '%s' module changed: removing from global module list", diff --git a/contrib/llvm-project/lldb/source/Core/PluginManager.cpp b/contrib/llvm-project/lldb/source/Core/PluginManager.cpp index 37050494aa2e..38a9573411f4 100644 --- a/contrib/llvm-project/lldb/source/Core/PluginManager.cpp +++ b/contrib/llvm-project/lldb/source/Core/PluginManager.cpp @@ -621,9 +621,10 @@ struct ObjectFileInstance : public PluginInstance<ObjectFileCreateInstance> { CallbackType create_callback, ObjectFileCreateMemoryInstance create_memory_callback, ObjectFileGetModuleSpecifications get_module_specifications, - ObjectFileSaveCore save_core) - : PluginInstance<ObjectFileCreateInstance>(name, description, - create_callback), + ObjectFileSaveCore save_core, + DebuggerInitializeCallback debugger_init_callback) + : PluginInstance<ObjectFileCreateInstance>( + name, description, create_callback, debugger_init_callback), create_memory_callback(create_memory_callback), get_module_specifications(get_module_specifications), save_core(save_core) {} @@ -644,10 +645,11 @@ bool PluginManager::RegisterPlugin( ObjectFileCreateInstance create_callback, ObjectFileCreateMemoryInstance create_memory_callback, ObjectFileGetModuleSpecifications get_module_specifications, - ObjectFileSaveCore save_core) { + ObjectFileSaveCore save_core, + DebuggerInitializeCallback debugger_init_callback) { return GetObjectFileInstances().RegisterPlugin( name, description, create_callback, create_memory_callback, - get_module_specifications, save_core); + get_module_specifications, save_core, debugger_init_callback); } bool PluginManager::UnregisterPlugin(ObjectFileCreateInstance create_callback) { @@ -1031,14 +1033,14 @@ PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) { #pragma mark Trace struct TraceInstance - : public PluginInstance<TraceCreateInstanceForSessionFile> { + : public PluginInstance<TraceCreateInstanceFromBundle> { TraceInstance( llvm::StringRef name, llvm::StringRef description, - CallbackType create_callback_for_session_file, + CallbackType create_callback_from_bundle, TraceCreateInstanceForLiveProcess create_callback_for_live_process, llvm::StringRef schema) - : PluginInstance<TraceCreateInstanceForSessionFile>( - name, description, create_callback_for_session_file), + : PluginInstance<TraceCreateInstanceFromBundle>( + name, description, create_callback_from_bundle), schema(schema), create_callback_for_live_process(create_callback_for_live_process) {} @@ -1055,21 +1057,21 @@ static TraceInstances &GetTracePluginInstances() { bool PluginManager::RegisterPlugin( llvm::StringRef name, llvm::StringRef description, - TraceCreateInstanceForSessionFile create_callback_for_session_file, + TraceCreateInstanceFromBundle create_callback_from_bundle, TraceCreateInstanceForLiveProcess create_callback_for_live_process, llvm::StringRef schema) { return GetTracePluginInstances().RegisterPlugin( - name, description, create_callback_for_session_file, + name, description, create_callback_from_bundle, create_callback_for_live_process, schema); } bool PluginManager::UnregisterPlugin( - TraceCreateInstanceForSessionFile create_callback_for_session_file) { + TraceCreateInstanceFromBundle create_callback_from_bundle) { return GetTracePluginInstances().UnregisterPlugin( - create_callback_for_session_file); + create_callback_from_bundle); } -TraceCreateInstanceForSessionFile +TraceCreateInstanceFromBundle PluginManager::GetTraceCreateCallback(llvm::StringRef plugin_name) { return GetTracePluginInstances().GetCallbackForName(plugin_name); } @@ -1364,6 +1366,7 @@ LanguageSet PluginManager::GetREPLAllTypeSystemSupportedLanguages() { void PluginManager::DebuggerInitialize(Debugger &debugger) { GetDynamicLoaderInstances().PerformDebuggerCallback(debugger); GetJITLoaderInstances().PerformDebuggerCallback(debugger); + GetObjectFileInstances().PerformDebuggerCallback(debugger); GetPlatformInstances().PerformDebuggerCallback(debugger); GetProcessInstances().PerformDebuggerCallback(debugger); GetSymbolFileInstances().PerformDebuggerCallback(debugger); @@ -1490,6 +1493,7 @@ CreateSettingForPlugin(Debugger &debugger, ConstString plugin_type_name, static const char *kDynamicLoaderPluginName("dynamic-loader"); static const char *kPlatformPluginName("platform"); static const char *kProcessPluginName("process"); +static const char *kObjectFilePluginName("object-file"); static const char *kSymbolFilePluginName("symbol-file"); static const char *kJITLoaderPluginName("jit-loader"); static const char *kStructuredDataPluginName("structured-data"); @@ -1543,6 +1547,22 @@ bool PluginManager::CreateSettingForProcessPlugin( } lldb::OptionValuePropertiesSP +PluginManager::GetSettingForObjectFilePlugin(Debugger &debugger, + ConstString setting_name) { + return GetSettingForPlugin(debugger, setting_name, + ConstString(kObjectFilePluginName)); +} + +bool PluginManager::CreateSettingForObjectFilePlugin( + Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, + ConstString description, bool is_global_property) { + return CreateSettingForPlugin( + debugger, ConstString(kObjectFilePluginName), + ConstString("Settings for object file plug-ins"), properties_sp, + description, is_global_property); +} + +lldb::OptionValuePropertiesSP PluginManager::GetSettingForSymbolFilePlugin(Debugger &debugger, ConstString setting_name) { return GetSettingForPlugin(debugger, setting_name, diff --git a/contrib/llvm-project/lldb/source/Core/RichManglingContext.cpp b/contrib/llvm-project/lldb/source/Core/RichManglingContext.cpp index cecb5c6a2e54..64b18b401f2d 100644 --- a/contrib/llvm-project/lldb/source/Core/RichManglingContext.cpp +++ b/contrib/llvm-project/lldb/source/Core/RichManglingContext.cpp @@ -7,11 +7,8 @@ //===----------------------------------------------------------------------===// #include "lldb/Core/RichManglingContext.h" - -#include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" - #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" +#include "lldb/Utility/LLDBLog.h" #include "llvm/ADT/StringRef.h" @@ -47,7 +44,7 @@ bool RichManglingContext::FromItaniumName(ConstString mangled) { ResetProvider(ItaniumPartialDemangler); } - if (Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE)) { + if (Log *log = GetLog(LLDBLog::Demangle)) { if (!err) { ParseFullName(); LLDB_LOG(log, "demangled itanium: {0} -> \"{1}\"", mangled, m_ipd_buf); @@ -103,7 +100,7 @@ llvm::StringRef RichManglingContext::processIPDStrResult(char *ipd_res, m_ipd_buf = ipd_res; // std::realloc freed or reused the old buffer. m_ipd_buf_size = res_size; // May actually be bigger, but we can't know. - if (Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE)) + if (Log *log = GetLog(LLDBLog::Demangle)) LLDB_LOG(log, "ItaniumPartialDemangler Realloc: new buffer size is {0}", m_ipd_buf_size); } @@ -126,6 +123,7 @@ llvm::StringRef RichManglingContext::ParseFunctionBaseName() { case None: return {}; } + llvm_unreachable("Fully covered switch above!"); } llvm::StringRef RichManglingContext::ParseFunctionDeclContextName() { @@ -142,6 +140,7 @@ llvm::StringRef RichManglingContext::ParseFunctionDeclContextName() { case None: return {}; } + llvm_unreachable("Fully covered switch above!"); } llvm::StringRef RichManglingContext::ParseFullName() { @@ -159,4 +158,5 @@ llvm::StringRef RichManglingContext::ParseFullName() { case None: return {}; } + llvm_unreachable("Fully covered switch above!"); } diff --git a/contrib/llvm-project/lldb/source/Core/Section.cpp b/contrib/llvm-project/lldb/source/Core/Section.cpp index 1660e3c92f2c..50c1562f7561 100644 --- a/contrib/llvm-project/lldb/source/Core/Section.cpp +++ b/contrib/llvm-project/lldb/source/Core/Section.cpp @@ -164,12 +164,6 @@ Section::Section(const ModuleSP &module_sp, ObjectFile *obj_file, m_log2align(log2align), m_children(), m_fake(false), m_encrypted(false), m_thread_specific(false), m_readable(false), m_writable(false), m_executable(false), m_relocated(false), m_target_byte_size(target_byte_size) { - // printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ", - // addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 " - // - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s\n", - // this, module_sp.get(), sect_id, file_addr, file_addr + - // byte_size, file_offset, file_offset + file_size, flags, - // name.GetCString()); } Section::Section(const lldb::SectionSP &parent_section_sp, @@ -186,19 +180,11 @@ Section::Section(const lldb::SectionSP &parent_section_sp, m_log2align(log2align), m_children(), m_fake(false), m_encrypted(false), m_thread_specific(false), m_readable(false), m_writable(false), m_executable(false), m_relocated(false), m_target_byte_size(target_byte_size) { - // printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ", - // addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 " - // - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s.%s\n", - // this, module_sp.get(), sect_id, file_addr, file_addr + - // byte_size, file_offset, file_offset + file_size, flags, - // parent_section_sp->GetName().GetCString(), name.GetCString()); if (parent_section_sp) m_parent_wp = parent_section_sp; } -Section::~Section() { - // printf ("Section::~Section(%p)\n", this); -} +Section::~Section() = default; addr_t Section::GetFileAddress() const { SectionSP parent_sp(GetParent()); @@ -423,9 +409,15 @@ bool Section::ContainsOnlyDebugInfo() const { case eSectionTypeGoSymtab: case eSectionTypeAbsoluteAddress: case eSectionTypeOther: + // Used for "__dof_cache" in mach-o or ".debug" for COFF which isn't debug + // information that we parse at all. This was causing system files with no + // debug info to show debug info byte sizes in the "statistics dump" output + // for each module. New "eSectionType" enums should be created for dedicated + // debug info that has a predefined format if we wish for these sections to + // show up as debug info. + case eSectionTypeDebug: return false; - case eSectionTypeDebug: case eSectionTypeDWARFDebugAbbrev: case eSectionTypeDWARFDebugAbbrevDwo: case eSectionTypeDWARFDebugAddr: diff --git a/contrib/llvm-project/lldb/source/Core/SourceLocationSpec.cpp b/contrib/llvm-project/lldb/source/Core/SourceLocationSpec.cpp index 610754bb187c..c83d2d89370d 100644 --- a/contrib/llvm-project/lldb/source/Core/SourceLocationSpec.cpp +++ b/contrib/llvm-project/lldb/source/Core/SourceLocationSpec.cpp @@ -16,7 +16,7 @@ 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)), + column.value_or(LLDB_INVALID_COLUMN_NUMBER)), m_check_inlines(check_inlines), m_exact_match(exact_match) {} SourceLocationSpec::operator bool() const { return m_declaration.IsValid(); } diff --git a/contrib/llvm-project/lldb/source/Core/SourceManager.cpp b/contrib/llvm-project/lldb/source/Core/SourceManager.cpp index effba485f026..0e2157f377e0 100644 --- a/contrib/llvm-project/lldb/source/Core/SourceManager.cpp +++ b/contrib/llvm-project/lldb/source/Core/SourceManager.cpp @@ -25,7 +25,6 @@ #include "lldb/Utility/AnsiTerminal.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataBuffer.h" -#include "lldb/Utility/DataBufferLLVM.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Stream.h" #include "lldb/lldb-enumerations.h" @@ -50,6 +49,14 @@ using namespace lldb_private; static inline bool is_newline_char(char ch) { return ch == '\n' || ch == '\r'; } +static void resolve_tilde(FileSpec &file_spec) { + if (!FileSystem::Instance().Exists(file_spec) && + file_spec.GetDirectory() && + file_spec.GetDirectory().GetCString()[0] == '~') { + FileSystem::Instance().Resolve(file_spec); + } +} + // SourceManager constructor SourceManager::SourceManager(const TargetSP &target_sp) : m_last_line(0), m_last_count(0), m_default_set(false), @@ -67,10 +74,13 @@ SourceManager::FileSP SourceManager::GetFile(const FileSpec &file_spec) { if (!file_spec) return nullptr; + FileSpec resolved_fspec = file_spec; + resolve_tilde(resolved_fspec); + DebuggerSP debugger_sp(m_debugger_wp.lock()); FileSP file_sp; if (debugger_sp && debugger_sp->GetUseSourceCache()) - file_sp = debugger_sp->GetSourceFileCache().FindSourceFile(file_spec); + file_sp = debugger_sp->GetSourceFileCache().FindSourceFile(resolved_fspec); TargetSP target_sp(m_target_wp.lock()); @@ -88,9 +98,9 @@ SourceManager::FileSP SourceManager::GetFile(const FileSpec &file_spec) { // If file_sp is no good or it points to a non-existent file, reset it. if (!file_sp || !FileSystem::Instance().Exists(file_sp->GetFileSpec())) { if (target_sp) - file_sp = std::make_shared<File>(file_spec, target_sp.get()); + file_sp = std::make_shared<File>(resolved_fspec, target_sp.get()); else - file_sp = std::make_shared<File>(file_spec, debugger_sp); + file_sp = std::make_shared<File>(resolved_fspec, debugger_sp); if (debugger_sp && debugger_sp->GetUseSourceCache()) debugger_sp->GetSourceFileCache().AddSourceFile(file_sp); @@ -442,6 +452,7 @@ void SourceManager::File::CommonInitializer(const FileSpec &file_spec, } } } + resolve_tilde(m_file_spec); // Try remapping if m_file_spec does not correspond to an existing file. if (!FileSystem::Instance().Exists(m_file_spec)) { // Check target specific source remappings (i.e., the @@ -645,7 +656,7 @@ bool SourceManager::File::CalculateLineOffsets(uint32_t line) { if (m_data_sp.get() == nullptr) return false; - const char *start = (char *)m_data_sp->GetBytes(); + const char *start = (const char *)m_data_sp->GetBytes(); if (start) { const char *end = start + m_data_sp->GetByteSize(); @@ -695,7 +706,7 @@ bool SourceManager::File::GetLine(uint32_t line_no, std::string &buffer) { if (end_offset == UINT32_MAX) { end_offset = m_data_sp->GetByteSize(); } - buffer.assign((char *)m_data_sp->GetBytes() + start_offset, + buffer.assign((const char *)m_data_sp->GetBytes() + start_offset, end_offset - start_offset); return true; diff --git a/contrib/llvm-project/lldb/source/Core/StreamAsynchronousIO.cpp b/contrib/llvm-project/lldb/source/Core/StreamAsynchronousIO.cpp index 04195a6d13ea..c2c64b61ab72 100644 --- a/contrib/llvm-project/lldb/source/Core/StreamAsynchronousIO.cpp +++ b/contrib/llvm-project/lldb/source/Core/StreamAsynchronousIO.cpp @@ -14,8 +14,9 @@ using namespace lldb; using namespace lldb_private; -StreamAsynchronousIO::StreamAsynchronousIO(Debugger &debugger, bool for_stdout) - : Stream(0, 4, eByteOrderBig), m_debugger(debugger), m_data(), +StreamAsynchronousIO::StreamAsynchronousIO(Debugger &debugger, bool for_stdout, + bool colors) + : Stream(0, 4, eByteOrderBig, colors), m_debugger(debugger), m_data(), m_for_stdout(for_stdout) {} StreamAsynchronousIO::~StreamAsynchronousIO() { diff --git a/contrib/llvm-project/lldb/source/Core/StreamFile.cpp b/contrib/llvm-project/lldb/source/Core/StreamFile.cpp index 7753397ae0f1..8aac0b6d6306 100644 --- a/contrib/llvm-project/lldb/source/Core/StreamFile.cpp +++ b/contrib/llvm-project/lldb/source/Core/StreamFile.cpp @@ -8,6 +8,7 @@ #include "lldb/Core/StreamFile.h" #include "lldb/Host/FileSystem.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include <cstdio> @@ -37,7 +38,7 @@ StreamFile::StreamFile(const char *path, File::OpenOptions options, m_file_sp = std::move(file.get()); else { // TODO refactor this so the error gets popagated up instead of logged here. - LLDB_LOG_ERROR(GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST), file.takeError(), + LLDB_LOG_ERROR(GetLog(LLDBLog::Host), file.takeError(), "Cannot open {1}: {0}", path); m_file_sp = std::make_shared<File>(); } diff --git a/contrib/llvm-project/lldb/source/Core/Value.cpp b/contrib/llvm-project/lldb/source/Core/Value.cpp index fb57c0fedf04..2b60dd6f00fa 100644 --- a/contrib/llvm-project/lldb/source/Core/Value.cpp +++ b/contrib/llvm-project/lldb/source/Core/Value.cpp @@ -41,13 +41,10 @@ using namespace lldb_private; 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(ValueType::Scalar), m_context_type(ContextType::Invalid), - m_data_buffer() {} + : m_value(scalar), m_compiler_type(), m_data_buffer() {} Value::Value(const void *bytes, int len) - : m_value(), m_compiler_type(), m_context(nullptr), - m_value_type(ValueType::HostAddress), m_context_type(ContextType::Invalid), + : m_value(), m_compiler_type(), m_value_type(ValueType::HostAddress), m_data_buffer() { SetBytes(bytes, len); } @@ -665,13 +662,6 @@ void Value::ConvertToLoadAddress(Module *module, Target *target) { GetScalar() = load_addr; } -ValueList::ValueList(const ValueList &rhs) { m_values = rhs.m_values; } - -const ValueList &ValueList::operator=(const ValueList &rhs) { - m_values = rhs.m_values; - return *this; -} - void ValueList::PushValue(const Value &value) { m_values.push_back(value); } size_t ValueList::GetSize() { return m_values.size(); } diff --git a/contrib/llvm-project/lldb/source/Core/ValueObject.cpp b/contrib/llvm-project/lldb/source/Core/ValueObject.cpp index 6794d0c7331d..d80139ab1840 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObject.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObject.cpp @@ -42,8 +42,8 @@ #include "lldb/Utility/DataBuffer.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Flags.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" #include "lldb/Utility/Scalar.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" @@ -200,7 +200,7 @@ bool ValueObject::UpdateValueIfNeeded(bool update_format) { } bool ValueObject::UpdateFormatsIfNeeded() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS)); + Log *log = GetLog(LLDBLog::DataFormatters); LLDB_LOGF(log, "[%s %p] checking for FormatManager revisions. ValueObject " "rev: %d - Global rev: %d", @@ -265,7 +265,7 @@ CompilerType ValueObject::MaybeCalculateCompleteType() { process_sp->GetLanguageRuntime(GetObjectRuntimeLanguage())) { if (llvm::Optional<CompilerType> complete_type = runtime->GetRuntimeType(compiler_type)) { - m_override_type = complete_type.getValue(); + m_override_type = *complete_type; if (m_override_type.IsValid()) return m_override_type; } @@ -792,7 +792,7 @@ bool ValueObject::SetData(DataExtractor &data, Status &error) { uint64_t count = 0; const Encoding encoding = GetCompilerType().GetEncoding(count); - const size_t byte_size = GetByteSize().getValueOr(0); + const size_t byte_size = GetByteSize().value_or(0); Value::ValueType value_type = m_value.GetValueType(); @@ -848,18 +848,18 @@ bool ValueObject::SetData(DataExtractor &data, Status &error) { } static bool CopyStringDataToBufferSP(const StreamString &source, - lldb::DataBufferSP &destination) { + lldb::WritableDataBufferSP &destination) { llvm::StringRef src = source.GetString(); - src.consume_back(llvm::StringRef("\0", 1)); + src = src.rtrim('\0'); destination = std::make_shared<DataBufferHeap>(src.size(), 0); memcpy(destination->GetBytes(), src.data(), src.size()); return true; } std::pair<size_t, bool> -ValueObject::ReadPointedString(lldb::DataBufferSP &buffer_sp, Status &error, - uint32_t max_length, bool honor_array, - Format item_format) { +ValueObject::ReadPointedString(lldb::WritableDataBufferSP &buffer_sp, + Status &error, uint32_t max_length, + bool honor_array, Format item_format) { bool was_capped = false; StreamString s; ExecutionContext exe_ctx(GetExecutionContextRef()); @@ -1184,7 +1184,7 @@ bool ValueObject::DumpPrintableRepresentation( eFormatVectorOfChar)) // print char[] & char* directly { Status error; - lldb::DataBufferSP buffer_sp; + lldb::WritableDataBufferSP buffer_sp; std::pair<size_t, bool> read_string = ReadPointedString( buffer_sp, error, 0, (custom_format == eFormatVectorOfChar) || (custom_format == eFormatCharArray)); @@ -1474,7 +1474,7 @@ bool ValueObject::SetValueFromCString(const char *value_str, Status &error) { uint64_t count = 0; const Encoding encoding = GetCompilerType().GetEncoding(count); - const size_t byte_size = GetByteSize().getValueOr(0); + const size_t byte_size = GetByteSize().value_or(0); Value::ValueType value_type = m_value.GetValueType(); @@ -1656,13 +1656,13 @@ ValueObjectSP ValueObject::GetSyntheticBitFieldChild(uint32_t from, uint32_t to, uint32_t bit_field_offset = from; if (GetDataExtractor().GetByteOrder() == eByteOrderBig) bit_field_offset = - GetByteSize().getValueOr(0) * 8 - bit_field_size - bit_field_offset; + GetByteSize().value_or(0) * 8 - bit_field_size - bit_field_offset; // We haven't made a synthetic array member for INDEX yet, so lets make // one and cache it for any future reference. ValueObjectChild *synthetic_child = new ValueObjectChild( - *this, GetCompilerType(), index_const_str, - GetByteSize().getValueOr(0), 0, bit_field_size, bit_field_offset, - false, false, eAddressTypeInvalid, 0); + *this, GetCompilerType(), index_const_str, GetByteSize().value_or(0), + 0, bit_field_size, bit_field_offset, false, false, + eAddressTypeInvalid, 0); // Cache the value if we got one back... if (synthetic_child) { @@ -2803,7 +2803,7 @@ ValueObject::EvaluationPoint::EvaluationPoint() : m_mod_id(), m_exe_ctx_ref() {} ValueObject::EvaluationPoint::EvaluationPoint(ExecutionContextScope *exe_scope, bool use_selected) - : m_mod_id(), m_exe_ctx_ref(), m_needs_update(true) { + : m_mod_id(), m_exe_ctx_ref() { ExecutionContext exe_ctx(exe_scope); TargetSP target_sp(exe_ctx.GetTargetSP()); if (target_sp) { @@ -2840,7 +2840,7 @@ ValueObject::EvaluationPoint::EvaluationPoint(ExecutionContextScope *exe_scope, ValueObject::EvaluationPoint::EvaluationPoint( const ValueObject::EvaluationPoint &rhs) - : m_mod_id(), m_exe_ctx_ref(rhs.m_exe_ctx_ref), m_needs_update(true) {} + : m_mod_id(), m_exe_ctx_ref(rhs.m_exe_ctx_ref) {} ValueObject::EvaluationPoint::~EvaluationPoint() = default; diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectChild.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectChild.cpp index a2beeb0bcdeb..d61d2021c318 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObjectChild.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObjectChild.cpp @@ -82,7 +82,7 @@ ConstString ValueObjectChild::GetDisplayTypeName() { } LazyBool ValueObjectChild::CanUpdateWithInvalidExecutionContext() { - if (m_can_update_with_invalid_exe_ctx.hasValue()) + if (m_can_update_with_invalid_exe_ctx) return m_can_update_with_invalid_exe_ctx.getValue(); if (m_parent) { ValueObject *opinionated_parent = diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectDynamicValue.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectDynamicValue.cpp index bf087f33c0e9..cc5c481cdbb5 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObjectDynamicValue.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObjectDynamicValue.cpp @@ -16,8 +16,8 @@ #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" #include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-types.h" @@ -201,7 +201,7 @@ bool ValueObjectDynamicValue::UpdateValue() { Value old_value(m_value); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES)); + Log *log = GetLog(LLDBLog::Types); bool has_changed_type = false; diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectRegister.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectRegister.cpp index 743083a2d1ed..2aa0c68ba40f 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObjectRegister.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObjectRegister.cpp @@ -18,6 +18,7 @@ #include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" @@ -202,9 +203,8 @@ CompilerType ValueObjectRegister::GetCompilerTypeImpl() { auto type_system_or_err = exe_module->GetTypeSystemForLanguage(eLanguageTypeC); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR( - lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TYPES), - std::move(err), "Unable to get CompilerType from TypeSystem"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Types), std::move(err), + "Unable to get CompilerType from TypeSystem"); } else { m_compiler_type = type_system_or_err->GetBuiltinTypeForEncodingAndBitSize( @@ -269,26 +269,30 @@ bool ValueObjectRegister::SetValueFromCString(const char *value_str, // The new value will be in the m_data. Copy that into our register value. error = m_reg_value.SetValueFromString(&m_reg_info, llvm::StringRef(value_str)); - if (error.Success()) { - if (m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) { - SetNeedsUpdate(); - return true; - } else - return false; - } else + if (!error.Success()) return false; + + if (!m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) { + error.SetErrorString("unable to write back to register"); + return false; + } + + SetNeedsUpdate(); + return true; } bool ValueObjectRegister::SetData(DataExtractor &data, Status &error) { error = m_reg_value.SetValueFromData(&m_reg_info, data, 0, false); - if (error.Success()) { - if (m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) { - SetNeedsUpdate(); - return true; - } else - return false; - } else + if (!error.Success()) return false; + + if (!m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) { + error.SetErrorString("unable to write back to register"); + return false; + } + + SetNeedsUpdate(); + return true; } bool ValueObjectRegister::ResolveValue(Scalar &scalar) { diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectSyntheticFilter.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectSyntheticFilter.cpp index aa55e3965706..a1001b396912 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObjectSyntheticFilter.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObjectSyntheticFilter.cpp @@ -12,8 +12,8 @@ #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/TypeSynthetic.h" #include "lldb/Target/ExecutionContext.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" #include "lldb/Utility/Status.h" #include "llvm/ADT/STLExtras.h" @@ -81,7 +81,7 @@ ConstString ValueObjectSynthetic::GetDisplayTypeName() { } size_t ValueObjectSynthetic::CalculateNumChildren(uint32_t max) { - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS); + Log *log = GetLog(LLDBLog::DataFormatters); UpdateValueIfNeeded(); if (m_synthetic_children_count < UINT32_MAX) @@ -148,7 +148,7 @@ void ValueObjectSynthetic::CreateSynthFilter() { } bool ValueObjectSynthetic::UpdateValue() { - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS); + Log *log = GetLog(LLDBLog::DataFormatters); SetValueIsValid(false); m_error.Clear(); @@ -234,7 +234,7 @@ bool ValueObjectSynthetic::UpdateValue() { lldb::ValueObjectSP ValueObjectSynthetic::GetChildAtIndex(size_t idx, bool can_create) { - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS); + Log *log = GetLog(LLDBLog::DataFormatters); LLDB_LOGF(log, "[ValueObjectSynthetic::GetChildAtIndex] name=%s, retrieving " diff --git a/contrib/llvm-project/lldb/source/DataFormatters/DumpValueObjectOptions.cpp b/contrib/llvm-project/lldb/source/DataFormatters/DumpValueObjectOptions.cpp index 46a2a489586b..38de4428bb23 100644 --- a/contrib/llvm-project/lldb/source/DataFormatters/DumpValueObjectOptions.cpp +++ b/contrib/llvm-project/lldb/source/DataFormatters/DumpValueObjectOptions.cpp @@ -38,8 +38,9 @@ DumpValueObjectOptions::SetMaximumPointerDepth(PointerDepth depth) { } DumpValueObjectOptions & -DumpValueObjectOptions::SetMaximumDepth(uint32_t depth) { +DumpValueObjectOptions::SetMaximumDepth(uint32_t depth, bool is_default) { m_max_depth = depth; + m_max_depth_is_default = is_default; return *this; } diff --git a/contrib/llvm-project/lldb/source/DataFormatters/FormatManager.cpp b/contrib/llvm-project/lldb/source/DataFormatters/FormatManager.cpp index f07bb9a7136a..a8390c5d79c6 100644 --- a/contrib/llvm-project/lldb/source/DataFormatters/FormatManager.cpp +++ b/contrib/llvm-project/lldb/source/DataFormatters/FormatManager.cpp @@ -8,15 +8,14 @@ #include "lldb/DataFormatters/FormatManager.h" -#include "llvm/ADT/STLExtras.h" - - #include "lldb/Core/Debugger.h" #include "lldb/DataFormatters/FormattersHelpers.h" #include "lldb/DataFormatters/LanguageCategory.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Language.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" +#include "llvm/ADT/STLExtras.h" using namespace lldb; using namespace lldb_private; @@ -90,11 +89,11 @@ static bool GetFormatFromFormatChar(char format_char, Format &format) { return false; } -static bool GetFormatFromFormatName(const char *format_name, +static bool GetFormatFromFormatName(llvm::StringRef format_name, bool partial_match_ok, Format &format) { uint32_t i; for (i = 0; i < g_num_format_infos; ++i) { - if (strcasecmp(g_format_infos[i].format_name, format_name) == 0) { + if (format_name.equals_insensitive(g_format_infos[i].format_name)) { format = g_format_infos[i].format; return true; } @@ -102,8 +101,8 @@ static bool GetFormatFromFormatName(const char *format_name, if (partial_match_ok) { for (i = 0; i < g_num_format_infos; ++i) { - if (strcasestr(g_format_infos[i].format_name, format_name) == - g_format_infos[i].format_name) { + if (llvm::StringRef(g_format_infos[i].format_name) + .startswith_insensitive(format_name)) { format = g_format_infos[i].format; return true; } @@ -614,7 +613,7 @@ ImplSP FormatManager::Get(ValueObject &valobj, if (ImplSP retval_sp = GetCached<ImplSP>(match_data)) return retval_sp; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS)); + Log *log = GetLog(LLDBLog::DataFormatters); LLDB_LOGF(log, "[%s] Search failed. Giving language a chance.", __FUNCTION__); for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) { @@ -637,7 +636,7 @@ ImplSP FormatManager::Get(ValueObject &valobj, template <typename ImplSP> ImplSP FormatManager::GetCached(FormattersMatchData &match_data) { ImplSP retval_sp; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS)); + Log *log = GetLog(LLDBLog::DataFormatters); if (match_data.GetTypeForCache()) { LLDB_LOGF(log, "\n\n[%s] Looking into cache for type %s", __FUNCTION__, match_data.GetTypeForCache().AsCString("<invalid>")); diff --git a/contrib/llvm-project/lldb/source/DataFormatters/StringPrinter.cpp b/contrib/llvm-project/lldb/source/DataFormatters/StringPrinter.cpp index ec8664ebe17a..0dd5d518f60b 100644 --- a/contrib/llvm-project/lldb/source/DataFormatters/StringPrinter.cpp +++ b/contrib/llvm-project/lldb/source/DataFormatters/StringPrinter.cpp @@ -293,7 +293,7 @@ static bool DumpEncodedBufferToStream( data_ptr = (const SourceDataType *)data.GetDataStart(); } - lldb::DataBufferSP utf8_data_buffer_sp; + lldb::WritableDataBufferSP utf8_data_buffer_sp; llvm::UTF8 *utf8_data_ptr = nullptr; llvm::UTF8 *utf8_data_end_ptr = nullptr; @@ -450,7 +450,7 @@ static bool ReadEncodedBufferAndDumpToStream( } const int bufferSPSize = sourceSize * type_width; - lldb::DataBufferSP buffer_sp(new DataBufferHeap(bufferSPSize, 0)); + lldb::WritableDataBufferSP buffer_sp(new DataBufferHeap(bufferSPSize, 0)); // Check if we got bytes. We never get any bytes if we have an empty // string, but we still continue so that we end up actually printing diff --git a/contrib/llvm-project/lldb/source/DataFormatters/TypeCategoryMap.cpp b/contrib/llvm-project/lldb/source/DataFormatters/TypeCategoryMap.cpp index a011c5414ee9..aa8387b4deec 100644 --- a/contrib/llvm-project/lldb/source/DataFormatters/TypeCategoryMap.cpp +++ b/contrib/llvm-project/lldb/source/DataFormatters/TypeCategoryMap.cpp @@ -9,9 +9,9 @@ #include "lldb/DataFormatters/TypeCategoryMap.h" #include "lldb/DataFormatters/FormatClasses.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" - using namespace lldb; using namespace lldb_private; @@ -174,7 +174,7 @@ void TypeCategoryMap::Get(FormattersMatchData &match_data, ImplSP &retval) { ActiveCategoriesIterator begin, end = m_active_categories.end(); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS)); + Log *log = GetLog(LLDBLog::DataFormatters); if (log) { for (auto match : match_data.GetMatchesVector()) { diff --git a/contrib/llvm-project/lldb/source/DataFormatters/TypeFormat.cpp b/contrib/llvm-project/lldb/source/DataFormatters/TypeFormat.cpp index 9c5046687013..ae9d8d806a5b 100644 --- a/contrib/llvm-project/lldb/source/DataFormatters/TypeFormat.cpp +++ b/contrib/llvm-project/lldb/source/DataFormatters/TypeFormat.cpp @@ -77,7 +77,8 @@ bool TypeFormatImpl_Format::FormatObject(ValueObject *valobj, if (target_sp) { size_t max_len = target_sp->GetMaximumSizeOfStringSummary(); Status error; - DataBufferSP buffer_sp(new DataBufferHeap(max_len + 1, 0)); + WritableDataBufferSP buffer_sp( + new DataBufferHeap(max_len + 1, 0)); Address address(valobj->GetPointerValue()); if (target_sp->ReadCStringFromMemory( address, (char *)buffer_sp->GetBytes(), max_len, error) && diff --git a/contrib/llvm-project/lldb/source/DataFormatters/ValueObjectPrinter.cpp b/contrib/llvm-project/lldb/source/DataFormatters/ValueObjectPrinter.cpp index 082ad344d2d1..6fd6308ded5d 100644 --- a/contrib/llvm-project/lldb/source/DataFormatters/ValueObjectPrinter.cpp +++ b/contrib/llvm-project/lldb/source/DataFormatters/ValueObjectPrinter.cpp @@ -500,7 +500,7 @@ bool ValueObjectPrinter::ShouldPrintChildren( if (m_options.m_use_objc) return false; - if (is_failed_description || m_curr_depth < m_options.m_max_depth) { + if (is_failed_description || !HasReachedMaximumDepth()) { // We will show children for all concrete types. We won't show pointer // contents unless a pointer depth has been specified. We won't reference // contents unless the reference is the root object (depth of zero). @@ -786,9 +786,22 @@ void ValueObjectPrinter::PrintChildrenIfNeeded(bool value_printed, m_stream->EOL(); } else PrintChildren(value_printed, summary_printed, curr_ptr_depth); - } else if (m_curr_depth >= m_options.m_max_depth && IsAggregate() && + } else if (HasReachedMaximumDepth() && IsAggregate() && ShouldPrintValueObject()) { m_stream->PutCString("{...}\n"); + // The maximum child depth has been reached. If `m_max_depth` is the default + // (i.e. the user has _not_ customized it), then lldb presents a warning to + // the user. The warning tells the user that the limit has been reached, but + // more importantly tells them how to expand the limit if desired. + if (m_options.m_max_depth_is_default) + m_valobj->GetTargetSP() + ->GetDebugger() + .GetCommandInterpreter() + .SetReachedMaximumDepth(); } else m_stream->EOL(); } + +bool ValueObjectPrinter::HasReachedMaximumDepth() { + return m_curr_depth >= m_options.m_max_depth; +} diff --git a/contrib/llvm-project/lldb/source/DataFormatters/VectorType.cpp b/contrib/llvm-project/lldb/source/DataFormatters/VectorType.cpp index 11371918830b..e35ed881db08 100644 --- a/contrib/llvm-project/lldb/source/DataFormatters/VectorType.cpp +++ b/contrib/llvm-project/lldb/source/DataFormatters/VectorType.cpp @@ -189,8 +189,7 @@ namespace formatters { class VectorTypeSyntheticFrontEnd : public SyntheticChildrenFrontEnd { public: VectorTypeSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) - : SyntheticChildrenFrontEnd(*valobj_sp), m_parent_format(eFormatInvalid), - m_item_format(eFormatInvalid), m_child_type(), m_num_children(0) {} + : SyntheticChildrenFrontEnd(*valobj_sp), m_child_type() {} ~VectorTypeSyntheticFrontEnd() override = default; @@ -238,10 +237,10 @@ public: } private: - lldb::Format m_parent_format; - lldb::Format m_item_format; + lldb::Format m_parent_format = eFormatInvalid; + lldb::Format m_item_format = eFormatInvalid; CompilerType m_child_type; - size_t m_num_children; + size_t m_num_children = 0; }; } // namespace formatters diff --git a/contrib/llvm-project/lldb/source/Expression/DWARFExpression.cpp b/contrib/llvm-project/lldb/source/Expression/DWARFExpression.cpp index ccd41fb4a94e..1f11907dc64c 100644 --- a/contrib/llvm-project/lldb/source/Expression/DWARFExpression.cpp +++ b/contrib/llvm-project/lldb/source/Expression/DWARFExpression.cpp @@ -16,6 +16,7 @@ #include "lldb/Core/Value.h" #include "lldb/Core/dwarf.h" #include "lldb/Utility/DataEncoder.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Scalar.h" @@ -35,11 +36,14 @@ #include "lldb/Target/StackID.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h" +#include "llvm/DebugInfo/DWARF/DWARFExpression.h" #include "Plugins/SymbolFile/DWARF/DWARFUnit.h" using namespace lldb; using namespace lldb_private; +using namespace lldb_private::dwarf; static lldb::addr_t ReadAddressFromDebugAddrSection(const DWARFUnit *dwarf_cu, @@ -60,8 +64,7 @@ DWARFExpression::DWARFExpression() : m_module_wp(), m_data() {} DWARFExpression::DWARFExpression(lldb::ModuleSP module_sp, const DataExtractor &data, const DWARFUnit *dwarf_cu) - : m_module_wp(), m_data(data), m_dwarf_cu(dwarf_cu), - m_reg_kind(eRegisterKindDWARF) { + : m_module_wp(), m_data(data), m_dwarf_cu(dwarf_cu) { if (module_sp) m_module_wp = module_sp; } @@ -126,7 +129,6 @@ private: } void DWARFExpression::GetDescription(Stream *s, lldb::DescriptionLevel level, - addr_t location_list_base_addr, ABI *abi) const { if (IsLocationList()) { // We have a location list @@ -856,29 +858,28 @@ bool DWARFExpression::Evaluate(ExecutionContext *exe_ctx, ModuleSP module_sp = m_module_wp.lock(); if (IsLocationList()) { - addr_t pc; + Address pc; StackFrame *frame = nullptr; - if (reg_ctx) - pc = reg_ctx->GetPC(); - else { + if (!reg_ctx || !reg_ctx->GetPCForSymbolication(pc)) { frame = exe_ctx->GetFramePtr(); if (!frame) return false; RegisterContextSP reg_ctx_sp = frame->GetRegisterContext(); if (!reg_ctx_sp) return false; - pc = reg_ctx_sp->GetPC(); + reg_ctx_sp->GetPCForSymbolication(pc); } if (func_load_addr != LLDB_INVALID_ADDRESS) { - if (pc == LLDB_INVALID_ADDRESS) { + if (!pc.IsValid()) { if (error_ptr) error_ptr->SetErrorString("Invalid PC in frame."); return false; } - if (llvm::Optional<DataExtractor> expr = - GetLocationExpression(func_load_addr, pc)) { + Target *target = exe_ctx->GetTargetPtr(); + if (llvm::Optional<DataExtractor> expr = GetLocationExpression( + func_load_addr, pc.GetLoadAddress(target))) { return DWARFExpression::Evaluate( exe_ctx, reg_ctx, module_sp, *expr, m_dwarf_cu, m_reg_kind, initial_value_ptr, object_address_ptr, result, error_ptr); @@ -941,6 +942,72 @@ void UpdateValueTypeFromLocationDescription(Log *log, const DWARFUnit *dwarf_cu, } } // namespace +/// Helper function to move common code used to resolve a file address and turn +/// into a load address. +/// +/// \param exe_ctx Pointer to the execution context +/// \param module_sp shared_ptr contains the module if we have one +/// \param error_ptr pointer to Status object if we have one +/// \param dw_op_type C-style string used to vary the error output +/// \param file_addr the file address we are trying to resolve and turn into a +/// load address +/// \param so_addr out parameter, will be set to load addresss or section offset +/// \param check_sectionoffset bool which determines if having a section offset +/// but not a load address is considerd a success +/// \returns llvm::Optional containing the load address if resolving and getting +/// the load address succeed or an empty Optinal otherwise. If +/// check_sectionoffset is true we consider LLDB_INVALID_ADDRESS a +/// success if so_addr.IsSectionOffset() is true. +static llvm::Optional<lldb::addr_t> +ResolveLoadAddress(ExecutionContext *exe_ctx, lldb::ModuleSP &module_sp, + Status *error_ptr, const char *dw_op_type, + lldb::addr_t file_addr, Address &so_addr, + bool check_sectionoffset = false) { + if (!module_sp) { + if (error_ptr) + error_ptr->SetErrorStringWithFormat( + "need module to resolve file address for %s", dw_op_type); + return {}; + } + + if (!module_sp->ResolveFileAddress(file_addr, so_addr)) { + if (error_ptr) + error_ptr->SetErrorString("failed to resolve file address in module"); + return {}; + } + + addr_t load_addr = so_addr.GetLoadAddress(exe_ctx->GetTargetPtr()); + + if (load_addr == LLDB_INVALID_ADDRESS && + (check_sectionoffset && !so_addr.IsSectionOffset())) { + if (error_ptr) + error_ptr->SetErrorString("failed to resolve load address"); + return {}; + } + + return load_addr; +} + +/// Helper function to move common code used to load sized data from a uint8_t +/// buffer. +/// +/// \param addr_bytes uint8_t buffer containg raw data +/// \param size_addr_bytes how large is the underlying raw data +/// \param byte_order what is the byter order of the underlyig data +/// \param size How much of the underlying data we want to use +/// \return The underlying data converted into a Scalar +static Scalar DerefSizeExtractDataHelper(uint8_t *addr_bytes, + size_t size_addr_bytes, + ByteOrder byte_order, size_t size) { + DataExtractor addr_data(addr_bytes, size_addr_bytes, byte_order, size); + + lldb::offset_t addr_data_offset = 0; + if (size <= 8) + return addr_data.GetMaxU64(&addr_data_offset, size); + else + return addr_data.GetAddress(&addr_data_offset); +} + bool DWARFExpression::Evaluate( ExecutionContext *exe_ctx, RegisterContext *reg_ctx, lldb::ModuleSP module_sp, const DataExtractor &opcodes, @@ -977,7 +1044,7 @@ bool DWARFExpression::Evaluate( uint64_t op_piece_offset = 0; Value pieces; // Used for DW_OP_piece - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); // A generic type is "an integral type that has the size of an address and an // unspecified signedness". For now, just use the signedness of the operand. // TODO: Implement a real typed stack, and store the genericness of the value @@ -1086,26 +1153,15 @@ bool DWARFExpression::Evaluate( case Value::ValueType::FileAddress: { auto file_addr = stack.back().GetScalar().ULongLong( LLDB_INVALID_ADDRESS); - if (!module_sp) { - if (error_ptr) - error_ptr->SetErrorString( - "need module to resolve file address for DW_OP_deref"); - return false; - } + Address so_addr; - if (!module_sp->ResolveFileAddress(file_addr, so_addr)) { - if (error_ptr) - error_ptr->SetErrorString( - "failed to resolve file address in module"); - return false; - } - addr_t load_Addr = so_addr.GetLoadAddress(exe_ctx->GetTargetPtr()); - if (load_Addr == LLDB_INVALID_ADDRESS) { - if (error_ptr) - error_ptr->SetErrorString("failed to resolve load address"); + auto maybe_load_addr = ResolveLoadAddress( + exe_ctx, module_sp, error_ptr, "DW_OP_deref", file_addr, so_addr); + + if (!maybe_load_addr) return false; - } - stack.back().GetScalar() = load_Addr; + + stack.back().GetScalar() = *maybe_load_addr; // Fall through to load address promotion code below. } LLVM_FALLTHROUGH; case Value::ValueType::Scalar: @@ -1216,6 +1272,47 @@ bool DWARFExpression::Evaluate( stack.back().GetScalar() = ptr; stack.back().ClearContext(); } break; + case Value::ValueType::FileAddress: { + auto file_addr = + stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS); + Address so_addr; + auto maybe_load_addr = + ResolveLoadAddress(exe_ctx, module_sp, error_ptr, + "DW_OP_deref_size", file_addr, so_addr, + /*check_sectionoffset=*/true); + + if (!maybe_load_addr) + return false; + + addr_t load_addr = *maybe_load_addr; + + if (load_addr == LLDB_INVALID_ADDRESS && so_addr.IsSectionOffset()) { + uint8_t addr_bytes[8]; + Status error; + + if (exe_ctx->GetTargetRef().ReadMemory( + so_addr, &addr_bytes, size, error, + /*force_live_memory=*/false) == size) { + ObjectFile *objfile = module_sp->GetObjectFile(); + + stack.back().GetScalar() = DerefSizeExtractDataHelper( + addr_bytes, size, objfile->GetByteOrder(), size); + stack.back().ClearContext(); + break; + } else { + if (error_ptr) + error_ptr->SetErrorStringWithFormat( + "Failed to dereference pointer for for DW_OP_deref_size: " + "%s\n", + error.AsCString()); + return false; + } + } + stack.back().GetScalar() = load_addr; + // Fall through to load address promotion code below. + } + + LLVM_FALLTHROUGH; case Value::ValueType::Scalar: case Value::ValueType::LoadAddress: if (exe_ctx) { @@ -1226,26 +1323,10 @@ bool DWARFExpression::Evaluate( Status error; if (process->ReadMemory(pointer_addr, &addr_bytes, size, error) == size) { - DataExtractor addr_data(addr_bytes, sizeof(addr_bytes), - process->GetByteOrder(), size); - lldb::offset_t addr_data_offset = 0; - switch (size) { - case 1: - stack.back().GetScalar() = addr_data.GetU8(&addr_data_offset); - break; - case 2: - stack.back().GetScalar() = addr_data.GetU16(&addr_data_offset); - break; - case 4: - stack.back().GetScalar() = addr_data.GetU32(&addr_data_offset); - break; - case 8: - stack.back().GetScalar() = addr_data.GetU64(&addr_data_offset); - break; - default: - stack.back().GetScalar() = - addr_data.GetAddress(&addr_data_offset); - } + + stack.back().GetScalar() = + DerefSizeExtractDataHelper(addr_bytes, sizeof(addr_bytes), + process->GetByteOrder(), size); stack.back().ClearContext(); } else { if (error_ptr) @@ -1268,7 +1349,6 @@ bool DWARFExpression::Evaluate( } break; - case Value::ValueType::FileAddress: case Value::ValueType::Invalid: if (error_ptr) error_ptr->SetErrorString("Invalid value for DW_OP_deref_size.\n"); @@ -2670,14 +2750,50 @@ static DataExtractor ToDataExtractor(const llvm::DWARFLocationExpression &loc, return DataExtractor(buffer_sp, byte_order, addr_size); } -llvm::Optional<DataExtractor> -DWARFExpression::GetLocationExpression(addr_t load_function_start, - addr_t addr) const { - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); +bool DWARFExpression::DumpLocations(Stream *s, lldb::DescriptionLevel level, + addr_t load_function_start, addr_t addr, + ABI *abi) { + if (!IsLocationList()) { + DumpLocation(s, m_data, level, abi); + return true; + } + bool dump_all = addr == LLDB_INVALID_ADDRESS; + llvm::ListSeparator separator; + auto callback = [&](llvm::DWARFLocationExpression loc) -> bool { + if (loc.Range && + (dump_all || (loc.Range->LowPC <= addr && addr < loc.Range->HighPC))) { + uint32_t addr_size = m_data.GetAddressByteSize(); + DataExtractor data = ToDataExtractor(loc, m_data.GetByteOrder(), + m_data.GetAddressByteSize()); + s->AsRawOstream() << separator; + s->PutCString("["); + s->AsRawOstream() << llvm::format_hex(loc.Range->LowPC, + 2 + 2 * addr_size); + s->PutCString(", "); + s->AsRawOstream() << llvm::format_hex(loc.Range->HighPC, + 2 + 2 * addr_size); + s->PutCString(") -> "); + DumpLocation(s, data, level, abi); + return dump_all; + } + return true; + }; + if (!GetLocationExpressions(load_function_start, callback)) + return false; + return true; +} + +bool DWARFExpression::GetLocationExpressions( + addr_t load_function_start, + llvm::function_ref<bool(llvm::DWARFLocationExpression)> callback) const { + if (load_function_start == LLDB_INVALID_ADDRESS) + return false; + + Log *log = GetLog(LLDBLog::Expressions); std::unique_ptr<llvm::DWARFLocationTable> loctable_up = m_dwarf_cu->GetLocationTable(m_data); - llvm::Optional<DataExtractor> result; + uint64_t offset = 0; auto lookup_addr = [&](uint32_t index) -> llvm::Optional<llvm::object::SectionedAddress> { @@ -2697,19 +2813,32 @@ DWARFExpression::GetLocationExpression(addr_t load_function_start, addr_t slide = load_function_start - m_loclist_addresses->func_file_addr; loc->Range->LowPC += slide; loc->Range->HighPC += slide; - - if (loc->Range->LowPC <= addr && addr < loc->Range->HighPC) - result = ToDataExtractor(*loc, m_data.GetByteOrder(), - m_data.GetAddressByteSize()); } - return !result; + return callback(*loc); }; - llvm::Error E = loctable_up->visitAbsoluteLocationList( + llvm::Error error = loctable_up->visitAbsoluteLocationList( offset, llvm::object::SectionedAddress{m_loclist_addresses->cu_file_addr}, lookup_addr, process_list); - if (E) - LLDB_LOG_ERROR(log, std::move(E), "{0}"); - return result; + if (error) { + LLDB_LOG_ERROR(log, std::move(error), "{0}"); + return false; + } + return true; +} + +llvm::Optional<DataExtractor> +DWARFExpression::GetLocationExpression(addr_t load_function_start, + addr_t addr) const { + llvm::Optional<DataExtractor> data; + auto callback = [&](llvm::DWARFLocationExpression loc) { + if (loc.Range && loc.Range->LowPC <= addr && addr < loc.Range->HighPC) { + data = ToDataExtractor(loc, m_data.GetByteOrder(), + m_data.GetAddressByteSize()); + } + return !data; + }; + GetLocationExpressions(load_function_start, callback); + return data; } bool DWARFExpression::MatchesOperand(StackFrame &frame, @@ -2732,10 +2861,11 @@ bool DWARFExpression::MatchesOperand(StackFrame &frame, if (load_function_start == LLDB_INVALID_ADDRESS) return false; - addr_t pc = frame.GetFrameCodeAddress().GetLoadAddress( + addr_t pc = frame.GetFrameCodeAddressForSymbolication().GetLoadAddress( frame.CalculateTarget().get()); - if (llvm::Optional<DataExtractor> expr = GetLocationExpression(load_function_start, pc)) + if (llvm::Optional<DataExtractor> expr = + GetLocationExpression(load_function_start, pc)) opcodes = std::move(*expr); else return false; diff --git a/contrib/llvm-project/lldb/source/Expression/ExpressionVariable.cpp b/contrib/llvm-project/lldb/source/Expression/ExpressionVariable.cpp index 565a3d1a8161..da2f3b2a83fb 100644 --- a/contrib/llvm-project/lldb/source/Expression/ExpressionVariable.cpp +++ b/contrib/llvm-project/lldb/source/Expression/ExpressionVariable.cpp @@ -9,6 +9,7 @@ #include "lldb/Expression/ExpressionVariable.h" #include "lldb/Expression/IRExecutionUnit.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" using namespace lldb_private; @@ -41,7 +42,7 @@ lldb::addr_t PersistentExpressionState::LookupSymbol(ConstString name) { void PersistentExpressionState::RegisterExecutionUnit( lldb::IRExecutionUnitSP &execution_unit_sp) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); m_execution_units.insert(execution_unit_sp); diff --git a/contrib/llvm-project/lldb/source/Expression/FunctionCaller.cpp b/contrib/llvm-project/lldb/source/Expression/FunctionCaller.cpp index 5f34675b4b64..307bed1ee3fd 100644 --- a/contrib/llvm-project/lldb/source/Expression/FunctionCaller.cpp +++ b/contrib/llvm-project/lldb/source/Expression/FunctionCaller.cpp @@ -24,6 +24,7 @@ #include "lldb/Target/ThreadPlan.h" #include "lldb/Target/ThreadPlanCallFunction.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/State.h" @@ -218,7 +219,7 @@ bool FunctionCaller::InsertFunction(ExecutionContext &exe_ctx, if (!WriteFunctionArguments(exe_ctx, args_addr_ref, diagnostic_manager)) return false; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); LLDB_LOGF(log, "Call Address: 0x%" PRIx64 " Struct Address: 0x%" PRIx64 ".\n", m_jit_start_addr, args_addr_ref); @@ -229,8 +230,7 @@ lldb::ThreadPlanSP FunctionCaller::GetThreadPlanToCallFunction( ExecutionContext &exe_ctx, lldb::addr_t args_addr, const EvaluateExpressionOptions &options, DiagnosticManager &diagnostic_manager) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS | - LIBLLDB_LOG_STEP)); + Log *log(GetLog(LLDBLog::Expressions | LLDBLog::Step)); LLDB_LOGF(log, "-- [FunctionCaller::GetThreadPlanToCallFunction] Creating " @@ -269,8 +269,7 @@ bool FunctionCaller::FetchFunctionResults(ExecutionContext &exe_ctx, // then use GetReturnValueObject // to fetch the value. That way we can fetch any values we need. - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS | - LIBLLDB_LOG_STEP)); + Log *log(GetLog(LLDBLog::Expressions | LLDBLog::Step)); LLDB_LOGF(log, "-- [FunctionCaller::FetchFunctionResults] Fetching function " @@ -343,8 +342,7 @@ lldb::ExpressionResults FunctionCaller::ExecuteFunction( return lldb::eExpressionSetupError; } - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS | - LIBLLDB_LOG_STEP)); + Log *log(GetLog(LLDBLog::Expressions | LLDBLog::Step)); LLDB_LOGF(log, "== [FunctionCaller::ExecuteFunction] Executing function \"%s\" ==", diff --git a/contrib/llvm-project/lldb/source/Expression/IRExecutionUnit.cpp b/contrib/llvm-project/lldb/source/Expression/IRExecutionUnit.cpp index 3c4a87c27e20..49fa72f7112d 100644 --- a/contrib/llvm-project/lldb/source/Expression/IRExecutionUnit.cpp +++ b/contrib/llvm-project/lldb/source/Expression/IRExecutionUnit.cpp @@ -21,6 +21,7 @@ #include "lldb/Core/Module.h" #include "lldb/Core/Section.h" #include "lldb/Expression/IRExecutionUnit.h" +#include "lldb/Host/HostInfo.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/SymbolFile.h" @@ -32,6 +33,7 @@ #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/../../source/Plugins/ObjectFile/JIT/ObjectFileJIT.h" @@ -70,8 +72,7 @@ lldb::addr_t IRExecutionUnit::WriteNow(const uint8_t *bytes, size_t size, return LLDB_INVALID_ADDRESS; } - if (Log *log = - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)) { + if (Log *log = GetLog(LLDBLog::Expressions)) { DataBufferHeap my_buffer(size, 0); Status err; ReadMemory(my_buffer.GetBytes(), allocation_process_addr, size, err); @@ -99,7 +100,7 @@ void IRExecutionUnit::FreeNow(lldb::addr_t allocation) { Status IRExecutionUnit::DisassembleFunction(Stream &stream, lldb::ProcessSP &process_wp) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); ExecutionContext exe_ctx(process_wp); @@ -150,7 +151,8 @@ Status IRExecutionUnit::DisassembleFunction(Stream &stream, return ret; } - lldb::DataBufferSP buffer_sp(new DataBufferHeap(func_range.second, 0)); + lldb::WritableDataBufferSP buffer_sp( + new DataBufferHeap(func_range.second, 0)); Process *process = exe_ctx.GetProcessPtr(); Status err; @@ -254,7 +256,7 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr, m_did_jit = true; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); std::string error_string; @@ -306,27 +308,37 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr, class ObjectDumper : public llvm::ObjectCache { public: + ObjectDumper(FileSpec output_dir) : m_out_dir(output_dir) {} void notifyObjectCompiled(const llvm::Module *module, llvm::MemoryBufferRef object) override { int fd = 0; llvm::SmallVector<char, 256> result_path; std::string object_name_model = "jit-object-" + module->getModuleIdentifier() + "-%%%.o"; - (void)llvm::sys::fs::createUniqueFile(object_name_model, fd, result_path); - llvm::raw_fd_ostream fds(fd, true); - fds.write(object.getBufferStart(), object.getBufferSize()); + FileSpec model_spec + = m_out_dir.CopyByAppendingPathComponent(object_name_model); + std::string model_path = model_spec.GetPath(); + + std::error_code result + = llvm::sys::fs::createUniqueFile(model_path, fd, result_path); + if (!result) { + llvm::raw_fd_ostream fds(fd, true); + fds.write(object.getBufferStart(), object.getBufferSize()); + } } - std::unique_ptr<llvm::MemoryBuffer> - getObject(const llvm::Module *module) override { + getObject(const llvm::Module *module) override { // Return nothing - we're just abusing the object-cache mechanism to dump // objects. return nullptr; - } + } + private: + FileSpec m_out_dir; }; - if (process_sp->GetTarget().GetEnableSaveObjects()) { - m_object_cache_up = std::make_unique<ObjectDumper>(); + FileSpec save_objects_dir = process_sp->GetTarget().GetSaveJITObjectsDir(); + if (save_objects_dir) { + m_object_cache_up = std::make_unique<ObjectDumper>(save_objects_dir); m_execution_engine_up->setObjectCache(m_object_cache_up.get()); } @@ -592,7 +604,7 @@ lldb::SectionType IRExecutionUnit::GetSectionTypeFromSectionName( uint8_t *IRExecutionUnit::MemoryManager::allocateCodeSection( uintptr_t Size, unsigned Alignment, unsigned SectionID, llvm::StringRef SectionName) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); uint8_t *return_value = m_default_mm_up->allocateCodeSection( Size, Alignment, SectionID, SectionName); @@ -622,7 +634,7 @@ uint8_t *IRExecutionUnit::MemoryManager::allocateCodeSection( uint8_t *IRExecutionUnit::MemoryManager::allocateDataSection( uintptr_t Size, unsigned Alignment, unsigned SectionID, llvm::StringRef SectionName, bool IsReadOnly) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); uint8_t *return_value = m_default_mm_up->allocateDataSection( Size, Alignment, SectionID, SectionName, IsReadOnly); @@ -882,7 +894,7 @@ lldb::addr_t IRExecutionUnit::FindSymbol(lldb_private::ConstString name, void IRExecutionUnit::GetStaticInitializers( std::vector<lldb::addr_t> &static_initializers) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); llvm::GlobalVariable *global_ctors = m_module->getNamedGlobal("llvm.global_ctors"); @@ -950,7 +962,7 @@ IRExecutionUnit::MemoryManager::getSymbolAddress(const std::string &Name) { uint64_t IRExecutionUnit::MemoryManager::GetSymbolAddressAndPresence( const std::string &Name, bool &missing_weak) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); ConstString name_cs(Name.c_str()); @@ -977,7 +989,7 @@ void *IRExecutionUnit::MemoryManager::getPointerToNamedFunction( lldb::addr_t IRExecutionUnit::GetRemoteAddressForLocal(lldb::addr_t local_address) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); for (AllocationRecord &record : m_records) { if (local_address >= record.m_host_address && diff --git a/contrib/llvm-project/lldb/source/Expression/IRInterpreter.cpp b/contrib/llvm-project/lldb/source/Expression/IRInterpreter.cpp index 9b2af56dfc8a..a6efeb3f960f 100644 --- a/contrib/llvm-project/lldb/source/Expression/IRInterpreter.cpp +++ b/contrib/llvm-project/lldb/source/Expression/IRInterpreter.cpp @@ -16,6 +16,7 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" @@ -41,6 +42,7 @@ #include <map> using namespace llvm; +using lldb_private::LLDBLog; static std::string PrintValue(const Value *value, bool truncate = false) { std::string s; @@ -95,8 +97,8 @@ public: ValueMap m_values; DataLayout &m_target_data; lldb_private::IRExecutionUnit &m_execution_unit; - const BasicBlock *m_bb; - const BasicBlock *m_prev_bb; + const BasicBlock *m_bb = nullptr; + const BasicBlock *m_prev_bb = nullptr; BasicBlock::const_iterator m_ii; BasicBlock::const_iterator m_ie; @@ -111,8 +113,7 @@ public: lldb_private::IRExecutionUnit &execution_unit, lldb::addr_t stack_frame_bottom, lldb::addr_t stack_frame_top) - : m_target_data(target_data), m_execution_unit(execution_unit), - m_bb(nullptr), m_prev_bb(nullptr) { + : m_target_data(target_data), m_execution_unit(execution_unit) { m_byte_order = (target_data.isLittleEndian() ? lldb::eByteOrderLittle : lldb::eByteOrderBig); m_addr_byte_size = (target_data.getPointerSize(0)); @@ -283,9 +284,11 @@ public: return true; // no offset to apply! SmallVector<Value *, 8> indices(op_cursor, op_end); - Type *src_elem_ty = cast<GEPOperator>(constant_expr)->getSourceElementType(); + + // DataLayout::getIndexedOffsetInType assumes the indices are + // instances of ConstantInt. uint64_t offset = m_target_data.getIndexedOffsetInType(src_elem_ty, indices); @@ -325,8 +328,7 @@ public: m_values[value] = data_address; - lldb_private::Log *log( - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + lldb_private::Log *log(GetLog(LLDBLog::Expressions)); if (log) { LLDB_LOGF(log, "Made an allocation for argument %s", @@ -465,12 +467,20 @@ static bool CanResolveConstant(llvm::Constant *constant) { case Instruction::BitCast: return CanResolveConstant(constant_expr->getOperand(0)); case Instruction::GetElementPtr: { + // Check that the base can be constant-resolved. ConstantExpr::const_op_iterator op_cursor = constant_expr->op_begin(); Constant *base = dyn_cast<Constant>(*op_cursor); - if (!base) + if (!base || !CanResolveConstant(base)) return false; - return CanResolveConstant(base); + // Check that all other operands are just ConstantInt. + for (Value *op : make_range(constant_expr->op_begin() + 1, + constant_expr->op_end())) { + ConstantInt *constant_int = dyn_cast<ConstantInt>(op); + if (!constant_int) + return false; + } + return true; } } } else { @@ -484,8 +494,7 @@ static bool CanResolveConstant(llvm::Constant *constant) { bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function, lldb_private::Status &error, const bool support_function_calls) { - lldb_private::Log *log( - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + lldb_private::Log *log(GetLog(LLDBLog::Expressions)); bool saw_function_with_body = false; for (Function &f : module) { @@ -637,8 +646,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, lldb::addr_t stack_frame_bottom, lldb::addr_t stack_frame_top, lldb_private::ExecutionContext &exe_ctx) { - lldb_private::Log *log( - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + lldb_private::Log *log(GetLog(LLDBLog::Expressions)); if (log) { std::string s; @@ -1184,16 +1192,6 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, const Value *pointer_operand = load_inst->getPointerOperand(); - Type *pointer_ty = pointer_operand->getType(); - PointerType *pointer_ptr_ty = dyn_cast<PointerType>(pointer_ty); - if (!pointer_ptr_ty) { - LLDB_LOGF(log, "getPointerOperand()->getType() is not a PointerType"); - error.SetErrorToGenericError(); - error.SetErrorString(interpreter_internal_error); - return false; - } - Type *target_ty = pointer_ptr_ty->getElementType(); - lldb::addr_t D = frame.ResolveValue(load_inst, module); lldb::addr_t P = frame.ResolveValue(pointer_operand, module); @@ -1222,6 +1220,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, return false; } + Type *target_ty = load_inst->getType(); size_t target_size = data_layout.getTypeStoreSize(target_ty); lldb_private::DataBufferHeap buffer(target_size, 0); @@ -1267,12 +1266,6 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, const Value *value_operand = store_inst->getValueOperand(); const Value *pointer_operand = store_inst->getPointerOperand(); - Type *pointer_ty = pointer_operand->getType(); - PointerType *pointer_ptr_ty = dyn_cast<PointerType>(pointer_ty); - if (!pointer_ptr_ty) - return false; - Type *target_ty = pointer_ptr_ty->getElementType(); - lldb::addr_t D = frame.ResolveValue(value_operand, module); lldb::addr_t P = frame.ResolveValue(pointer_operand, module); @@ -1301,6 +1294,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, return false; } + Type *target_ty = value_operand->getType(); size_t target_size = data_layout.getTypeStoreSize(target_ty); lldb_private::DataBufferHeap buffer(target_size, 0); @@ -1381,21 +1375,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, lldb_private::DiagnosticManager diagnostics; lldb_private::EvaluateExpressionOptions options; - // We generally receive a function pointer which we must dereference - llvm::Type *prototype = val->getType(); - if (!prototype->isPointerTy()) { - error.SetErrorToGenericError(); - error.SetErrorString("call need function pointer"); - return false; - } - - // Dereference the function pointer - prototype = prototype->getPointerElementType(); - if (!(prototype->isFunctionTy() || prototype->isFunctionVarArg())) { - error.SetErrorToGenericError(); - error.SetErrorString("call need function pointer"); - return false; - } + llvm::FunctionType *prototype = call_inst->getFunctionType(); // Find number of arguments const int numArgs = call_inst->arg_size(); diff --git a/contrib/llvm-project/lldb/source/Expression/IRMemoryMap.cpp b/contrib/llvm-project/lldb/source/Expression/IRMemoryMap.cpp index 9eee5cf5b9a2..6b8f7babc6f0 100644 --- a/contrib/llvm-project/lldb/source/Expression/IRMemoryMap.cpp +++ b/contrib/llvm-project/lldb/source/Expression/IRMemoryMap.cpp @@ -13,6 +13,7 @@ #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" @@ -288,8 +289,7 @@ IRMemoryMap::Allocation::Allocation(lldb::addr_t process_alloc, lldb::addr_t IRMemoryMap::Malloc(size_t size, uint8_t alignment, uint32_t permissions, AllocationPolicy policy, bool zero_memory, Status &error) { - lldb_private::Log *log( - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + lldb_private::Log *log(GetLog(LLDBLog::Expressions)); error.Clear(); lldb::ProcessSP process_sp; @@ -476,8 +476,7 @@ void IRMemoryMap::Free(lldb::addr_t process_address, Status &error) { } } - if (lldb_private::Log *log = - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)) { + if (lldb_private::Log *log = GetLog(LLDBLog::Expressions)) { LLDB_LOGF(log, "IRMemoryMap::Free (0x%" PRIx64 ") freed [0x%" PRIx64 "..0x%" PRIx64 ")", @@ -574,8 +573,7 @@ void IRMemoryMap::WriteMemory(lldb::addr_t process_address, break; } - if (lldb_private::Log *log = - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)) { + if (lldb_private::Log *log = GetLog(LLDBLog::Expressions)) { LLDB_LOGF(log, "IRMemoryMap::WriteMemory (0x%" PRIx64 ", 0x%" PRIxPTR ", 0x%" PRId64 ") went to [0x%" PRIx64 "..0x%" PRIx64 ")", @@ -704,8 +702,7 @@ void IRMemoryMap::ReadMemory(uint8_t *bytes, lldb::addr_t process_address, break; } - if (lldb_private::Log *log = - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)) { + if (lldb_private::Log *log = GetLog(LLDBLog::Expressions)) { LLDB_LOGF(log, "IRMemoryMap::ReadMemory (0x%" PRIx64 ", 0x%" PRIxPTR ", 0x%" PRId64 ") came from [0x%" PRIx64 "..0x%" PRIx64 ")", diff --git a/contrib/llvm-project/lldb/source/Expression/LLVMUserExpression.cpp b/contrib/llvm-project/lldb/source/Expression/LLVMUserExpression.cpp index 527dff8bf60f..d67660812150 100644 --- a/contrib/llvm-project/lldb/source/Expression/LLVMUserExpression.cpp +++ b/contrib/llvm-project/lldb/source/Expression/LLVMUserExpression.cpp @@ -30,6 +30,7 @@ #include "lldb/Target/ThreadPlan.h" #include "lldb/Target/ThreadPlanCallUserExpression.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" @@ -67,8 +68,7 @@ LLVMUserExpression::DoExecute(DiagnosticManager &diagnostic_manager, // The expression log is quite verbose, and if you're just tracking the // execution of the expression, it's quite convenient to have these logs come // out with the STEP log as well. - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS | - LIBLLDB_LOG_STEP)); + Log *log(GetLog(LLDBLog::Expressions | LLDBLog::Step)); if (m_jit_start_addr == LLDB_INVALID_ADDRESS && !m_can_interpret) { diagnostic_manager.PutString( @@ -254,7 +254,7 @@ bool LLVMUserExpression::FinalizeJITExecution( DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, lldb::ExpressionVariableSP &result, lldb::addr_t function_stack_bottom, lldb::addr_t function_stack_top) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); LLDB_LOGF(log, "-- [UserExpression::FinalizeJITExecution] Dematerializing " "after execution --"); diff --git a/contrib/llvm-project/lldb/source/Expression/Materializer.cpp b/contrib/llvm-project/lldb/source/Expression/Materializer.cpp index d40365d60fb3..9ee2d983ddfc 100644 --- a/contrib/llvm-project/lldb/source/Expression/Materializer.cpp +++ b/contrib/llvm-project/lldb/source/Expression/Materializer.cpp @@ -19,6 +19,7 @@ #include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegisterValue.h" @@ -58,7 +59,7 @@ public: } void MakeAllocation(IRMemoryMap &map, Status &err) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); // Allocate a spare memory area to store the persistent variable's // contents. @@ -67,7 +68,7 @@ public: const bool zero_memory = false; lldb::addr_t mem = map.Malloc( - m_persistent_variable_sp->GetByteSize().getValueOr(0), 8, + m_persistent_variable_sp->GetByteSize().value_or(0), 8, lldb::ePermissionsReadable | lldb::ePermissionsWritable, IRMemoryMap::eAllocationPolicyMirror, zero_memory, allocate_error); @@ -106,7 +107,7 @@ public: Status write_error; map.WriteMemory(mem, m_persistent_variable_sp->GetValueBytes(), - m_persistent_variable_sp->GetByteSize().getValueOr(0), + m_persistent_variable_sp->GetByteSize().value_or(0), write_error); if (!write_error.Success()) { @@ -138,7 +139,7 @@ public: void Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Status &err) override { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); const lldb::addr_t load_addr = process_address + m_offset; @@ -190,7 +191,7 @@ public: void Dematerialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, lldb::addr_t frame_top, lldb::addr_t frame_bottom, Status &err) override { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); const lldb::addr_t load_addr = process_address + m_offset; @@ -235,7 +236,7 @@ public: map.GetBestExecutionContextScope(), m_persistent_variable_sp.get()->GetCompilerType(), m_persistent_variable_sp->GetName(), location, eAddressTypeLoad, - m_persistent_variable_sp->GetByteSize().getValueOr(0)); + m_persistent_variable_sp->GetByteSize().value_or(0)); if (frame_top != LLDB_INVALID_ADDRESS && frame_bottom != LLDB_INVALID_ADDRESS && location >= frame_bottom && @@ -281,7 +282,7 @@ public: m_persistent_variable_sp->GetName().GetCString(), (uint64_t)mem, (unsigned long long)m_persistent_variable_sp->GetByteSize() - .getValueOr(0)); + .value_or(0)); // Read the contents of the spare memory area @@ -290,7 +291,8 @@ public: Status read_error; map.ReadMemory(m_persistent_variable_sp->GetValueBytes(), mem, - m_persistent_variable_sp->GetByteSize().getValueOr(0), read_error); + m_persistent_variable_sp->GetByteSize().value_or(0), + read_error); if (!read_error.Success()) { err.SetErrorStringWithFormat( @@ -371,11 +373,12 @@ public: if (!err.Success()) { dump_stream.Printf(" <could not be read>\n"); } else { - DataBufferHeap data( - m_persistent_variable_sp->GetByteSize().getValueOr(0), 0); + DataBufferHeap data(m_persistent_variable_sp->GetByteSize().value_or(0), + 0); map.ReadMemory(data.GetBytes(), target_address, - m_persistent_variable_sp->GetByteSize().getValueOr(0), err); + m_persistent_variable_sp->GetByteSize().value_or(0), + err); if (!err.Success()) { dump_stream.Printf(" <could not be read>\n"); @@ -412,9 +415,7 @@ uint32_t Materializer::AddPersistentVariable( class EntityVariable : public Materializer::Entity { public: EntityVariable(lldb::VariableSP &variable_sp) - : Entity(), m_variable_sp(variable_sp), m_is_reference(false), - m_temporary_allocation(LLDB_INVALID_ADDRESS), - m_temporary_allocation_size(0) { + : Entity(), m_variable_sp(variable_sp) { // Hard-coding to maximum size of a pointer since all variables are // materialized by reference m_size = 8; @@ -425,7 +426,7 @@ public: void Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Status &err) override { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); const lldb::addr_t load_addr = process_address + m_offset; if (log) { @@ -528,7 +529,7 @@ public: "size of variable %s (%" PRIu64 ") is larger than the ValueObject's size (%" PRIu64 ")", m_variable_sp->GetName().AsCString(), - m_variable_sp->GetType()->GetByteSize(scope).getValueOr(0), + m_variable_sp->GetType()->GetByteSize(scope).value_or(0), data.GetByteSize()); } return; @@ -594,7 +595,7 @@ public: void Dematerialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, lldb::addr_t frame_top, lldb::addr_t frame_bottom, Status &err) override { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); const lldb::addr_t load_addr = process_address + m_offset; if (log) { @@ -625,7 +626,7 @@ public: Status extract_error; map.GetMemoryData(data, m_temporary_allocation, - valobj_sp->GetByteSize().getValueOr(0), extract_error); + valobj_sp->GetByteSize().value_or(0), extract_error); if (!extract_error.Success()) { err.SetErrorStringWithFormat("couldn't get the data for variable %s", @@ -748,9 +749,9 @@ public: private: lldb::VariableSP m_variable_sp; - bool m_is_reference; - lldb::addr_t m_temporary_allocation; - size_t m_temporary_allocation_size; + bool m_is_reference = false; + lldb::addr_t m_temporary_allocation = LLDB_INVALID_ADDRESS; + size_t m_temporary_allocation_size = 0; lldb::DataBufferSP m_original_data; }; @@ -768,9 +769,7 @@ public: bool keep_in_memory, Materializer::PersistentVariableDelegate *delegate) : Entity(), m_type(type), m_is_program_reference(is_program_reference), - m_keep_in_memory(keep_in_memory), - m_temporary_allocation(LLDB_INVALID_ADDRESS), - m_temporary_allocation_size(0), m_delegate(delegate) { + m_keep_in_memory(keep_in_memory), m_delegate(delegate) { // Hard-coding to maximum size of a pointer since all results are // materialized by reference m_size = 8; @@ -924,7 +923,7 @@ public: ret->ValueUpdated(); - const size_t pvar_byte_size = ret->GetByteSize().getValueOr(0); + const size_t pvar_byte_size = ret->GetByteSize().value_or(0); uint8_t *pvar_data = ret->GetValueBytes(); map.ReadMemory(pvar_data, address, pvar_byte_size, read_error); @@ -1029,8 +1028,8 @@ private: bool m_is_program_reference; bool m_keep_in_memory; - lldb::addr_t m_temporary_allocation; - size_t m_temporary_allocation_size; + lldb::addr_t m_temporary_allocation = LLDB_INVALID_ADDRESS; + size_t m_temporary_allocation_size = 0; Materializer::PersistentVariableDelegate *m_delegate; }; @@ -1057,7 +1056,7 @@ public: void Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Status &err) override { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); const lldb::addr_t load_addr = process_address + m_offset; @@ -1106,7 +1105,7 @@ public: void Dematerialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, lldb::addr_t frame_top, lldb::addr_t frame_bottom, Status &err) override { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); const lldb::addr_t load_addr = process_address + m_offset; @@ -1176,7 +1175,7 @@ public: void Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Status &err) override { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); const lldb::addr_t load_addr = process_address + m_offset; @@ -1239,7 +1238,7 @@ public: void Dematerialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, lldb::addr_t frame_top, lldb::addr_t frame_bottom, Status &err) override { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); const lldb::addr_t load_addr = process_address + m_offset; @@ -1377,8 +1376,7 @@ Materializer::Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, return DematerializerSP(); } - if (Log *log = - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)) { + if (Log *log = GetLog(LLDBLog::Expressions)) { LLDB_LOGF( log, "Materializer::Materialize (frame_sp = %p, process_address = 0x%" PRIx64 @@ -1415,8 +1413,7 @@ void Materializer::Dematerializer::Dematerialize(Status &error, error.SetErrorToGenericError(); error.SetErrorString("Couldn't dematerialize: target is gone"); } else { - if (Log *log = - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)) { + if (Log *log = GetLog(LLDBLog::Expressions)) { LLDB_LOGF(log, "Materializer::Dematerialize (frame_sp = %p, process_address " "= 0x%" PRIx64 ") about to dematerialize:", diff --git a/contrib/llvm-project/lldb/source/Expression/REPL.cpp b/contrib/llvm-project/lldb/source/Expression/REPL.cpp index be41c60ebb5f..d7582af9b2ea 100644 --- a/contrib/llvm-project/lldb/source/Expression/REPL.cpp +++ b/contrib/llvm-project/lldb/source/Expression/REPL.cpp @@ -25,6 +25,7 @@ using namespace lldb_private; REPL::REPL(LLVMCastKind kind, Target &target) : m_target(target), m_kind(kind) { // Make sure all option values have sane defaults Debugger &debugger = m_target.GetDebugger(); + debugger.SetShowProgress(false); auto exe_ctx = debugger.GetCommandInterpreter().GetExecutionContext(); m_format_options.OptionParsingStarting(&exe_ctx); m_varobj_options.OptionParsingStarting(&exe_ctx); diff --git a/contrib/llvm-project/lldb/source/Expression/UserExpression.cpp b/contrib/llvm-project/lldb/source/Expression/UserExpression.cpp index 692594b03f16..f821603f03e5 100644 --- a/contrib/llvm-project/lldb/source/Expression/UserExpression.cpp +++ b/contrib/llvm-project/lldb/source/Expression/UserExpression.cpp @@ -37,6 +37,7 @@ #include "lldb/Target/ThreadPlan.h" #include "lldb/Target/ThreadPlanCallUserExpression.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" @@ -141,12 +142,12 @@ UserExpression::Evaluate(ExecutionContext &exe_ctx, llvm::StringRef expr, llvm::StringRef prefix, lldb::ValueObjectSP &result_valobj_sp, Status &error, std::string *fixed_expression, ValueObject *ctx_obj) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS | - LIBLLDB_LOG_STEP)); + Log *log(GetLog(LLDBLog::Expressions | LLDBLog::Step)); if (ctx_obj) { - static unsigned const ctx_type_mask = - lldb::TypeFlags::eTypeIsClass | lldb::TypeFlags::eTypeIsStructUnion; + static unsigned const ctx_type_mask = lldb::TypeFlags::eTypeIsClass | + lldb::TypeFlags::eTypeIsStructUnion | + lldb::TypeFlags::eTypeIsReference; if (!(ctx_obj->GetTypeInfo() & ctx_type_mask)) { LLDB_LOG(log, "== [UserExpression::Evaluate] Passed a context object of " "an invalid type, can't run expressions."); @@ -155,6 +156,21 @@ UserExpression::Evaluate(ExecutionContext &exe_ctx, } } + if (ctx_obj && ctx_obj->GetTypeInfo() & lldb::TypeFlags::eTypeIsReference) { + Status error; + lldb::ValueObjectSP deref_ctx_sp = ctx_obj->Dereference(error); + if (!error.Success()) { + LLDB_LOG(log, "== [UserExpression::Evaluate] Passed a context object of " + "a reference type that can't be dereferenced, can't run " + "expressions."); + error.SetErrorString( + "passed context object of an reference type cannot be deferenced"); + return lldb::eExpressionSetupError; + } + + ctx_obj = deref_ctx_sp.get(); + } + lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy(); lldb::LanguageType language = options.GetLanguage(); const ResultType desired_type = options.DoesCoerceToId() diff --git a/contrib/llvm-project/lldb/source/Host/common/Editline.cpp b/contrib/llvm-project/lldb/source/Host/common/Editline.cpp index 6898f8452161..ea0f06f63707 100644 --- a/contrib/llvm-project/lldb/source/Host/common/Editline.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/Editline.cpp @@ -1080,8 +1080,13 @@ unsigned char Editline::TypedCharacter(int ch) { llvm::StringRef line(line_info->buffer, line_info->lastchar - line_info->buffer); + const char *ansi_prefix = + m_color_prompts ? m_suggestion_ansi_prefix.c_str() : ""; + const char *ansi_suffix = + m_color_prompts ? m_suggestion_ansi_suffix.c_str() : ""; + if (llvm::Optional<std::string> to_add = m_suggestion_callback(line)) { - std::string to_add_color = ANSI_FAINT + to_add.getValue() + ANSI_UNFAINT; + std::string to_add_color = ansi_prefix + to_add.getValue() + ansi_suffix; fputs(typed.c_str(), m_output_file); fputs(to_add_color.c_str(), m_output_file); size_t new_autosuggestion_size = line.size() + to_add->length(); @@ -1371,10 +1376,12 @@ Editline *Editline::InstanceFor(EditLine *editline) { } Editline::Editline(const char *editline_name, FILE *input_file, - FILE *output_file, FILE *error_file, bool color_prompts) + FILE *output_file, FILE *error_file, + std::recursive_mutex &output_mutex, bool color_prompts) : m_editor_status(EditorStatus::Complete), m_color_prompts(color_prompts), m_input_file(input_file), m_output_file(output_file), - m_error_file(error_file), m_input_connection(fileno(input_file), false) { + m_error_file(error_file), m_input_connection(fileno(input_file), false), + m_output_mutex(output_mutex) { // Get a shared history instance m_editor_name = (editline_name == nullptr) ? "lldb-tmp" : editline_name; m_history_sp = EditlineHistory::GetHistory(m_editor_name); @@ -1383,12 +1390,13 @@ Editline::Editline(const char *editline_name, FILE *input_file, if (m_output_file) { const int term_fd = fileno(m_output_file); if (term_fd != -1) { - static std::mutex *g_init_terminal_fds_mutex_ptr = nullptr; + static std::recursive_mutex *g_init_terminal_fds_mutex_ptr = nullptr; static std::set<int> *g_init_terminal_fds_ptr = nullptr; static llvm::once_flag g_once_flag; llvm::call_once(g_once_flag, [&]() { g_init_terminal_fds_mutex_ptr = - new std::mutex(); // NOTE: Leak to avoid C++ destructor chain issues + new std::recursive_mutex(); // NOTE: Leak to avoid C++ destructor + // chain issues g_init_terminal_fds_ptr = new std::set<int>(); // NOTE: Leak to avoid // C++ destructor chain // issues @@ -1396,7 +1404,8 @@ Editline::Editline(const char *editline_name, FILE *input_file, // We must make sure to initialize the terminal a given file descriptor // only once. If we do this multiple times, we start leaking memory. - std::lock_guard<std::mutex> guard(*g_init_terminal_fds_mutex_ptr); + std::lock_guard<std::recursive_mutex> guard( + *g_init_terminal_fds_mutex_ptr); if (g_init_terminal_fds_ptr->find(term_fd) == g_init_terminal_fds_ptr->end()) { g_init_terminal_fds_ptr->insert(term_fd); @@ -1468,7 +1477,7 @@ uint32_t Editline::GetCurrentLine() { return m_current_line_index; } bool Editline::Interrupt() { bool result = true; - std::lock_guard<std::mutex> guard(m_output_mutex); + std::lock_guard<std::recursive_mutex> guard(m_output_mutex); if (m_editor_status == EditorStatus::Editing) { fprintf(m_output_file, "^C\n"); result = m_input_connection.InterruptRead(); @@ -1479,7 +1488,7 @@ bool Editline::Interrupt() { bool Editline::Cancel() { bool result = true; - std::lock_guard<std::mutex> guard(m_output_mutex); + std::lock_guard<std::recursive_mutex> guard(m_output_mutex); if (m_editor_status == EditorStatus::Editing) { MoveCursor(CursorLocation::EditingCursor, CursorLocation::BlockStart); fprintf(m_output_file, ANSI_CLEAR_BELOW); @@ -1494,7 +1503,7 @@ bool Editline::GetLine(std::string &line, bool &interrupted) { m_input_lines = std::vector<EditLineStringType>(); m_input_lines.insert(m_input_lines.begin(), EditLineConstString("")); - std::lock_guard<std::mutex> guard(m_output_mutex); + std::lock_guard<std::recursive_mutex> guard(m_output_mutex); lldbassert(m_editor_status != EditorStatus::Editing); if (m_editor_status == EditorStatus::Interrupted) { @@ -1539,7 +1548,7 @@ bool Editline::GetLines(int first_line_number, StringList &lines, m_input_lines = std::vector<EditLineStringType>(); m_input_lines.insert(m_input_lines.begin(), EditLineConstString("")); - std::lock_guard<std::mutex> guard(m_output_mutex); + std::lock_guard<std::recursive_mutex> guard(m_output_mutex); // Begin the line editing loop DisplayInput(); SetCurrentLine(0); @@ -1569,7 +1578,7 @@ bool Editline::GetLines(int first_line_number, StringList &lines, } void Editline::PrintAsync(Stream *stream, const char *s, size_t len) { - std::lock_guard<std::mutex> guard(m_output_mutex); + std::lock_guard<std::recursive_mutex> guard(m_output_mutex); if (m_editor_status == EditorStatus::Editing) { MoveCursor(CursorLocation::EditingCursor, CursorLocation::BlockStart); fprintf(m_output_file, ANSI_CLEAR_BELOW); diff --git a/contrib/llvm-project/lldb/source/Host/common/File.cpp b/contrib/llvm-project/lldb/source/Host/common/File.cpp index daac1fef2f36..760fb98fb496 100644 --- a/contrib/llvm-project/lldb/source/Host/common/File.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/File.cpp @@ -23,17 +23,17 @@ #include <unistd.h> #endif -#include "llvm/Support/ConvertUTF.h" -#include "llvm/Support/Errno.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Process.h" - #include "lldb/Host/Config.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/VASPrintf.h" +#include "llvm/Support/ConvertUTF.h" +#include "llvm/Support/Errno.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Process.h" using namespace lldb; using namespace lldb_private; @@ -215,18 +215,13 @@ size_t File::Printf(const char *format, ...) { } size_t File::PrintfVarArg(const char *format, va_list args) { - size_t result = 0; - char *s = nullptr; - result = vasprintf(&s, format, args); - if (s != nullptr) { - if (result > 0) { - size_t s_len = result; - Write(s, s_len); - result = s_len; - } - free(s); + llvm::SmallString<0> s; + if (VASprintf(s, format, args)) { + size_t written = s.size();; + Write(s.data(), written); + return written; } - return result; + return 0; } Expected<File::OpenOptions> File::GetOptions() const { diff --git a/contrib/llvm-project/lldb/source/Host/common/FileSystem.cpp b/contrib/llvm-project/lldb/source/Host/common/FileSystem.cpp index 1e4a24abe301..501062f99a53 100644 --- a/contrib/llvm-project/lldb/source/Host/common/FileSystem.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/FileSystem.cpp @@ -8,6 +8,7 @@ #include "lldb/Host/FileSystem.h" +#include "lldb/Utility/DataBufferLLVM.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/TildeExpressionResolver.h" @@ -49,27 +50,6 @@ void FileSystem::Initialize() { InstanceImpl().emplace(); } -void FileSystem::Initialize(std::shared_ptr<FileCollectorBase> collector) { - lldbassert(!InstanceImpl() && "Already initialized."); - InstanceImpl().emplace(collector); -} - -llvm::Error FileSystem::Initialize(const FileSpec &mapping) { - lldbassert(!InstanceImpl() && "Already initialized."); - - llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> buffer = - llvm::vfs::getRealFileSystem()->getBufferForFile(mapping.GetPath()); - - if (!buffer) - return llvm::errorCodeToError(buffer.getError()); - - InstanceImpl().emplace(llvm::vfs::getVFSFromYAML(std::move(buffer.get()), - nullptr, mapping.GetPath()), - true); - - return llvm::Error::success(); -} - void FileSystem::Initialize(IntrusiveRefCntPtr<vfs::FileSystem> fs) { lldbassert(!InstanceImpl() && "Already initialized."); InstanceImpl().emplace(fs); @@ -293,35 +273,55 @@ void FileSystem::Resolve(FileSpec &file_spec) { file_spec.SetIsResolved(true); } -std::shared_ptr<DataBufferLLVM> -FileSystem::CreateDataBuffer(const llvm::Twine &path, uint64_t size, - uint64_t offset) { - Collect(path); - - const bool is_volatile = !IsLocal(path); - const ErrorOr<std::string> external_path = GetExternalPath(path); - - if (!external_path) - return nullptr; - - std::unique_ptr<llvm::WritableMemoryBuffer> buffer; +template <typename T> +static std::unique_ptr<T> GetMemoryBuffer(const llvm::Twine &path, + uint64_t size, uint64_t offset, + bool is_volatile) { + std::unique_ptr<T> buffer; if (size == 0) { - auto buffer_or_error = - llvm::WritableMemoryBuffer::getFile(*external_path, is_volatile); + auto buffer_or_error = T::getFile(path, is_volatile); if (!buffer_or_error) return nullptr; buffer = std::move(*buffer_or_error); } else { - auto buffer_or_error = llvm::WritableMemoryBuffer::getFileSlice( - *external_path, size, offset, is_volatile); + auto buffer_or_error = T::getFileSlice(path, size, offset, is_volatile); if (!buffer_or_error) return nullptr; buffer = std::move(*buffer_or_error); } + return buffer; +} + +std::shared_ptr<WritableDataBuffer> +FileSystem::CreateWritableDataBuffer(const llvm::Twine &path, uint64_t size, + uint64_t offset) { + const bool is_volatile = !IsLocal(path); + auto buffer = GetMemoryBuffer<llvm::WritableMemoryBuffer>(path, size, offset, + is_volatile); + if (!buffer) + return {}; + return std::shared_ptr<WritableDataBufferLLVM>( + new WritableDataBufferLLVM(std::move(buffer))); +} + +std::shared_ptr<DataBuffer> +FileSystem::CreateDataBuffer(const llvm::Twine &path, uint64_t size, + uint64_t offset) { + const bool is_volatile = !IsLocal(path); + auto buffer = + GetMemoryBuffer<llvm::MemoryBuffer>(path, size, offset, is_volatile); + if (!buffer) + return {}; return std::shared_ptr<DataBufferLLVM>(new DataBufferLLVM(std::move(buffer))); } -std::shared_ptr<DataBufferLLVM> +std::shared_ptr<WritableDataBuffer> +FileSystem::CreateWritableDataBuffer(const FileSpec &file_spec, uint64_t size, + uint64_t offset) { + return CreateWritableDataBuffer(file_spec.GetPath(), size, offset); +} + +std::shared_ptr<DataBuffer> FileSystem::CreateDataBuffer(const FileSpec &file_spec, uint64_t size, uint64_t offset) { return CreateDataBuffer(file_spec.GetPath(), size, offset); @@ -450,18 +450,14 @@ static mode_t GetOpenMode(uint32_t permissions) { Expected<FileUP> FileSystem::Open(const FileSpec &file_spec, File::OpenOptions options, uint32_t permissions, bool should_close_fd) { - Collect(file_spec.GetPath()); - const int open_flags = GetOpenFlags(options); const mode_t open_mode = (open_flags & O_CREAT) ? GetOpenMode(permissions) : 0; - auto path = GetExternalPath(file_spec); - if (!path) - return errorCodeToError(path.getError()); + auto path = file_spec.GetPath(); int descriptor = llvm::sys::RetryAfterSignal( - -1, OpenWithFS, *this, path->c_str(), open_flags, open_mode); + -1, OpenWithFS, *this, path.c_str(), open_flags, open_mode); if (!File::DescriptorIsValid(descriptor)) return llvm::errorCodeToError( @@ -473,43 +469,6 @@ Expected<FileUP> FileSystem::Open(const FileSpec &file_spec, return std::move(file); } -ErrorOr<std::string> FileSystem::GetExternalPath(const llvm::Twine &path) { - if (!m_mapped) - return path.str(); - - // If VFS mapped we know the underlying FS is a RedirectingFileSystem. - ErrorOr<vfs::RedirectingFileSystem::LookupResult> Result = - static_cast<vfs::RedirectingFileSystem &>(*m_fs).lookupPath(path.str()); - if (!Result) { - if (Result.getError() == llvm::errc::no_such_file_or_directory) { - return path.str(); - } - return Result.getError(); - } - - 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) { - return GetExternalPath(file_spec.GetPath()); -} - -void FileSystem::Collect(const FileSpec &file_spec) { - Collect(file_spec.GetPath()); -} - -void FileSystem::Collect(const llvm::Twine &file) { - if (!m_collector) - return; - - if (llvm::sys::fs::is_directory(file)) - m_collector->addDirectory(file); - else - m_collector->addFile(file); -} - void FileSystem::SetHomeDirectory(std::string home_directory) { m_home_directory = std::move(home_directory); } diff --git a/contrib/llvm-project/lldb/source/Host/common/Host.cpp b/contrib/llvm-project/lldb/source/Host/common/Host.cpp index 53a096c617df..f35eb47ff683 100644 --- a/contrib/llvm-project/lldb/source/Host/common/Host.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/Host.cpp @@ -56,8 +56,8 @@ #include "lldb/Host/ProcessLauncher.h" #include "lldb/Host/ThreadLauncher.h" #include "lldb/Host/posix/ConnectionFileDescriptorPosix.h" -#include "lldb/Utility/DataBufferLLVM.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Predicate.h" #include "lldb/Utility/ReproducerProvider.h" @@ -90,30 +90,24 @@ int __pthread_fchdir(int fildes); using namespace lldb; using namespace lldb_private; -#if !defined(__APPLE__) && !defined(_WIN32) -struct MonitorInfo { - lldb::pid_t pid; // The process ID to monitor - Host::MonitorChildProcessCallback - callback; // The callback function to call when "pid" exits or signals - bool monitor_signals; // If true, call the callback when "pid" gets signaled. -}; +#if !defined(__APPLE__) +void Host::SystemLog(llvm::StringRef message) { llvm::errs() << message; } +#endif -static thread_result_t MonitorChildProcessThreadFunction(void *arg); +#if !defined(__APPLE__) && !defined(_WIN32) +static thread_result_t +MonitorChildProcessThreadFunction(::pid_t pid, + Host::MonitorChildProcessCallback callback); llvm::Expected<HostThread> Host::StartMonitoringChildProcess( - const Host::MonitorChildProcessCallback &callback, lldb::pid_t pid, - bool monitor_signals) { - MonitorInfo *info_ptr = new MonitorInfo(); - - info_ptr->pid = pid; - info_ptr->callback = callback; - info_ptr->monitor_signals = monitor_signals; - + const Host::MonitorChildProcessCallback &callback, lldb::pid_t pid) { char thread_name[256]; ::snprintf(thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%" PRIu64 ")>", pid); - return ThreadLauncher::LaunchThread( - thread_name, MonitorChildProcessThreadFunction, info_ptr, 0); + assert(pid <= UINT32_MAX); + return ThreadLauncher::LaunchThread(thread_name, [pid, callback] { + return MonitorChildProcessThreadFunction(pid, callback); + }); } #ifndef __linux__ @@ -162,26 +156,13 @@ static bool CheckForMonitorCancellation() { return false; } -static thread_result_t MonitorChildProcessThreadFunction(void *arg) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); - const char *function = __FUNCTION__; - LLDB_LOGF(log, "%s (arg = %p) thread starting...", function, arg); - - MonitorInfo *info = (MonitorInfo *)arg; - - const Host::MonitorChildProcessCallback callback = info->callback; - const bool monitor_signals = info->monitor_signals; - - assert(info->pid <= UINT32_MAX); - const ::pid_t pid = monitor_signals ? -1 * getpgid(info->pid) : info->pid; - - delete info; +static thread_result_t +MonitorChildProcessThreadFunction(::pid_t pid, + Host::MonitorChildProcessCallback callback) { + Log *log = GetLog(LLDBLog::Process); + LLDB_LOG(log, "pid = {0}", pid); int status = -1; -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) -#define __WALL 0 -#endif - const int options = __WALL; #ifdef __linux__ // This signal is only used to interrupt the thread from waitpid @@ -191,126 +172,57 @@ static thread_result_t MonitorChildProcessThreadFunction(void *arg) { ::sigaction(SIGUSR1, &sigUsr1Action, nullptr); #endif // __linux__ - while (true) { - log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS); - LLDB_LOGF(log, "%s ::waitpid (pid = %" PRIi32 ", &status, options = %i)...", - function, pid, options); + while(1) { + log = GetLog(LLDBLog::Process); + LLDB_LOG(log, "::waitpid({0}, &status, 0)...", pid); if (CheckForMonitorCancellation()) - break; + return nullptr; + + const ::pid_t wait_pid = ::waitpid(pid, &status, 0); - // Get signals from all children with same process group of pid - const ::pid_t wait_pid = ::waitpid(pid, &status, options); + LLDB_LOG(log, "::waitpid({0}, &status, 0) => pid = {1}, status = {2:x}", pid, + wait_pid, status); if (CheckForMonitorCancellation()) + return nullptr; + + if (wait_pid != -1) break; + if (errno != EINTR) { + LLDB_LOG(log, "pid = {0}, thread exiting because waitpid failed ({1})...", + pid, llvm::sys::StrError()); + return nullptr; + } + } - if (wait_pid == -1) { - if (errno == EINTR) - continue; - else { - LLDB_LOG(log, - "arg = {0}, thread exiting because waitpid failed ({1})...", - arg, llvm::sys::StrError()); - break; - } - } else if (wait_pid > 0) { - bool exited = false; - int signal = 0; - int exit_status = 0; - const char *status_cstr = nullptr; - if (WIFSTOPPED(status)) { - signal = WSTOPSIG(status); - status_cstr = "STOPPED"; - } else if (WIFEXITED(status)) { - exit_status = WEXITSTATUS(status); - status_cstr = "EXITED"; - exited = true; - } else if (WIFSIGNALED(status)) { - signal = WTERMSIG(status); - status_cstr = "SIGNALED"; - if (wait_pid == abs(pid)) { - exited = true; - exit_status = -1; - } - } else { - status_cstr = "(\?\?\?)"; - } + int signal = 0; + int exit_status = 0; + if (WIFEXITED(status)) { + exit_status = WEXITSTATUS(status); + } else if (WIFSIGNALED(status)) { + signal = WTERMSIG(status); + exit_status = -1; + } else { + llvm_unreachable("Unknown status"); + } - // Scope for pthread_cancel_disabler - { + // Scope for pthread_cancel_disabler + { #ifndef __linux__ - ScopedPThreadCancelDisabler pthread_cancel_disabler; + ScopedPThreadCancelDisabler pthread_cancel_disabler; #endif - log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS); - LLDB_LOGF(log, - "%s ::waitpid (pid = %" PRIi32 - ", &status, options = %i) => pid = %" PRIi32 - ", status = 0x%8.8x (%s), signal = %i, exit_state = %i", - function, pid, options, wait_pid, status, status_cstr, signal, - exit_status); - - if (exited || (signal != 0 && monitor_signals)) { - bool callback_return = false; - if (callback) - callback_return = callback(wait_pid, exited, signal, exit_status); - - // If our process exited, then this thread should exit - if (exited && wait_pid == abs(pid)) { - LLDB_LOGF(log, - "%s (arg = %p) thread exiting because pid received " - "exit signal...", - __FUNCTION__, arg); - break; - } - // If the callback returns true, it means this process should exit - if (callback_return) { - LLDB_LOGF(log, - "%s (arg = %p) thread exiting because callback " - "returned true...", - __FUNCTION__, arg); - break; - } - } - } - } + if (callback) + callback(pid, signal, exit_status); } - log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS); - LLDB_LOGF(log, "%s (arg = %p) thread exiting...", __FUNCTION__, arg); - + LLDB_LOG(GetLog(LLDBLog::Process), "pid = {0} thread exiting...", pid); return nullptr; } #endif // #if !defined (__APPLE__) && !defined (_WIN32) -#if !defined(__APPLE__) - -void Host::SystemLog(SystemLogType type, const char *format, va_list args) { - vfprintf(stderr, format, args); -} - -#endif - -void Host::SystemLog(SystemLogType type, const char *format, ...) { - { - va_list args; - va_start(args, format); - SystemLog(type, format, args); - va_end(args); - } - - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST)); - if (log && log->GetVerbose()) { - // Log to log channel. This allows testcases to grep for log output. - va_list args; - va_start(args, format); - log->VAPrintf(format, args); - va_end(args); - } -} - lldb::pid_t Host::GetCurrentProcessID() { return ::getpid(); } #ifndef _WIN32 @@ -450,11 +362,10 @@ struct ShellInfo { int status = -1; }; -static bool +static void MonitorShellCommand(std::shared_ptr<ShellInfo> shell_info, lldb::pid_t pid, - bool exited, // True if the process did exit - int signo, // Zero for no signal - int status) // Exit value of process if signal is zero + int signo, // Zero for no signal + int status) // Exit value of process if signal is zero { shell_info->pid = pid; shell_info->signo = signo; @@ -462,7 +373,6 @@ MonitorShellCommand(std::shared_ptr<ShellInfo> shell_info, lldb::pid_t pid, // Let the thread running Host::RunShellCommand() know that the process // exited and that ShellInfo has been filled in by broadcasting to it shell_info->process_reaped.SetValue(true, eBroadcastAlways); - return true; } Status Host::RunShellCommand(llvm::StringRef command, @@ -557,12 +467,9 @@ Status Host::RunShellCommand(llvm::StringRef shell_path, const Args &args, launch_info.AppendSuppressFileAction(STDERR_FILENO, false, true); std::shared_ptr<ShellInfo> shell_info_sp(new ShellInfo()); - const bool monitor_signals = false; launch_info.SetMonitorProcessCallback( std::bind(MonitorShellCommand, shell_info_sp, std::placeholders::_1, - std::placeholders::_2, std::placeholders::_3, - std::placeholders::_4), - monitor_signals); + std::placeholders::_2, std::placeholders::_3)); error = LaunchProcess(launch_info); const lldb::pid_t pid = launch_info.GetProcessID(); @@ -595,11 +502,13 @@ Status Host::RunShellCommand(llvm::StringRef shell_path, const Args &args, error.SetErrorStringWithFormat( "shell command output is too large to fit into a std::string"); } else { - auto Buffer = - FileSystem::Instance().CreateDataBuffer(output_file_spec); + WritableDataBufferSP Buffer = + FileSystem::Instance().CreateWritableDataBuffer( + output_file_spec); if (error.Success()) - command_output_ptr->assign(Buffer->GetChars(), - Buffer->GetByteSize()); + command_output_ptr->assign( + reinterpret_cast<char *>(Buffer->GetBytes()), + Buffer->GetByteSize()); } } } @@ -644,6 +553,7 @@ bool Host::OpenFileInExternalEditor(const FileSpec &file_spec, return false; } +bool Host::IsInteractiveGraphicSession() { return false; } #endif std::unique_ptr<Connection> Host::CreateDefaultConnection(llvm::StringRef url) { @@ -721,3 +631,11 @@ uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info, return result; } + +char SystemLogHandler::ID; + +SystemLogHandler::SystemLogHandler() {} + +void SystemLogHandler::Emit(llvm::StringRef message) { + Host::SystemLog(message); +} diff --git a/contrib/llvm-project/lldb/source/Host/common/HostInfoBase.cpp b/contrib/llvm-project/lldb/source/Host/common/HostInfoBase.cpp index a6239a3208bc..22c0403006e9 100644 --- a/contrib/llvm-project/lldb/source/Host/common/HostInfoBase.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/HostInfoBase.cpp @@ -13,6 +13,7 @@ #include "lldb/Host/HostInfo.h" #include "lldb/Host/HostInfoBase.h" #include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" @@ -84,8 +85,7 @@ void HostInfoBase::Terminate() { llvm::Triple HostInfoBase::GetTargetTriple() { llvm::call_once(g_fields->m_host_triple_once, []() { - g_fields->m_host_triple = - HostInfo::GetArchitecture().GetTriple(); + g_fields->m_host_triple = HostInfo::GetArchitecture().GetTriple(); }); return g_fields->m_host_triple; } @@ -107,7 +107,8 @@ const ArchSpec &HostInfoBase::GetArchitecture(ArchitectureKind arch_kind) { : g_fields->m_host_arch_32; } -llvm::Optional<HostInfoBase::ArchitectureKind> HostInfoBase::ParseArchitectureKind(llvm::StringRef kind) { +llvm::Optional<HostInfoBase::ArchitectureKind> +HostInfoBase::ParseArchitectureKind(llvm::StringRef kind) { return llvm::StringSwitch<llvm::Optional<ArchitectureKind>>(kind) .Case(LLDB_ARCH_DEFAULT, eArchKindDefault) .Case(LLDB_ARCH_DEFAULT_32BIT, eArchKind32) @@ -119,7 +120,7 @@ FileSpec HostInfoBase::GetShlibDir() { llvm::call_once(g_fields->m_lldb_so_dir_once, []() { if (!HostInfo::ComputeSharedLibraryDirectory(g_fields->m_lldb_so_dir)) g_fields->m_lldb_so_dir = FileSpec(); - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + Log *log = GetLog(LLDBLog::Host); LLDB_LOG(log, "shlib dir -> `{0}`", g_fields->m_lldb_so_dir); }); return g_fields->m_lldb_so_dir; @@ -129,7 +130,7 @@ FileSpec HostInfoBase::GetSupportExeDir() { llvm::call_once(g_fields->m_lldb_support_exe_dir_once, []() { if (!HostInfo::ComputeSupportExeDirectory(g_fields->m_lldb_support_exe_dir)) g_fields->m_lldb_support_exe_dir = FileSpec(); - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + Log *log = GetLog(LLDBLog::Host); LLDB_LOG(log, "support exe dir -> `{0}`", g_fields->m_lldb_support_exe_dir); }); return g_fields->m_lldb_support_exe_dir; @@ -139,7 +140,7 @@ FileSpec HostInfoBase::GetHeaderDir() { llvm::call_once(g_fields->m_lldb_headers_dir_once, []() { if (!HostInfo::ComputeHeaderDirectory(g_fields->m_lldb_headers_dir)) g_fields->m_lldb_headers_dir = FileSpec(); - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + Log *log = GetLog(LLDBLog::Host); LLDB_LOG(log, "header dir -> `{0}`", g_fields->m_lldb_headers_dir); }); return g_fields->m_lldb_headers_dir; @@ -147,9 +148,10 @@ FileSpec HostInfoBase::GetHeaderDir() { FileSpec HostInfoBase::GetSystemPluginDir() { llvm::call_once(g_fields->m_lldb_system_plugin_dir_once, []() { - if (!HostInfo::ComputeSystemPluginsDirectory(g_fields->m_lldb_system_plugin_dir)) + if (!HostInfo::ComputeSystemPluginsDirectory( + g_fields->m_lldb_system_plugin_dir)) g_fields->m_lldb_system_plugin_dir = FileSpec(); - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + Log *log = GetLog(LLDBLog::Host); LLDB_LOG(log, "system plugin dir -> `{0}`", g_fields->m_lldb_system_plugin_dir); }); @@ -158,9 +160,10 @@ FileSpec HostInfoBase::GetSystemPluginDir() { FileSpec HostInfoBase::GetUserPluginDir() { llvm::call_once(g_fields->m_lldb_user_plugin_dir_once, []() { - if (!HostInfo::ComputeUserPluginsDirectory(g_fields->m_lldb_user_plugin_dir)) + if (!HostInfo::ComputeUserPluginsDirectory( + g_fields->m_lldb_user_plugin_dir)) g_fields->m_lldb_user_plugin_dir = FileSpec(); - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + Log *log = GetLog(LLDBLog::Host); LLDB_LOG(log, "user plugin dir -> `{0}`", g_fields->m_lldb_user_plugin_dir); }); return g_fields->m_lldb_user_plugin_dir; @@ -168,9 +171,10 @@ FileSpec HostInfoBase::GetUserPluginDir() { FileSpec HostInfoBase::GetProcessTempDir() { llvm::call_once(g_fields->m_lldb_process_tmp_dir_once, []() { - if (!HostInfo::ComputeProcessTempFileDirectory( g_fields->m_lldb_process_tmp_dir)) + if (!HostInfo::ComputeProcessTempFileDirectory( + g_fields->m_lldb_process_tmp_dir)) g_fields->m_lldb_process_tmp_dir = FileSpec(); - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + Log *log = GetLog(LLDBLog::Host); LLDB_LOG(log, "process temp dir -> `{0}`", g_fields->m_lldb_process_tmp_dir); }); @@ -179,10 +183,11 @@ FileSpec HostInfoBase::GetProcessTempDir() { FileSpec HostInfoBase::GetGlobalTempDir() { llvm::call_once(g_fields->m_lldb_global_tmp_dir_once, []() { - if (!HostInfo::ComputeGlobalTempFileDirectory( g_fields->m_lldb_global_tmp_dir)) + if (!HostInfo::ComputeGlobalTempFileDirectory( + g_fields->m_lldb_global_tmp_dir)) g_fields->m_lldb_global_tmp_dir = FileSpec(); - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + Log *log = GetLog(LLDBLog::Host); LLDB_LOG(log, "global temp dir -> `{0}`", g_fields->m_lldb_global_tmp_dir); }); return g_fields->m_lldb_global_tmp_dir; @@ -204,14 +209,15 @@ ArchSpec HostInfoBase::GetAugmentedArchSpec(llvm::StringRef triple) { normalized_triple.setVendor(host_triple.getVendor()); if (normalized_triple.getOSName().empty()) normalized_triple.setOS(host_triple.getOS()); - if (normalized_triple.getEnvironmentName().empty()) + if (normalized_triple.getEnvironmentName().empty() && + !host_triple.getEnvironmentName().empty()) normalized_triple.setEnvironment(host_triple.getEnvironment()); return ArchSpec(normalized_triple); } bool HostInfoBase::ComputePathRelativeToLibrary(FileSpec &file_spec, llvm::StringRef dir) { - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + Log *log = GetLog(LLDBLog::Host); FileSpec lldb_file_spec = GetShlibDir(); if (!lldb_file_spec) @@ -246,8 +252,7 @@ bool HostInfoBase::ComputeSharedLibraryDirectory(FileSpec &file_spec) { // On other posix systems, we will get .../lib(64|32)?/liblldb.so. FileSpec lldb_file_spec(Host::GetModuleFileSpecForHostAddress( - reinterpret_cast<void *>( - HostInfoBase::ComputeSharedLibraryDirectory))); + reinterpret_cast<void *>(HostInfoBase::ComputeSharedLibraryDirectory))); if (g_shlib_dir_helper) g_shlib_dir_helper(lldb_file_spec); diff --git a/contrib/llvm-project/lldb/source/Host/common/HostNativeThreadBase.cpp b/contrib/llvm-project/lldb/source/Host/common/HostNativeThreadBase.cpp index b8223e3ec42a..a9cbb69c4d98 100644 --- a/contrib/llvm-project/lldb/source/Host/common/HostNativeThreadBase.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/HostNativeThreadBase.cpp @@ -9,6 +9,7 @@ #include "lldb/Host/HostNativeThreadBase.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/ThreadLauncher.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "llvm/ADT/StringExtras.h" @@ -18,7 +19,7 @@ using namespace lldb; using namespace lldb_private; HostNativeThreadBase::HostNativeThreadBase(thread_t thread) - : m_thread(thread), m_result(0) {} // NOLINT(modernize-use-nullptr) + : m_thread(thread) {} lldb::thread_t HostNativeThreadBase::GetSystemHandle() const { return m_thread; @@ -51,16 +52,12 @@ lldb::thread_t HostNativeThreadBase::Release() { lldb::thread_result_t HostNativeThreadBase::ThreadCreateTrampoline(lldb::thread_arg_t arg) { - ThreadLauncher::HostThreadCreateInfo *info = - (ThreadLauncher::HostThreadCreateInfo *)arg; - llvm::set_thread_name(info->thread_name); + std::unique_ptr<ThreadLauncher::HostThreadCreateInfo> info_up( + (ThreadLauncher::HostThreadCreateInfo *)arg); + llvm::set_thread_name(info_up->thread_name); - thread_func_t thread_fptr = info->thread_fptr; - thread_arg_t thread_arg = info->thread_arg; - - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); LLDB_LOGF(log, "thread created"); - delete info; - return thread_fptr(thread_arg); + return info_up->impl(); } diff --git a/contrib/llvm-project/lldb/source/Host/common/HostProcess.cpp b/contrib/llvm-project/lldb/source/Host/common/HostProcess.cpp index 06dd192013ba..8db5a61e8796 100644 --- a/contrib/llvm-project/lldb/source/Host/common/HostProcess.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/HostProcess.cpp @@ -22,20 +22,15 @@ HostProcess::~HostProcess() = default; Status HostProcess::Terminate() { return m_native_process->Terminate(); } -Status HostProcess::GetMainModule(FileSpec &file_spec) const { - return m_native_process->GetMainModule(file_spec); -} - lldb::pid_t HostProcess::GetProcessId() const { return m_native_process->GetProcessId(); } bool HostProcess::IsRunning() const { return m_native_process->IsRunning(); } -llvm::Expected<HostThread> -HostProcess::StartMonitoring(const Host::MonitorChildProcessCallback &callback, - bool monitor_signals) { - return m_native_process->StartMonitoring(callback, monitor_signals); +llvm::Expected<HostThread> HostProcess::StartMonitoring( + const Host::MonitorChildProcessCallback &callback) { + return m_native_process->StartMonitoring(callback); } HostNativeProcessBase &HostProcess::GetNativeProcess() { diff --git a/contrib/llvm-project/lldb/source/Host/common/MainLoop.cpp b/contrib/llvm-project/lldb/source/Host/common/MainLoop.cpp index d36587ce2346..8e384c9266b6 100644 --- a/contrib/llvm-project/lldb/source/Host/common/MainLoop.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/MainLoop.cpp @@ -347,6 +347,10 @@ MainLoop::RegisterSignal(int signo, const Callback &callback, Status &error) { #endif } +void MainLoop::AddPendingCallback(const Callback &callback) { + m_pending_callbacks.push_back(callback); +} + void MainLoop::UnregisterReadObject(IOObject::WaitableHandle handle) { bool erased = m_read_fds.erase(handle); UNUSED_IF_ASSERT_DISABLED(erased); @@ -401,6 +405,10 @@ Status MainLoop::Run() { return error; impl.ProcessEvents(); + + for (const Callback &callback : m_pending_callbacks) + callback(*this); + m_pending_callbacks.clear(); } return Status(); } diff --git a/contrib/llvm-project/lldb/source/Host/common/MonitoringProcessLauncher.cpp b/contrib/llvm-project/lldb/source/Host/common/MonitoringProcessLauncher.cpp index 1ef345cd5082..953934ea4a6e 100644 --- a/contrib/llvm-project/lldb/source/Host/common/MonitoringProcessLauncher.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/MonitoringProcessLauncher.cpp @@ -10,6 +10,7 @@ #include "lldb/Host/FileSystem.h" #include "lldb/Host/HostProcess.h" #include "lldb/Host/ProcessLaunchInfo.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "llvm/Support/FileSystem.h" @@ -50,12 +51,11 @@ MonitoringProcessLauncher::LaunchProcess(const ProcessLaunchInfo &launch_info, m_delegate_launcher->LaunchProcess(resolved_info, error); if (process.GetProcessId() != LLDB_INVALID_PROCESS_ID) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); assert(launch_info.GetMonitorProcessCallback()); llvm::Expected<HostThread> maybe_thread = - process.StartMonitoring(launch_info.GetMonitorProcessCallback(), - launch_info.GetMonitorSignals()); + process.StartMonitoring(launch_info.GetMonitorProcessCallback()); if (!maybe_thread) error.SetErrorStringWithFormatv("failed to launch host thread: {}", llvm::toString(maybe_thread.takeError())); diff --git a/contrib/llvm-project/lldb/source/Host/common/NativeProcessProtocol.cpp b/contrib/llvm-project/lldb/source/Host/common/NativeProcessProtocol.cpp index ea80a05430f7..be521a31cb37 100644 --- a/contrib/llvm-project/lldb/source/Host/common/NativeProcessProtocol.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/NativeProcessProtocol.cpp @@ -12,6 +12,7 @@ #include "lldb/Host/common/NativeRegisterContext.h" #include "lldb/Host/common/NativeThreadProtocol.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/State.h" #include "lldb/lldb-enumerations.h" @@ -74,7 +75,7 @@ llvm::Optional<WaitStatus> NativeProcessProtocol::GetExitStatus() { bool NativeProcessProtocol::SetExitStatus(WaitStatus status, bool bNotifyStateChange) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOG(log, "status = {0}, notify = {1}", status, bNotifyStateChange); // Exit status already set @@ -128,7 +129,7 @@ NativeProcessProtocol::GetWatchpointMap() const { llvm::Optional<std::pair<uint32_t, uint32_t>> NativeProcessProtocol::GetHardwareDebugSupportInfo() const { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); // get any thread NativeThreadProtocol *thread( @@ -152,7 +153,7 @@ Status NativeProcessProtocol::SetWatchpoint(lldb::addr_t addr, size_t size, // thread that is attached to via the (FIXME implement) OnThreadAttached () // method. - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); // Update the thread list UpdateThreads(); @@ -236,7 +237,7 @@ Status NativeProcessProtocol::SetHardwareBreakpoint(lldb::addr_t addr, // This default implementation assumes setting a hardware breakpoint for this // process will require setting same hardware breakpoint for each of its // existing threads. New thread will do the same once created. - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); // Update the thread list UpdateThreads(); @@ -308,24 +309,36 @@ Status NativeProcessProtocol::RemoveHardwareBreakpoint(lldb::addr_t addr) { void NativeProcessProtocol::SynchronouslyNotifyProcessStateChanged( lldb::StateType state) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); m_delegate.ProcessStateChanged(this, state); + switch (state) { + case eStateStopped: + case eStateExited: + case eStateCrashed: + NotifyTracersProcessDidStop(); + break; + default: + break; + } + LLDB_LOG(log, "sent state notification [{0}] from process {1}", state, GetID()); } void NativeProcessProtocol::NotifyDidExec() { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOG(log, "process {0} exec()ed", GetID()); + m_software_breakpoints.clear(); + m_delegate.DidExec(this); } Status NativeProcessProtocol::SetSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); LLDB_LOG(log, "addr = {0:x}, size_hint = {1}", addr, size_hint); auto it = m_software_breakpoints.find(addr); @@ -342,7 +355,7 @@ Status NativeProcessProtocol::SetSoftwareBreakpoint(lldb::addr_t addr, } Status NativeProcessProtocol::RemoveSoftwareBreakpoint(lldb::addr_t addr) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); LLDB_LOG(log, "addr = {0:x}", addr); auto it = m_software_breakpoints.find(addr); if (it == m_software_breakpoints.end()) @@ -408,7 +421,7 @@ Status NativeProcessProtocol::RemoveSoftwareBreakpoint(lldb::addr_t addr) { llvm::Expected<NativeProcessProtocol::SoftwareBreakpoint> NativeProcessProtocol::EnableSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); auto expected_trap = GetSoftwareBreakpointTrapOpcode(size_hint); if (!expected_trap) @@ -554,7 +567,7 @@ size_t NativeProcessProtocol::GetSoftwareBreakpointPCOffset() { void NativeProcessProtocol::FixupBreakpointPCAsNeeded( NativeThreadProtocol &thread) { - Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS); + Log *log = GetLog(LLDBLog::Breakpoints); Status error; diff --git a/contrib/llvm-project/lldb/source/Host/common/NativeRegisterContext.cpp b/contrib/llvm-project/lldb/source/Host/common/NativeRegisterContext.cpp index d0afc2b47dac..7e4ffe8dfa18 100644 --- a/contrib/llvm-project/lldb/source/Host/common/NativeRegisterContext.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/NativeRegisterContext.cpp @@ -7,8 +7,7 @@ //===----------------------------------------------------------------------===// #include "lldb/Host/common/NativeRegisterContext.h" - -#include "lldb/Utility/Log.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/RegisterValue.h" #include "lldb/Host/PosixApi.h" @@ -122,7 +121,7 @@ const char *NativeRegisterContext::GetRegisterSetNameForRegisterAtIndex( } lldb::addr_t NativeRegisterContext::GetPC(lldb::addr_t fail_value) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); @@ -197,7 +196,7 @@ NativeRegisterContext::ReadRegisterAsUnsigned(uint32_t reg, uint64_t NativeRegisterContext::ReadRegisterAsUnsigned(const RegisterInfo *reg_info, lldb::addr_t fail_value) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); if (reg_info) { RegisterValue value; diff --git a/contrib/llvm-project/lldb/source/Host/common/ProcessLaunchInfo.cpp b/contrib/llvm-project/lldb/source/Host/common/ProcessLaunchInfo.cpp index 07e4f15c9e9e..b8827992bc7a 100644 --- a/contrib/llvm-project/lldb/source/Host/common/ProcessLaunchInfo.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/ProcessLaunchInfo.cpp @@ -13,6 +13,7 @@ #include "lldb/Host/FileSystem.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/ProcessLaunchInfo.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" @@ -40,9 +41,7 @@ ProcessLaunchInfo::ProcessLaunchInfo(const FileSpec &stdin_file_spec, const FileSpec &working_directory, uint32_t launch_flags) : 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_file_actions(), m_pty(new PseudoTerminal), m_scripted_process_class_name(), m_scripted_process_dictionary_sp() { if (stdin_file_spec) { FileAction file_action; @@ -176,27 +175,18 @@ void ProcessLaunchInfo::Clear() { m_scripted_process_dictionary_sp.reset(); } -void ProcessLaunchInfo::SetMonitorProcessCallback( - const Host::MonitorChildProcessCallback &callback, bool monitor_signals) { - m_monitor_callback = callback; - m_monitor_signals = monitor_signals; -} - -bool ProcessLaunchInfo::NoOpMonitorCallback(lldb::pid_t pid, bool exited, int signal, int status) { - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS); - LLDB_LOG(log, "pid = {0}, exited = {1}, signal = {2}, status = {3}", pid, - exited, signal, status); - return true; +void ProcessLaunchInfo::NoOpMonitorCallback(lldb::pid_t pid, int signal, + int status) { + Log *log = GetLog(LLDBLog::Process); + LLDB_LOG(log, "pid = {0}, signal = {1}, status = {2}", pid, signal, status); } bool ProcessLaunchInfo::MonitorProcess() const { if (m_monitor_callback && ProcessIDIsValid()) { llvm::Expected<HostThread> maybe_thread = - Host::StartMonitoringChildProcess(m_monitor_callback, GetProcessID(), - m_monitor_signals); + Host::StartMonitoringChildProcess(m_monitor_callback, GetProcessID()); if (!maybe_thread) - LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST), - "failed to launch host thread: {}", + LLDB_LOG(GetLog(LLDBLog::Host), "failed to launch host thread: {}", llvm::toString(maybe_thread.takeError())); return true; } @@ -211,7 +201,7 @@ void ProcessLaunchInfo::SetDetachOnError(bool enable) { } llvm::Error ProcessLaunchInfo::SetUpPtyRedirection() { - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS); + Log *log = GetLog(LLDBLog::Process); bool stdin_free = GetFileActionForFD(STDIN_FILENO) == nullptr; bool stdout_free = GetFileActionForFD(STDOUT_FILENO) == nullptr; diff --git a/contrib/llvm-project/lldb/source/Host/common/PseudoTerminal.cpp b/contrib/llvm-project/lldb/source/Host/common/PseudoTerminal.cpp index dce4c5185c7b..be4c3c7928df 100644 --- a/contrib/llvm-project/lldb/source/Host/common/PseudoTerminal.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/PseudoTerminal.cpp @@ -22,6 +22,10 @@ #include "lldb/Host/PosixApi.h" +#if defined(__APPLE__) +#include <Availability.h> +#endif + #if defined(__ANDROID__) int posix_openpt(int flags); #endif @@ -99,21 +103,35 @@ llvm::Error PseudoTerminal::OpenSecondary(int oflag) { std::error_code(errno, std::generic_category())); } -std::string PseudoTerminal::GetSecondaryName() const { - assert(m_primary_fd >= 0); -#if HAVE_PTSNAME_R - char buf[PATH_MAX]; - buf[0] = '\0'; - int r = ptsname_r(m_primary_fd, buf, sizeof(buf)); - (void)r; - assert(r == 0); - return buf; -#else +#if !HAVE_PTSNAME_R || defined(__APPLE__) +static std::string use_ptsname(int fd) { static std::mutex mutex; std::lock_guard<std::mutex> guard(mutex); - const char *r = ptsname(m_primary_fd); + const char *r = ptsname(fd); assert(r != nullptr); return r; +} +#endif + +std::string PseudoTerminal::GetSecondaryName() const { + assert(m_primary_fd >= 0); +#if HAVE_PTSNAME_R +#if defined(__APPLE__) + if (__builtin_available(macos 10.13.4, iOS 11.3, tvOS 11.3, watchOS 4.4, *)) { +#endif + char buf[PATH_MAX]; + buf[0] = '\0'; + int r = ptsname_r(m_primary_fd, buf, sizeof(buf)); + (void)r; + assert(r == 0); + return buf; +#if defined(__APPLE__) + } else { + return use_ptsname(m_primary_fd); + } +#endif +#else + return use_ptsname(m_primary_fd); #endif } diff --git a/contrib/llvm-project/lldb/source/Host/common/Socket.cpp b/contrib/llvm-project/lldb/source/Host/common/Socket.cpp index d8b8f54a6468..c2fb5509034e 100644 --- a/contrib/llvm-project/lldb/source/Host/common/Socket.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/Socket.cpp @@ -13,6 +13,7 @@ #include "lldb/Host/SocketAddress.h" #include "lldb/Host/common/TCPSocket.h" #include "lldb/Host/common/UDPSocket.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "llvm/ADT/STLExtras.h" @@ -146,7 +147,7 @@ std::unique_ptr<Socket> Socket::Create(const SocketProtocol protocol, llvm::Expected<std::unique_ptr<Socket>> Socket::TcpConnect(llvm::StringRef host_and_port, bool child_processes_inherit) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); + Log *log = GetLog(LLDBLog::Connection); LLDB_LOG(log, "host_and_port = {0}", host_and_port); Status error; @@ -165,7 +166,7 @@ Socket::TcpConnect(llvm::StringRef host_and_port, llvm::Expected<std::unique_ptr<TCPSocket>> Socket::TcpListen(llvm::StringRef host_and_port, bool child_processes_inherit, int backlog) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); + Log *log = GetLog(LLDBLog::Connection); LLDB_LOG(log, "host_and_port = {0}", host_and_port); std::unique_ptr<TCPSocket> listen_socket( @@ -225,7 +226,7 @@ Status Socket::Read(void *buf, size_t &num_bytes) { } else num_bytes = bytes_received; - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_COMMUNICATION)); + Log *log = GetLog(LLDBLog::Communication); if (log) { LLDB_LOGF(log, "%p Socket::Read() (socket = %" PRIu64 @@ -253,7 +254,7 @@ Status Socket::Write(const void *buf, size_t &num_bytes) { } else num_bytes = bytes_sent; - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_COMMUNICATION)); + Log *log = GetLog(LLDBLog::Communication); if (log) { LLDB_LOGF(log, "%p Socket::Write() (socket = %" PRIu64 @@ -277,7 +278,7 @@ Status Socket::Close() { if (!IsValid() || !m_should_close_fd) return error; - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); + Log *log = GetLog(LLDBLog::Connection); LLDB_LOGF(log, "%p Socket::Close (fd = %" PRIu64 ")", static_cast<void *>(this), static_cast<uint64_t>(m_socket)); diff --git a/contrib/llvm-project/lldb/source/Host/common/TCPSocket.cpp b/contrib/llvm-project/lldb/source/Host/common/TCPSocket.cpp index 28c3fa1188c2..eabc9fef8a66 100644 --- a/contrib/llvm-project/lldb/source/Host/common/TCPSocket.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/TCPSocket.cpp @@ -14,6 +14,7 @@ #include "lldb/Host/Config.h" #include "lldb/Host/MainLoop.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "llvm/Config/llvm-config.h" @@ -148,7 +149,7 @@ Status TCPSocket::CreateSocket(int domain) { Status TCPSocket::Connect(llvm::StringRef name) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_COMMUNICATION)); + Log *log = GetLog(LLDBLog::Communication); LLDB_LOGF(log, "TCPSocket::%s (host/port = %s)", __FUNCTION__, name.data()); Status error; @@ -169,7 +170,7 @@ Status TCPSocket::Connect(llvm::StringRef name) { if (-1 == llvm::sys::RetryAfterSignal(-1, ::connect, GetNativeSocket(), &address.sockaddr(), address.GetLength())) { - CLOSE_SOCKET(GetNativeSocket()); + Close(); continue; } @@ -184,7 +185,7 @@ Status TCPSocket::Connect(llvm::StringRef name) { } Status TCPSocket::Listen(llvm::StringRef name, int backlog) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); + Log *log = GetLog(LLDBLog::Connection); LLDB_LOGF(log, "TCPSocket::%s (%s)", __FUNCTION__, name.data()); Status error; diff --git a/contrib/llvm-project/lldb/source/Host/common/ThreadLauncher.cpp b/contrib/llvm-project/lldb/source/Host/common/ThreadLauncher.cpp index bd104b3e4aed..28c90215f874 100644 --- a/contrib/llvm-project/lldb/source/Host/common/ThreadLauncher.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/ThreadLauncher.cpp @@ -21,17 +21,18 @@ using namespace lldb; using namespace lldb_private; -llvm::Expected<HostThread> ThreadLauncher::LaunchThread( - llvm::StringRef name, lldb::thread_func_t thread_function, - lldb::thread_arg_t thread_arg, size_t min_stack_byte_size) { - // Host::ThreadCreateTrampoline will delete this pointer for us. - HostThreadCreateInfo *info_ptr = - new HostThreadCreateInfo(name.data(), thread_function, thread_arg); +llvm::Expected<HostThread> +ThreadLauncher::LaunchThread(llvm::StringRef name, + std::function<thread_result_t()> impl, + size_t min_stack_byte_size) { + // Host::ThreadCreateTrampoline will take ownership if thread creation is + // successful. + auto info_up = std::make_unique<HostThreadCreateInfo>(name.str(), impl); lldb::thread_t thread; #ifdef _WIN32 thread = (lldb::thread_t)::_beginthreadex( 0, (unsigned)min_stack_byte_size, - HostNativeThread::ThreadCreateTrampoline, info_ptr, 0, NULL); + HostNativeThread::ThreadCreateTrampoline, info_up.get(), 0, NULL); if (thread == LLDB_INVALID_HOST_THREAD) return llvm::errorCodeToError(llvm::mapWindowsError(GetLastError())); #else @@ -63,7 +64,7 @@ llvm::Expected<HostThread> ThreadLauncher::LaunchThread( } int err = ::pthread_create(&thread, thread_attr_ptr, - HostNativeThread::ThreadCreateTrampoline, info_ptr); + HostNativeThread::ThreadCreateTrampoline, info_up.get()); if (destroy_attr) ::pthread_attr_destroy(&thread_attr); @@ -73,5 +74,6 @@ llvm::Expected<HostThread> ThreadLauncher::LaunchThread( std::error_code(err, std::generic_category())); #endif + info_up.release(); return HostThread(thread); } diff --git a/contrib/llvm-project/lldb/source/Host/common/UDPSocket.cpp b/contrib/llvm-project/lldb/source/Host/common/UDPSocket.cpp index 31266c980e0e..e40066d519c6 100644 --- a/contrib/llvm-project/lldb/source/Host/common/UDPSocket.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/UDPSocket.cpp @@ -9,6 +9,7 @@ #include "lldb/Host/common/UDPSocket.h" #include "lldb/Host/Config.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #if LLDB_ENABLE_POSIX @@ -54,7 +55,7 @@ llvm::Expected<std::unique_ptr<UDPSocket>> UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit) { std::unique_ptr<UDPSocket> socket; - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); + Log *log = GetLog(LLDBLog::Connection); LLDB_LOG(log, "host/port = {0}", name); Status error; diff --git a/contrib/llvm-project/lldb/source/Host/netbsd/HostNetBSD.cpp b/contrib/llvm-project/lldb/source/Host/netbsd/HostNetBSD.cpp index af31a11a20a0..9168ed97b77e 100644 --- a/contrib/llvm-project/lldb/source/Host/netbsd/HostNetBSD.cpp +++ b/contrib/llvm-project/lldb/source/Host/netbsd/HostNetBSD.cpp @@ -25,6 +25,7 @@ #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/NameMatches.h" #include "lldb/Utility/ProcessInfo.h" @@ -101,16 +102,16 @@ static bool GetNetBSDProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr, } static bool GetNetBSDProcessCPUType(ProcessInstanceInfo &process_info) { - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + Log *log = GetLog(LLDBLog::Host); if (process_info.ProcessIDIsValid()) { auto buffer_sp = FileSystem::Instance().CreateDataBuffer( process_info.GetExecutableFile(), 0x20, 0); if (buffer_sp) { - uint8_t exe_class = - llvm::object::getElfArchType( - {buffer_sp->GetChars(), size_t(buffer_sp->GetByteSize())}) - .first; + uint8_t exe_class = llvm::object::getElfArchType( + {reinterpret_cast<char *>(buffer_sp->GetBytes()), + size_t(buffer_sp->GetByteSize())}) + .first; switch (exe_class) { case llvm::ELF::ELFCLASS32: diff --git a/contrib/llvm-project/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp b/contrib/llvm-project/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp index b3140f7b0fd7..dc5b24979fb5 100644 --- a/contrib/llvm-project/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp +++ b/contrib/llvm-project/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp @@ -13,10 +13,11 @@ #define _DARWIN_UNLIMITED_SELECT #endif +#include "lldb/Host/posix/ConnectionFileDescriptorPosix.h" #include "lldb/Host/Config.h" #include "lldb/Host/Socket.h" #include "lldb/Host/SocketAddress.h" -#include "lldb/Host/posix/ConnectionFileDescriptorPosix.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/SelectHelper.h" #include "lldb/Utility/Timeout.h" @@ -54,8 +55,7 @@ ConnectionFileDescriptor::ConnectionFileDescriptor(bool child_processes_inherit) : Connection(), m_pipe(), m_mutex(), m_shutting_down(false), m_child_processes_inherit(child_processes_inherit) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION | - LIBLLDB_LOG_OBJECT)); + Log *log(GetLog(LLDBLog::Connection | LLDBLog::Object)); LLDB_LOGF(log, "%p ConnectionFileDescriptor::ConnectionFileDescriptor ()", static_cast<void *>(this)); } @@ -66,8 +66,7 @@ ConnectionFileDescriptor::ConnectionFileDescriptor(int fd, bool owns_fd) m_io_sp = std::make_shared<NativeFile>(fd, File::eOpenOptionReadWrite, owns_fd); - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION | - LIBLLDB_LOG_OBJECT)); + Log *log(GetLog(LLDBLog::Connection | LLDBLog::Object)); LLDB_LOGF(log, "%p ConnectionFileDescriptor::ConnectionFileDescriptor (fd = " "%i, owns_fd = %i)", @@ -82,8 +81,7 @@ ConnectionFileDescriptor::ConnectionFileDescriptor(Socket *socket) } ConnectionFileDescriptor::~ConnectionFileDescriptor() { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION | - LIBLLDB_LOG_OBJECT)); + Log *log(GetLog(LLDBLog::Connection | LLDBLog::Object)); LLDB_LOGF(log, "%p ConnectionFileDescriptor::~ConnectionFileDescriptor ()", static_cast<void *>(this)); Disconnect(nullptr); @@ -93,7 +91,7 @@ ConnectionFileDescriptor::~ConnectionFileDescriptor() { void ConnectionFileDescriptor::OpenCommandPipe() { CloseCommandPipe(); - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); + Log *log = GetLog(LLDBLog::Connection); // Make the command file descriptor here: Status result = m_pipe.CreateNew(m_child_processes_inherit); if (!result.Success()) { @@ -111,7 +109,7 @@ void ConnectionFileDescriptor::OpenCommandPipe() { } void ConnectionFileDescriptor::CloseCommandPipe() { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); + Log *log = GetLog(LLDBLog::Connection); LLDB_LOGF(log, "%p ConnectionFileDescriptor::CloseCommandPipe()", static_cast<void *>(this)); @@ -124,7 +122,8 @@ bool ConnectionFileDescriptor::IsConnected() const { ConnectionStatus ConnectionFileDescriptor::Connect(llvm::StringRef path, Status *error_ptr) { - return Connect(path, nullptr, error_ptr); + return Connect( + path, [](llvm::StringRef) {}, error_ptr); } ConnectionStatus @@ -132,7 +131,7 @@ ConnectionFileDescriptor::Connect(llvm::StringRef path, socket_id_callback_type socket_id_callback, Status *error_ptr) { std::lock_guard<std::recursive_mutex> guard(m_mutex); - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); + Log *log = GetLog(LLDBLog::Connection); LLDB_LOGF(log, "%p ConnectionFileDescriptor::Connect (url = '%s')", static_cast<void *>(this), path.str().c_str()); @@ -189,7 +188,7 @@ bool ConnectionFileDescriptor::InterruptRead() { } ConnectionStatus ConnectionFileDescriptor::Disconnect(Status *error_ptr) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); + Log *log = GetLog(LLDBLog::Connection); LLDB_LOGF(log, "%p ConnectionFileDescriptor::Disconnect ()", static_cast<void *>(this)); @@ -250,7 +249,7 @@ size_t ConnectionFileDescriptor::Read(void *dst, size_t dst_len, const Timeout<std::micro> &timeout, ConnectionStatus &status, Status *error_ptr) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); + Log *log = GetLog(LLDBLog::Connection); std::unique_lock<std::recursive_mutex> locker(m_mutex, std::defer_lock); if (!locker.try_lock()) { @@ -358,7 +357,7 @@ size_t ConnectionFileDescriptor::Read(void *dst, size_t dst_len, size_t ConnectionFileDescriptor::Write(const void *src, size_t src_len, ConnectionStatus &status, Status *error_ptr) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); + Log *log = GetLog(LLDBLog::Connection); LLDB_LOGF(log, "%p ConnectionFileDescriptor::Write (src = %p, src_len = %" PRIu64 ")", @@ -446,7 +445,7 @@ ConnectionFileDescriptor::BytesAvailable(const Timeout<std::micro> &timeout, // Read. If we ever get used more generally we will need to lock here as // well. - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_CONNECTION)); + Log *log = GetLog(LLDBLog::Connection); LLDB_LOG(log, "this = {0}, timeout = {1}", this, timeout); // Make a copy of the file descriptors to make sure we don't have another @@ -656,8 +655,8 @@ ConnectionFileDescriptor::ConnectUDP(llvm::StringRef s, if (error_ptr) *error_ptr = socket.takeError(); else - LLDB_LOG_ERROR(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION), - socket.takeError(), "tcp connect failed: {0}"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Connection), socket.takeError(), + "tcp connect failed: {0}"); return eConnectionStatusError; } m_io_sp = std::move(*socket); diff --git a/contrib/llvm-project/lldb/source/Host/posix/FileSystemPosix.cpp b/contrib/llvm-project/lldb/source/Host/posix/FileSystemPosix.cpp index 0aa34bc59435..3660f67895a4 100644 --- a/contrib/llvm-project/lldb/source/Host/posix/FileSystemPosix.cpp +++ b/contrib/llvm-project/lldb/source/Host/posix/FileSystemPosix.cpp @@ -72,11 +72,9 @@ Status FileSystem::ResolveSymbolicLink(const FileSpec &src, FileSpec &dst) { } FILE *FileSystem::Fopen(const char *path, const char *mode) { - Collect(path); return llvm::sys::RetryAfterSignal(nullptr, ::fopen, path, mode); } int FileSystem::Open(const char *path, int flags, int mode) { - Collect(path); return llvm::sys::RetryAfterSignal(-1, ::open, path, flags, mode); } diff --git a/contrib/llvm-project/lldb/source/Host/posix/HostProcessPosix.cpp b/contrib/llvm-project/lldb/source/Host/posix/HostProcessPosix.cpp index 8599a94d2241..064b5c7f8e80 100644 --- a/contrib/llvm-project/lldb/source/Host/posix/HostProcessPosix.cpp +++ b/contrib/llvm-project/lldb/source/Host/posix/HostProcessPosix.cpp @@ -49,31 +49,6 @@ Status HostProcessPosix::Signal(lldb::process_t process, int signo) { Status HostProcessPosix::Terminate() { return Signal(SIGKILL); } -Status HostProcessPosix::GetMainModule(FileSpec &file_spec) const { - Status error; - - // Use special code here because proc/[pid]/exe is a symbolic link. - char link_path[PATH_MAX]; - if (snprintf(link_path, PATH_MAX, "/proc/%" PRIu64 "/exe", m_process) != 1) { - error.SetErrorString("Unable to build /proc/<pid>/exe string"); - return error; - } - - error = FileSystem::Instance().Readlink(FileSpec(link_path), file_spec); - if (!error.Success()) - return error; - - // If the binary has been deleted, the link name has " (deleted)" appended. - // Remove if there. - if (file_spec.GetFilename().GetStringRef().endswith(" (deleted)")) { - const char *filename = file_spec.GetFilename().GetCString(); - static const size_t deleted_len = strlen(" (deleted)"); - const size_t len = file_spec.GetFilename().GetLength(); - file_spec.GetFilename().SetCStringWithLength(filename, len - deleted_len); - } - return error; -} - lldb::pid_t HostProcessPosix::GetProcessId() const { return m_process; } bool HostProcessPosix::IsRunning() const { @@ -86,7 +61,6 @@ bool HostProcessPosix::IsRunning() const { } llvm::Expected<HostThread> HostProcessPosix::StartMonitoring( - const Host::MonitorChildProcessCallback &callback, bool monitor_signals) { - return Host::StartMonitoringChildProcess(callback, m_process, - monitor_signals); + const Host::MonitorChildProcessCallback &callback) { + return Host::StartMonitoringChildProcess(callback, m_process); } diff --git a/contrib/llvm-project/lldb/source/Initialization/SystemInitializerCommon.cpp b/contrib/llvm-project/lldb/source/Initialization/SystemInitializerCommon.cpp index 1c8406f68784..b14218442cec 100644 --- a/contrib/llvm-project/lldb/source/Initialization/SystemInitializerCommon.cpp +++ b/contrib/llvm-project/lldb/source/Initialization/SystemInitializerCommon.cpp @@ -12,7 +12,7 @@ #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/Socket.h" -#include "lldb/Utility/Log.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/ReproducerProvider.h" #include "lldb/Utility/Timer.h" #include "lldb/Version/Version.h" @@ -43,42 +43,15 @@ SystemInitializerCommon::~SystemInitializerCommon() = default; /// Initialize the FileSystem based on the current reproducer mode. static llvm::Error InitializeFileSystem() { auto &r = repro::Reproducer::Instance(); - if (repro::Loader *loader = r.GetLoader()) { - FileSpec vfs_mapping = loader->GetFile<FileProvider::Info>(); - if (vfs_mapping) { - if (llvm::Error e = FileSystem::Initialize(vfs_mapping)) - return e; - } else { - FileSystem::Initialize(); - } - - // Set the current working directory form the reproducer. - llvm::Expected<std::string> working_dir = - repro::GetDirectoryFrom<WorkingDirectoryProvider>(loader); - if (!working_dir) - return working_dir.takeError(); - if (std::error_code ec = FileSystem::Instance() - .GetVirtualFileSystem() - ->setCurrentWorkingDirectory(*working_dir)) { - return llvm::errorCodeToError(ec); - } - - // Set the home directory from the reproducer. - llvm::Expected<std::string> home_dir = - repro::GetDirectoryFrom<HomeDirectoryProvider>(loader); - if (!home_dir) - return home_dir.takeError(); - FileSystem::Instance().SetHomeDirectory(*home_dir); - - return llvm::Error::success(); - } if (repro::Generator *g = r.GetGenerator()) { repro::VersionProvider &vp = g->GetOrCreate<repro::VersionProvider>(); vp.SetVersion(lldb_private::GetVersion()); repro::FileProvider &fp = g->GetOrCreate<repro::FileProvider>(); - FileSystem::Initialize(fp.GetFileCollector()); + + FileSystem::Initialize(llvm::FileCollector::createCollectorVFS( + llvm::vfs::getRealFileSystem(), fp.GetFileCollector())); fp.RecordInterestingDirectory( g->GetOrCreate<repro::WorkingDirectoryProvider>().GetDirectory()); @@ -125,7 +98,7 @@ llvm::Error SystemInitializerCommon::Initialize() { if (auto e = InitializeFileSystem()) return e; - Log::Initialize(); + InitializeLldbChannel(); HostInfo::Initialize(m_shlib_dir_helper); llvm::Error error = Socket::Initialize(); diff --git a/contrib/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp b/contrib/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp index 59c23716bf89..6ef209b20fc6 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp @@ -45,6 +45,7 @@ #include "lldb/Core/Debugger.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/StreamFile.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Reproducer.h" #include "lldb/Utility/State.h" @@ -83,6 +84,10 @@ #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/ScopedPrinter.h" +#if defined(__APPLE__) +#include <TargetConditionals.h> +#endif + using namespace lldb; using namespace lldb_private; @@ -123,7 +128,8 @@ CommandInterpreter::CommandInterpreter(Debugger &debugger, m_debugger(debugger), m_synchronous_execution(true), m_skip_lldbinit_files(false), m_skip_app_init_files(false), m_comment_char('#'), m_batch_command_mode(false), - m_truncation_warning(eNoTruncation), m_command_source_depth(0) { + m_truncation_warning(eNoOmission), m_max_depth_warning(eNoOmission), + m_command_source_depth(0) { SetEventName(eBroadcastBitThreadShouldExit, "thread-should-exit"); SetEventName(eBroadcastBitResetPrompt, "reset-prompt"); SetEventName(eBroadcastBitQuitCommandReceived, "quit"); @@ -206,7 +212,7 @@ bool CommandInterpreter::SetQuitExitCode(int exit_code) { } int CommandInterpreter::GetQuitExitCode(bool &exited) const { - exited = m_quit_exit_code.hasValue(); + exited = m_quit_exit_code.has_value(); if (exited) return *m_quit_exit_code; return 0; @@ -239,6 +245,12 @@ bool CommandInterpreter::GetRepeatPreviousCommand() const { nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0); } +bool CommandInterpreter::GetRequireCommandOverwrite() const { + const uint32_t idx = ePropertyRequireCommandOverwrite; + return m_collection_sp->GetPropertyAtIndexAsBoolean( + nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0); +} + void CommandInterpreter::Initialize() { LLDB_SCOPED_TIMER(); @@ -433,7 +445,7 @@ void CommandInterpreter::Initialize() { if (cmd_obj_sp) { alias_arguments_vector_sp = std::make_shared<OptionArgVector>(); #if defined(__APPLE__) -#if defined(TARGET_OS_IPHONE) +#if TARGET_OS_IPHONE AddAlias("r", cmd_obj_sp, "--"); AddAlias("run", cmd_obj_sp, "--"); #else @@ -1434,7 +1446,7 @@ void CommandInterpreter::GetHelp(CommandReturnObject &result, result.AppendMessage("Current user-defined container commands:"); result.AppendMessage(""); max_len = FindLongestCommandWord(m_user_mw_dict); - for (pos = m_user_dict.begin(); pos != m_user_mw_dict.end(); ++pos) { + for (pos = m_user_mw_dict.begin(); pos != m_user_mw_dict.end(); ++pos) { OutputFormattedHelpText(result.GetOutputStream(), pos->first, "--", pos->second->GetHelp(), max_len); } @@ -1825,7 +1837,7 @@ bool CommandInterpreter::HandleCommand(const char *command_line, std::string command_string(command_line); std::string original_command_string(command_line); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMANDS)); + Log *log = GetLog(LLDBLog::Commands); llvm::PrettyStackTraceFormat stack_trace("HandleCommand(command = \"%s\")", command_line); @@ -1943,16 +1955,21 @@ bool CommandInterpreter::HandleCommand(const char *command_line, // arguments. if (cmd_obj != nullptr) { - if (add_to_history) { + // If we got here when empty_command was true, then this command is a + // stored "repeat command" which we should give a chance to produce it's + // repeat command, even though we don't add repeat commands to the history. + if (add_to_history || empty_command) { Args command_args(command_string); - const char *repeat_command = cmd_obj->GetRepeatCommand(command_args, 0); - if (repeat_command != nullptr) - m_repeat_command.assign(repeat_command); + llvm::Optional<std::string> repeat_command = + cmd_obj->GetRepeatCommand(command_args, 0); + if (repeat_command) + m_repeat_command.assign(*repeat_command); else m_repeat_command.assign(original_command_string); + } + if (add_to_history) m_command_history.AppendString(original_command_string); - } std::string remainder; const std::size_t actual_cmd_name_len = cmd_obj->GetCommandName().size(); @@ -2374,6 +2391,21 @@ void CommandInterpreter::SourceInitFileHome(CommandReturnObject &result, SourceInitFile(FileSpec(init_file.str()), result); } +void CommandInterpreter::SourceInitFileGlobal(CommandReturnObject &result) { +#ifdef LLDB_GLOBAL_INIT_DIRECTORY + if (!m_skip_lldbinit_files) { + FileSpec init_file(LLDB_GLOBAL_INIT_DIRECTORY); + if (init_file) + init_file.MakeAbsolute(HostInfo::GetShlibDir()); + + init_file.AppendPathComponent("lldbinit"); + SourceInitFile(init_file, result); + return; + } +#endif + result.SetStatus(eReturnStatusSuccessFinishNoResult); +} + const char *CommandInterpreter::GetCommandPrefix() { const char *prefix = GetDebugger().GetIOHandlerCommandPrefix(); return prefix == nullptr ? "" : prefix; @@ -2950,28 +2982,27 @@ bool CommandInterpreter::WasInterrupted() const { return was_interrupted; } -void CommandInterpreter::PrintCommandOutput(Stream &stream, - llvm::StringRef str) { +void CommandInterpreter::PrintCommandOutput(IOHandler &io_handler, + llvm::StringRef str, + bool is_stdout) { + + lldb::StreamFileSP stream = is_stdout ? io_handler.GetOutputStreamFileSP() + : io_handler.GetErrorStreamFileSP(); // Split the output into lines and poll for interrupt requests - const char *data = str.data(); - size_t size = str.size(); - while (size > 0 && !WasInterrupted()) { - size_t chunk_size = 0; - for (; chunk_size < size; ++chunk_size) { - lldbassert(data[chunk_size] != '\0'); - if (data[chunk_size] == '\n') { - ++chunk_size; - break; - } + while (!str.empty() && !WasInterrupted()) { + llvm::StringRef line; + std::tie(line, str) = str.split('\n'); + { + std::lock_guard<std::recursive_mutex> guard(io_handler.GetOutputMutex()); + stream->Write(line.data(), line.size()); + stream->Write("\n", 1); } - chunk_size = stream.Write(data, chunk_size); - lldbassert(size >= chunk_size); - data += chunk_size; - size -= chunk_size; - } - if (size > 0) { - stream.Printf("\n... Interrupted.\n"); } + + std::lock_guard<std::recursive_mutex> guard(io_handler.GetOutputMutex()); + if (!str.empty()) + stream->Printf("\n... Interrupted.\n"); + stream->Flush(); } bool CommandInterpreter::EchoCommandNonInteractive( @@ -3007,16 +3038,24 @@ void CommandInterpreter::IOHandlerInputComplete(IOHandler &io_handler, // When using a non-interactive file handle (like when sourcing commands // from a file) we need to echo the command out so we don't just see the // command output and no command... - if (EchoCommandNonInteractive(line, io_handler.GetFlags())) + if (EchoCommandNonInteractive(line, io_handler.GetFlags())) { + std::lock_guard<std::recursive_mutex> guard(io_handler.GetOutputMutex()); io_handler.GetOutputStreamFileSP()->Printf( "%s%s\n", io_handler.GetPrompt(), line.c_str()); + } } StartHandlingCommand(); - OverrideExecutionContext(m_debugger.GetSelectedExecutionContext()); - auto finalize = llvm::make_scope_exit([this]() { - RestoreExecutionContext(); + ExecutionContext exe_ctx = m_debugger.GetSelectedExecutionContext(); + bool pushed_exe_ctx = false; + if (exe_ctx.HasTargetScope()) { + OverrideExecutionContext(exe_ctx); + pushed_exe_ctx = true; + } + auto finalize = llvm::make_scope_exit([this, pushed_exe_ctx]() { + if (pushed_exe_ctx) + RestoreExecutionContext(); }); lldb_private::CommandReturnObject result(m_debugger.GetUseColor()); @@ -3031,13 +3070,13 @@ void CommandInterpreter::IOHandlerInputComplete(IOHandler &io_handler, if (!result.GetImmediateOutputStream()) { llvm::StringRef output = result.GetOutputData(); - PrintCommandOutput(*io_handler.GetOutputStreamFileSP(), output); + PrintCommandOutput(io_handler, output, true); } // Now emit the command error text from the command we just executed if (!result.GetImmediateErrorStream()) { llvm::StringRef error = result.GetErrorData(); - PrintCommandOutput(*io_handler.GetErrorStreamFileSP(), error); + PrintCommandOutput(io_handler, error, false); } } @@ -3122,8 +3161,8 @@ bool CommandInterpreter::SaveTranscript( } auto error_out = [&](llvm::StringRef error_message, std::string description) { - LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMANDS), "{0} ({1}:{2})", - error_message, output_file, description); + LLDB_LOG(GetLog(LLDBLog::Commands), "{0} ({1}:{2})", error_message, + output_file, description); result.AppendErrorWithFormatv( "Failed to save session's transcripts to {0}!", *output_file); return false; @@ -3156,6 +3195,10 @@ bool CommandInterpreter::SaveTranscript( return true; } +bool CommandInterpreter::IsInteractive() { + return (GetIOHandler() ? GetIOHandler()->GetIsInteractive() : false); +} + FileSpec CommandInterpreter::GetCurrentSourceDir() { if (m_command_source_dirs.empty()) return {}; diff --git a/contrib/llvm-project/lldb/source/Interpreter/CommandObject.cpp b/contrib/llvm-project/lldb/source/Interpreter/CommandObject.cpp index dcae27ff5479..c92fec53a55e 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/CommandObject.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/CommandObject.cpp @@ -132,7 +132,7 @@ bool CommandObject::ParseOptions(Args &args, CommandReturnObject &result) { } else { // No error string, output the usage information into result options->GenerateOptionUsage( - result.GetErrorStream(), this, + result.GetErrorStream(), *this, GetCommandInterpreter().GetDebugger().GetTerminalWidth()); } } @@ -326,7 +326,7 @@ bool CommandObject::HelpTextContainsWord(llvm::StringRef search_word, if (!found_word && search_options && GetOptions() != nullptr) { StreamString usage_help; GetOptions()->GenerateOptionUsage( - usage_help, this, + usage_help, *this, GetCommandInterpreter().GetDebugger().GetTerminalWidth()); if (!usage_help.Empty()) { llvm::StringRef usage_text = usage_help.GetString(); @@ -863,7 +863,7 @@ void CommandObject::GenerateHelpText(Stream &output_strm) { Options *options = GetOptions(); if (options != nullptr) { options->GenerateOptionUsage( - output_strm, this, + output_strm, *this, GetCommandInterpreter().GetDebugger().GetTerminalWidth()); } llvm::StringRef long_help = GetHelpLong(); @@ -995,6 +995,11 @@ bool CommandObjectParsed::Execute(const char *args_string, if (ParseOptions(cmd_args, result)) { // Call the command-specific version of 'Execute', passing it the // already processed arguments. + if (cmd_args.GetArgumentCount() != 0 && m_arguments.empty()) { + result.AppendErrorWithFormatv("'{0}' doesn't take any arguments.", + GetCommandName()); + return false; + } handled = DoExecute(cmd_args, result); } } @@ -1126,7 +1131,12 @@ CommandObject::ArgumentTableEntry CommandObject::g_arguments_data[] = { { eArgTypeCommand, "command", CommandCompletions::eNoCompletion, { nullptr, false }, "An LLDB Command line command element." }, { eArgTypeColumnNum, "column", CommandCompletions::eNoCompletion, { nullptr, false }, "Column number in a source file." }, { 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." } + { eArgTypeSaveCoreStyle, "corefile-style", CommandCompletions::eNoCompletion, { nullptr, false }, "The type of corefile that lldb will try to create, dependant on this target's capabilities." }, + { eArgTypeLogHandler, "log-handler", CommandCompletions::eNoCompletion, { nullptr, false }, "The log handle that will be used to write out log messages." }, + { eArgTypeSEDStylePair, "substitution-pair", CommandCompletions::eNoCompletion, { nullptr, false }, "A sed-style pattern and target pair." }, + { eArgTypeConnectURL, "process-connect-url", CommandCompletions::eNoCompletion, { nullptr, false }, "A URL-style specification for a remote connection." }, + { eArgTypeTargetID, "target-id", CommandCompletions::eNoCompletion, { nullptr, false }, "The index ID for an lldb Target." }, + { eArgTypeStopHookID, "stop-hook-id", CommandCompletions::eNoCompletion, { nullptr, false }, "The ID you receive when you create a stop-hook." } // clang-format on }; diff --git a/contrib/llvm-project/lldb/source/Interpreter/CommandReturnObject.cpp b/contrib/llvm-project/lldb/source/Interpreter/CommandReturnObject.cpp index 1b1e6996764c..4433c43ff6d4 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/CommandReturnObject.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/CommandReturnObject.cpp @@ -106,7 +106,13 @@ void CommandReturnObject::AppendError(llvm::StringRef in_string) { void CommandReturnObject::SetError(const Status &error, const char *fallback_error_cstr) { - AppendError(error.AsCString(fallback_error_cstr)); + if (error.Fail()) + AppendError(error.AsCString(fallback_error_cstr)); +} + +void CommandReturnObject::SetError(llvm::Error error) { + if (error) + AppendError(llvm::toString(std::move(error))); } // Similar to AppendError, but do not prepend 'Status: ' to message, and don't diff --git a/contrib/llvm-project/lldb/source/Interpreter/InterpreterProperties.td b/contrib/llvm-project/lldb/source/Interpreter/InterpreterProperties.td index 1c6f0206c489..c0acc044fb7f 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/InterpreterProperties.td +++ b/contrib/llvm-project/lldb/source/Interpreter/InterpreterProperties.td @@ -36,4 +36,8 @@ let Definition = "interpreter" in { 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.">; + def RequireCommandOverwrite: Property<"require-overwrite", "Boolean">, + Global, + DefaultTrue, + Desc<"If true, require --overwrite in 'command script add' before overwriting existing user commands.">; } diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupMemoryTag.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupMemoryTag.cpp new file mode 100644 index 000000000000..6752b6c8acf2 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupMemoryTag.cpp @@ -0,0 +1,60 @@ +//===-- OptionGroupMemoryTag.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/Interpreter/OptionGroupMemoryTag.h" + +#include "lldb/Host/OptionParser.h" + +using namespace lldb; +using namespace lldb_private; + +static const uint32_t SHORT_OPTION_SHOW_TAGS = 0x54414753; // 'tags' + +OptionGroupMemoryTag::OptionGroupMemoryTag(bool note_binary /*=false*/) + : m_show_tags(false, false), m_option_definition{ + LLDB_OPT_SET_1, + false, + "show-tags", + SHORT_OPTION_SHOW_TAGS, + OptionParser::eNoArgument, + nullptr, + {}, + 0, + eArgTypeNone, + note_binary + ? "Include memory tags in output " + "(does not apply to binary output)." + : "Include memory tags in output."} {} + +llvm::ArrayRef<OptionDefinition> OptionGroupMemoryTag::GetDefinitions() { + return llvm::makeArrayRef(m_option_definition); +} + +Status +OptionGroupMemoryTag::SetOptionValue(uint32_t option_idx, + llvm::StringRef option_arg, + ExecutionContext *execution_context) { + assert(option_idx == 0 && "Only one option in memory tag group!"); + + switch (m_option_definition.short_option) { + case SHORT_OPTION_SHOW_TAGS: + m_show_tags.SetCurrentValue(true); + m_show_tags.SetOptionWasSet(); + break; + + default: + llvm_unreachable("Unimplemented option"); + } + + return {}; +} + +void OptionGroupMemoryTag::OptionParsingStarting( + ExecutionContext *execution_context) { + m_show_tags.Clear(); +} diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupPlatform.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupPlatform.cpp index 4242e010fa64..acdf3f293496 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupPlatform.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupPlatform.cpp @@ -18,27 +18,34 @@ using namespace lldb_private; PlatformSP OptionGroupPlatform::CreatePlatformWithOptions( CommandInterpreter &interpreter, const ArchSpec &arch, bool make_selected, Status &error, ArchSpec &platform_arch) const { + PlatformList &platforms = interpreter.GetDebugger().GetPlatformList(); + PlatformSP platform_sp; if (!m_platform_name.empty()) { - platform_sp = Platform::Create(ConstString(m_platform_name.c_str()), error); + platform_sp = platforms.Create(m_platform_name); + if (!platform_sp) { + error.SetErrorStringWithFormatv( + "unable to find a plug-in for the platform named \"{0}\"", + m_platform_name); + } if (platform_sp) { - if (platform_arch.IsValid() && - !platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch)) { - error.SetErrorStringWithFormat("platform '%s' doesn't support '%s'", - platform_sp->GetName().GetCString(), - arch.GetTriple().getTriple().c_str()); + if (platform_arch.IsValid() && !platform_sp->IsCompatibleArchitecture( + arch, {}, false, &platform_arch)) { + error.SetErrorStringWithFormatv("platform '{0}' doesn't support '{1}'", + platform_sp->GetPluginName(), + arch.GetTriple().getTriple()); platform_sp.reset(); return platform_sp; } } } else if (arch.IsValid()) { - platform_sp = Platform::Create(arch, &platform_arch, error); + platform_sp = platforms.GetOrCreate(arch, {}, &platform_arch, error); } if (platform_sp) { - interpreter.GetDebugger().GetPlatformList().Append(platform_sp, - make_selected); + if (make_selected) + platforms.SetSelectedPlatform(platform_sp); if (!m_os_version.empty()) platform_sp->SetOSVersion(m_os_version); @@ -122,7 +129,7 @@ bool OptionGroupPlatform::PlatformMatches( const lldb::PlatformSP &platform_sp) const { if (platform_sp) { if (!m_platform_name.empty()) { - if (platform_sp->GetName() != ConstString(m_platform_name.c_str())) + if (platform_sp->GetName() != m_platform_name) return false; } diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp index 04861b539650..57b593020b14 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp @@ -104,6 +104,8 @@ Status OptionGroupValueObjectDisplay::SetOptionValue( max_depth = UINT32_MAX; error.SetErrorStringWithFormat("invalid max depth '%s'", option_arg.str().c_str()); + } else { + max_depth_is_default = false; } break; @@ -163,6 +165,7 @@ void OptionGroupValueObjectDisplay::OptionParsingStarting( flat_output = false; use_objc = false; max_depth = UINT32_MAX; + max_depth_is_default = true; ptr_depth = 0; elem_count = 0; use_synth = true; @@ -172,9 +175,12 @@ void OptionGroupValueObjectDisplay::OptionParsingStarting( TargetSP target_sp = execution_context ? execution_context->GetTargetSP() : TargetSP(); - if (target_sp) + if (target_sp) { use_dynamic = target_sp->GetPreferDynamicValue(); - else { + auto max_depth_config = target_sp->GetMaximumDepthOfChildrenToDisplay(); + max_depth = std::get<uint32_t>(max_depth_config); + max_depth_is_default = std::get<bool>(max_depth_config); + } else { // If we don't have any targets, then dynamic values won't do us much good. use_dynamic = lldb::eNoDynamicValues; } @@ -190,7 +196,7 @@ DumpValueObjectOptions OptionGroupValueObjectDisplay::GetAsDumpOptions( options.SetShowSummary(false); else options.SetOmitSummaryDepth(no_summary_depth); - options.SetMaximumDepth(max_depth) + options.SetMaximumDepth(max_depth, max_depth_is_default) .SetShowTypes(show_types) .SetShowLocation(show_location) .SetUseObjectiveC(use_objc) diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueDictionary.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueDictionary.cpp index 26fed4a987e1..6baafc9213e1 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueDictionary.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueDictionary.cpp @@ -8,11 +8,12 @@ #include "lldb/Interpreter/OptionValueDictionary.h" -#include "llvm/ADT/StringRef.h" #include "lldb/DataFormatters/FormatManager.h" +#include "lldb/Interpreter/OptionValueEnumeration.h" #include "lldb/Interpreter/OptionValueString.h" #include "lldb/Utility/Args.h" #include "lldb/Utility/State.h" +#include "llvm/ADT/StringRef.h" using namespace lldb; using namespace lldb_private; @@ -161,16 +162,26 @@ Status OptionValueDictionary::SetArgs(const Args &args, return error; } - lldb::OptionValueSP value_sp(CreateValueFromCStringForTypeMask( - value.str().c_str(), m_type_mask, error)); - if (value_sp) { + if (m_type_mask == 1u << eTypeEnum) { + auto enum_value = + std::make_shared<OptionValueEnumeration>(m_enum_values, 0); + error = enum_value->SetValueFromString(value); if (error.Fail()) return error; m_value_was_set = true; - SetValueForKey(ConstString(key), value_sp, true); + SetValueForKey(ConstString(key), enum_value, true); } else { - error.SetErrorString("dictionaries that can contain multiple types " - "must subclass OptionValueArray"); + lldb::OptionValueSP value_sp(CreateValueFromCStringForTypeMask( + value.str().c_str(), m_type_mask, error)); + if (value_sp) { + if (error.Fail()) + return error; + m_value_was_set = true; + SetValueForKey(ConstString(key), value_sp, true); + } else { + error.SetErrorString("dictionaries that can contain multiple types " + "must subclass OptionValueArray"); + } } } break; diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileColonLine.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileColonLine.cpp index fb0b516c8616..e500005a815d 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileColonLine.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileColonLine.cpp @@ -24,9 +24,8 @@ using namespace lldb_private; OptionValueFileColonLine::OptionValueFileColonLine() = default; OptionValueFileColonLine::OptionValueFileColonLine(llvm::StringRef input) - : m_line_number(LLDB_INVALID_LINE_NUMBER), - m_column_number(LLDB_INVALID_COLUMN_NUMBER), - m_completion_mask(CommandCompletions::eSourceFileCompletion) { + +{ SetValueFromString(input, eVarSetOperationAssign); } diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileSpec.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileSpec.cpp index 3987a36b1b65..f35a6b886f98 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileSpec.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileSpec.cpp @@ -22,14 +22,14 @@ OptionValueFileSpec::OptionValueFileSpec(bool resolve) : m_resolve(resolve) {} OptionValueFileSpec::OptionValueFileSpec(const FileSpec &value, bool resolve) : 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) : m_current_value(current_value), m_default_value(default_value), - m_completion_mask(CommandCompletions::eDiskFileCompletion), + m_resolve(resolve) {} void OptionValueFileSpec::DumpValue(const ExecutionContext *exe_ctx, diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueProperties.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueProperties.cpp index 6e6580574edf..b216557b808f 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueProperties.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueProperties.cpp @@ -412,6 +412,17 @@ OptionValueSInt64 *OptionValueProperties::GetPropertyAtIndexAsOptionValueSInt64( return nullptr; } +OptionValueUInt64 *OptionValueProperties::GetPropertyAtIndexAsOptionValueUInt64( + const ExecutionContext *exe_ctx, uint32_t idx) const { + const Property *property = GetPropertyAtIndex(exe_ctx, false, idx); + if (property) { + OptionValue *value = property->GetValue().get(); + if (value) + return value->GetAsUInt64(); + } + return nullptr; +} + int64_t OptionValueProperties::GetPropertyAtIndexAsSInt64( const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const { const Property *property = GetPropertyAtIndex(exe_ctx, false, idx); diff --git a/contrib/llvm-project/lldb/source/Interpreter/Options.cpp b/contrib/llvm-project/lldb/source/Interpreter/Options.cpp index feebe338bc9a..26d9d2a17867 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/Options.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/Options.cpp @@ -20,6 +20,7 @@ #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Target/Target.h" #include "lldb/Utility/StreamString.h" +#include "llvm/ADT/STLExtras.h" using namespace lldb; using namespace lldb_private; @@ -223,21 +224,25 @@ Option *Options::GetLongOptions() { option_seen.find(short_opt); StreamString strm; if (defs[i].HasShortOption()) - Host::SystemLog(Host::eSystemLogError, - "option[%u] --%s has a short option -%c that " - "conflicts with option[%u] --%s, short option won't " - "be used for --%s\n", - (int)i, defs[i].long_option, short_opt, pos->second, - m_getopt_table[pos->second].definition->long_option, - defs[i].long_option); + Debugger::ReportError( + llvm::formatv( + "option[{0}] --{1} has a short option -{2} that " + "conflicts with option[{3}] --{4}, short option won't " + "be used for --{5}", + i, defs[i].long_option, short_opt, pos->second, + m_getopt_table[pos->second].definition->long_option, + defs[i].long_option) + .str()); else - Host::SystemLog(Host::eSystemLogError, - "option[%u] --%s has a short option 0x%x that " - "conflicts with option[%u] --%s, short option won't " - "be used for --%s\n", - (int)i, defs[i].long_option, short_opt, pos->second, - m_getopt_table[pos->second].definition->long_option, - defs[i].long_option); + Debugger::ReportError( + llvm::formatv( + "option[{0}] --{1} has a short option {2:x} that " + "conflicts with option[{3}] --{4}, short option won't " + "be used for --{5}n", + (int)i, defs[i].long_option, short_opt, pos->second, + m_getopt_table[pos->second].definition->long_option, + defs[i].long_option) + .str()); } } @@ -387,26 +392,19 @@ static bool PrintOption(const OptionDefinition &opt_def, return true; } -void Options::GenerateOptionUsage(Stream &strm, CommandObject *cmd, +void Options::GenerateOptionUsage(Stream &strm, CommandObject &cmd, uint32_t screen_width) { - const bool only_print_args = cmd->IsDashDashCommand(); - auto opt_defs = GetDefinitions(); const uint32_t save_indent_level = strm.GetIndentLevel(); - llvm::StringRef name; - + llvm::StringRef name = cmd.GetCommandName(); StreamString arguments_str; - - if (cmd) { - name = cmd->GetCommandName(); - cmd->GetFormattedCommandArguments(arguments_str); - } else - name = ""; + cmd.GetFormattedCommandArguments(arguments_str); const uint32_t num_options = NumCommandOptions(); if (num_options == 0) return; + const bool only_print_args = cmd.IsDashDashCommand(); if (!only_print_args) strm.PutCString("\nCommand Options Usage:\n"); @@ -418,113 +416,73 @@ void Options::GenerateOptionUsage(Stream &strm, CommandObject *cmd, // [options-for-level-1] // etc. - uint32_t num_option_sets = GetRequiredOptions().size(); - - uint32_t i; - if (!only_print_args) { + uint32_t num_option_sets = GetRequiredOptions().size(); for (uint32_t opt_set = 0; opt_set < num_option_sets; ++opt_set) { - uint32_t opt_set_mask; - - opt_set_mask = 1 << opt_set; if (opt_set > 0) strm.Printf("\n"); strm.Indent(name); // Different option sets may require different args. StreamString args_str; - if (cmd) - cmd->GetFormattedCommandArguments(args_str, opt_set_mask); + uint32_t opt_set_mask = 1 << opt_set; + cmd.GetFormattedCommandArguments(args_str, opt_set_mask); // First go through and print all options that take no arguments as a // single string. If a command has "-a" "-b" and "-c", this will show up // as [-abc] - std::set<int> options; - std::set<int>::const_iterator options_pos, options_end; - for (auto &def : opt_defs) { - if (def.usage_mask & opt_set_mask && def.HasShortOption()) { - // Add current option to the end of out_stream. + // We use a set here so that they will be sorted. + std::set<int> required_options; + std::set<int> optional_options; - if (def.required && def.option_has_arg == OptionParser::eNoArgument) { - options.insert(def.short_option); + for (auto &def : opt_defs) { + if (def.usage_mask & opt_set_mask && def.HasShortOption() && + def.option_has_arg == OptionParser::eNoArgument) { + if (def.required) { + required_options.insert(def.short_option); + } else { + optional_options.insert(def.short_option); } } } - if (!options.empty()) { - // We have some required options with no arguments + if (!required_options.empty()) { strm.PutCString(" -"); - for (i = 0; i < 2; ++i) - for (options_pos = options.begin(), options_end = options.end(); - options_pos != options_end; ++options_pos) { - if (i == 0 && ::islower(*options_pos)) - continue; - if (i == 1 && ::isupper(*options_pos)) - continue; - strm << (char)*options_pos; - } - } - - options.clear(); - for (auto &def : opt_defs) { - if (def.usage_mask & opt_set_mask && def.HasShortOption()) { - // Add current option to the end of out_stream. - - if (!def.required && - def.option_has_arg == OptionParser::eNoArgument) { - options.insert(def.short_option); - } - } + for (int short_option : required_options) + strm.PutChar(short_option); } - if (!options.empty()) { - // We have some required options with no arguments + if (!optional_options.empty()) { strm.PutCString(" [-"); - for (i = 0; i < 2; ++i) - for (options_pos = options.begin(), options_end = options.end(); - options_pos != options_end; ++options_pos) { - if (i == 0 && ::islower(*options_pos)) - continue; - if (i == 1 && ::isupper(*options_pos)) - continue; - strm << (char)*options_pos; - } + for (int short_option : optional_options) + strm.PutChar(short_option); strm.PutChar(']'); } // First go through and print the required options (list them up front). - for (auto &def : opt_defs) { - if (def.usage_mask & opt_set_mask && def.HasShortOption()) { - if (def.required && def.option_has_arg != OptionParser::eNoArgument) - PrintOption(def, eDisplayBestOption, " ", nullptr, true, strm); - } + if (def.usage_mask & opt_set_mask && def.HasShortOption() && + def.required && def.option_has_arg != OptionParser::eNoArgument) + PrintOption(def, eDisplayBestOption, " ", nullptr, true, strm); } // Now go through again, and this time only print the optional options. - for (auto &def : opt_defs) { - if (def.usage_mask & opt_set_mask) { - // Add current option to the end of out_stream. - - if (!def.required && def.option_has_arg != OptionParser::eNoArgument) - PrintOption(def, eDisplayBestOption, " ", nullptr, true, strm); - } + if (def.usage_mask & opt_set_mask && !def.required && + def.option_has_arg != OptionParser::eNoArgument) + PrintOption(def, eDisplayBestOption, " ", nullptr, true, strm); } if (args_str.GetSize() > 0) { - if (cmd->WantsRawCommandString() && !only_print_args) + if (cmd.WantsRawCommandString()) strm.Printf(" --"); - strm << " " << args_str.GetString(); - if (only_print_args) - break; } } } - if (cmd && (only_print_args || cmd->WantsRawCommandString()) && + if ((only_print_args || cmd.WantsRawCommandString()) && arguments_str.GetSize() > 0) { if (!only_print_args) strm.PutChar('\n'); @@ -540,63 +498,49 @@ void Options::GenerateOptionUsage(Stream &strm, CommandObject *cmd, // -short <argument> ( --long_name <argument> ) // help text - // This variable is used to keep track of which options' info we've printed - // out, because some options can be in more than one usage level, but we - // only want to print the long form of its information once. - - std::multimap<int, uint32_t> options_seen; strm.IndentMore(5); - // Put the unique command options in a vector & sort it, so we can output - // them alphabetically (by short_option) when writing out detailed help for - // each option. - - i = 0; - for (auto &def : opt_defs) - options_seen.insert(std::make_pair(def.short_option, i++)); + // Put the command options in a sorted container, so we can output + // them alphabetically by short_option. + std::multimap<int, uint32_t> options_ordered; + for (auto def : llvm::enumerate(opt_defs)) + options_ordered.insert( + std::make_pair(def.value().short_option, def.index())); - // Go through the unique'd and alphabetically sorted vector of options, - // find the table entry for each option and write out the detailed help - // information for that option. + // Go through each option, find the table entry and write out the detailed + // help information for that option. bool first_option_printed = false; - for (auto pos : options_seen) { - i = pos.second; - // Print out the help information for this option. - + for (auto pos : options_ordered) { // Put a newline separation between arguments if (first_option_printed) strm.EOL(); else first_option_printed = true; - CommandArgumentType arg_type = opt_defs[i].argument_type; - - StreamString arg_name_str; - arg_name_str.Printf("<%s>", CommandObject::GetArgumentName(arg_type)); + OptionDefinition opt_def = opt_defs[pos.second]; strm.Indent(); - if (opt_defs[i].short_option && opt_defs[i].HasShortOption()) { - PrintOption(opt_defs[i], eDisplayShortOption, nullptr, nullptr, false, + if (opt_def.short_option && opt_def.HasShortOption()) { + PrintOption(opt_def, eDisplayShortOption, nullptr, nullptr, false, strm); - PrintOption(opt_defs[i], eDisplayLongOption, " ( ", " )", false, strm); + PrintOption(opt_def, eDisplayLongOption, " ( ", " )", false, strm); } else { // Short option is not printable, just print long option - PrintOption(opt_defs[i], eDisplayLongOption, nullptr, nullptr, false, - strm); + PrintOption(opt_def, eDisplayLongOption, nullptr, nullptr, false, strm); } strm.EOL(); strm.IndentMore(5); - if (opt_defs[i].usage_text) - OutputFormattedUsageText(strm, opt_defs[i], screen_width); - if (!opt_defs[i].enum_values.empty()) { + if (opt_def.usage_text) + OutputFormattedUsageText(strm, opt_def, screen_width); + if (!opt_def.enum_values.empty()) { strm.Indent(); strm.Printf("Values: "); bool is_first = true; - for (const auto &enum_value : opt_defs[i].enum_values) { + for (const auto &enum_value : opt_def.enum_values) { if (is_first) { strm.Printf("%s", enum_value.string_value); is_first = false; diff --git a/contrib/llvm-project/lldb/source/Interpreter/Property.cpp b/contrib/llvm-project/lldb/source/Interpreter/Property.cpp index fe3a8a31394b..681596224d31 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/Property.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/Property.cpp @@ -68,9 +68,10 @@ Property::Property(const PropertyDefinition &definition) } case OptionValue::eTypeDictionary: // "definition.default_uint_value" is always a OptionValue::Type - m_value_sp = - std::make_shared<OptionValueDictionary>(OptionValue::ConvertTypeToMask( - (OptionValue::Type)definition.default_uint_value)); + m_value_sp = std::make_shared<OptionValueDictionary>( + OptionValue::ConvertTypeToMask( + (OptionValue::Type)definition.default_uint_value), + definition.enum_values); break; case OptionValue::eTypeEnum: diff --git a/contrib/llvm-project/lldb/source/Interpreter/ScriptInterpreter.cpp b/contrib/llvm-project/lldb/source/Interpreter/ScriptInterpreter.cpp index fbdcbb8da868..bc8a542afc87 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/ScriptInterpreter.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/ScriptInterpreter.cpp @@ -109,13 +109,13 @@ ScriptInterpreter::StringToLanguage(const llvm::StringRef &language) { Status ScriptInterpreter::SetBreakpointCommandCallback( std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec, const char *callback_text) { - Status return_error; + Status error; for (BreakpointOptions &bp_options : bp_options_vec) { - return_error = SetBreakpointCommandCallback(bp_options, callback_text); - if (return_error.Success()) + error = SetBreakpointCommandCallback(bp_options, callback_text); + if (!error.Success()) break; } - return return_error; + return error; } Status ScriptInterpreter::SetBreakpointCommandCallbackFunction( diff --git a/contrib/llvm-project/lldb/source/Interpreter/embedded_interpreter.py b/contrib/llvm-project/lldb/source/Interpreter/embedded_interpreter.py index 9312dbfaca4e..fd2cc06bc286 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/embedded_interpreter.py +++ b/contrib/llvm-project/lldb/source/Interpreter/embedded_interpreter.py @@ -1,4 +1,4 @@ -import sys +import sys if sys.version_info[0] < 3: import __builtin__ as builtins else: @@ -23,36 +23,6 @@ else: else: readline.parse_and_bind('tab: complete') -g_builtin_override_called = False - - -class LLDBQuitter(object): - - def __init__(self, name): - self.name = name - - def __repr__(self): - self() - - def __call__(self, code=None): - global g_builtin_override_called - g_builtin_override_called = True - raise SystemExit(-1) - - -def setquit(): - '''Redefine builtin functions 'quit()' and 'exit()' to print a message and raise an EOFError exception.''' - # This function will be called prior to each interactive - # interpreter loop or each single line, so we set the global - # g_builtin_override_called to False so we know if a SystemExit - # is thrown, we can catch it and tell the difference between - # a call to "quit()" or "exit()" and something like - # "sys.exit(123)" - global g_builtin_override_called - g_builtin_override_called = False - builtins.quit = LLDBQuitter('quit') - builtins.exit = LLDBQuitter('exit') - # When running one line, we might place the string to run in this string # in case it would be hard to correctly escape a string's contents @@ -70,6 +40,22 @@ def get_terminal_size(fd): return hw +class LLDBExit(SystemExit): + pass + + +def strip_and_check_exit(line): + line = line.rstrip() + if line in ('exit', 'quit'): + raise LLDBExit + return line + + +def readfunc(prompt): + line = input(prompt) + return strip_and_check_exit(line) + + def readfunc_stdio(prompt): sys.stdout.write(prompt) sys.stdout.flush() @@ -78,12 +64,11 @@ def readfunc_stdio(prompt): # ends with an incomplete line. An empty line indicates EOF. if not line: raise EOFError - return line.rstrip() + return strip_and_check_exit(line) def run_python_interpreter(local_dict): # Pass in the dictionary, for continuity from one session to the next. - setquit() try: fd = sys.stdin.fileno() interacted = False @@ -116,24 +101,30 @@ def run_python_interpreter(local_dict): # We have a real interactive terminal code.interact( banner="Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.", + readfunc=readfunc, local=local_dict) + except LLDBExit: + pass except SystemExit as e: - global g_builtin_override_called - if not g_builtin_override_called: - print('Script exited with %s' % (e)) + if e.code: + print('Script exited with code %s' % e.code) def run_one_line(local_dict, input_string): global g_run_one_line_str - setquit() try: + input_string = strip_and_check_exit(input_string) repl = code.InteractiveConsole(local_dict) if input_string: + # A newline is appended to support one-line statements containing + # control flow. For example "if True: print(1)" silently does + # nothing, but works with a newline: "if True: print(1)\n". + input_string += "\n" repl.runsource(input_string) elif g_run_one_line_str: repl.runsource(g_run_one_line_str) - + except LLDBExit: + pass except SystemExit as e: - global g_builtin_override_called - if not g_builtin_override_called: - print('Script exited with %s' % (e)) + if e.code: + print('Script exited with code %s' % e.code) 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 2de9c346d387..6eba8afc8afd 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp @@ -86,8 +86,7 @@ static void addPartialRegisters( uint32_t partial_reg_size, lldb::Encoding encoding, lldb::Format format) { for (auto it : llvm::enumerate(full_reg_indices)) { llvm::Optional<uint32_t> full_reg_index = it.value(); - if (!full_reg_index || - regs[full_reg_index.getValue()].byte_size != full_reg_size) + if (!full_reg_index || regs[*full_reg_index].byte_size != full_reg_size) return; lldb_private::DynamicRegisterInfo::Register partial_reg{ @@ -103,7 +102,7 @@ static void addPartialRegisters( LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - {full_reg_index.getValue()}, + {*full_reg_index}, {}}; addSupplementaryRegister(regs, partial_reg); } 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 e771f69d7dbc..52e42f1260a8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h @@ -16,8 +16,8 @@ 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; + lldb::addr_t FixCodeAddress(lldb::addr_t pc) override; + lldb::addr_t FixDataAddress(lldb::addr_t pc) override; protected: virtual lldb::addr_t FixAddress(lldb::addr_t pc, lldb::addr_t mask) { 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 804532acf9f7..9dfc50564e64 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 @@ -23,6 +23,7 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Scalar.h" @@ -62,7 +63,7 @@ bool ABIMacOSX_arm64::PrepareTrivialCall( if (!reg_ctx) return false; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); if (log) { StreamString s; @@ -589,9 +590,10 @@ static bool LoadValueFromConsecutiveGPRRegisters( } else { const RegisterInfo *reg_info = nullptr; if (is_return_value) { - // We are assuming we are decoding this immediately after returning from - // a function call and that the address of the structure is in x8 - reg_info = reg_ctx->GetRegisterInfoByName("x8", 0); + // The Darwin arm64 ABI doesn't write the return location back to x8 + // before returning from the function the way the x86_64 ABI does. So + // we can't reconstruct stack based returns on exit from the function: + return false; } else { // We are assuming we are stopped at the first instruction in a function // and that the ABI is being respected so all parameters appear where 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 95924159e9f0..2896f5920db9 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 @@ -23,6 +23,7 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Scalar.h" @@ -65,7 +66,7 @@ bool ABISysV_arm64::PrepareTrivialCall(Thread &thread, addr_t sp, if (!reg_ctx) return false; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); if (log) { StreamString s; @@ -560,9 +561,12 @@ static bool LoadValueFromConsecutiveGPRRegisters( } else { const RegisterInfo *reg_info = nullptr; if (is_return_value) { - // We are assuming we are decoding this immediately after returning from - // a function call and that the address of the structure is in x8 - reg_info = reg_ctx->GetRegisterInfoByName("x8", 0); + // The SysV arm64 ABI doesn't require you to write the return location + // back to x8 before returning from the function the way the x86_64 ABI + // does. It looks like all the users of this ABI currently choose not to + // do that, and so we can't reconstruct stack based returns on exit + // from the function. + return false; } else { // We are assuming we are stopped at the first instruction in a function // and that the ABI is being respected so all parameters appear where @@ -790,14 +794,20 @@ lldb::addr_t ABISysV_arm64::FixAddress(addr_t pc, addr_t 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. + // 0 means there isn't a mask or it has not been read yet. + // We do not return the top byte mask unless thread_sp is valid. + // This prevents calls to this function before the thread is setup locking + // in the value to just the top byte mask, in cases where pointer + // authentication might also be active. + uint64_t address_mask = 0; lldb::ThreadSP thread_sp = process_sp->GetThreadList().GetSelectedThread(); if (thread_sp) { + // Linux configures user-space virtual addresses with top byte ignored. + // We set default value of mask such that top byte is masked out. + 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::RegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext(); if (reg_ctx_sp) { const RegisterInfo *reg_info = 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 3620be6f274d..a9c7af145338 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 @@ -154,7 +154,7 @@ bool ABISysV_arc::IsRegisterFileReduced(RegisterContext ®_ctx) const { m_is_reg_file_reduced = (reg_value | rf_entries_bit) != 0; } - return m_is_reg_file_reduced.getValueOr(false); + return m_is_reg_file_reduced.value_or(false); } //------------------------------------------------------------------ @@ -458,7 +458,7 @@ ABISysV_arc::GetReturnValueObjectSimple(Thread &thread, const uint32_t type_flags = compiler_type.GetTypeInfo(); // Integer return type. if (type_flags & eTypeIsInteger) { - const size_t byte_size = compiler_type.GetByteSize(&thread).getValueOr(0); + const size_t byte_size = compiler_type.GetByteSize(&thread).value_or(0); auto raw_value = ReadRawValue(reg_ctx, byte_size); const bool is_signed = (type_flags & eTypeIsSigned) != 0; @@ -482,7 +482,7 @@ ABISysV_arc::GetReturnValueObjectSimple(Thread &thread, if (compiler_type.IsFloatingPointType(float_count, is_complex) && 1 == float_count && !is_complex) { - const size_t byte_size = compiler_type.GetByteSize(&thread).getValueOr(0); + const size_t byte_size = compiler_type.GetByteSize(&thread).value_or(0); auto raw_value = ReadRawValue(reg_ctx, byte_size); if (!SetSizedFloat(value.GetScalar(), raw_value, byte_size)) 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 9ed042df4e50..ecc5f6ffd288 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 @@ -1668,7 +1668,7 @@ ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl( ProcessSP process_sp(thread.GetProcess()); ByteOrder byte_order = process_sp->GetByteOrder(); - DataBufferSP data_sp(new DataBufferHeap(*byte_size, 0)); + WritableDataBufferSP data_sp(new DataBufferHeap(*byte_size, 0)); uint32_t data_offset = 0; for (uint32_t reg_index = 0; reg_index < vfp_count; reg_index++) { 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 662689ca0615..9d8ef339432d 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 @@ -25,6 +25,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" @@ -529,7 +530,7 @@ ABISysV_mips::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { bool ABISysV_mips::PrepareTrivialCall(Thread &thread, addr_t sp, addr_t func_addr, addr_t return_addr, llvm::ArrayRef<addr_t> args) const { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); if (log) { StreamString s; @@ -872,7 +873,7 @@ ValueObjectSP ABISysV_mips::GetReturnValueObjectImpl( DataExtractor f1_data; reg_ctx->ReadRegister(f1_info, f1_value); DataExtractor *copy_from_extractor = nullptr; - DataBufferSP data_sp(new DataBufferHeap(8, 0)); + WritableDataBufferSP data_sp(new DataBufferHeap(8, 0)); DataExtractor return_ext( data_sp, target_byte_order, target->GetArchitecture().GetAddressByteSize()); 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 7e272265e15d..24571ead527f 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 @@ -25,6 +25,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" @@ -526,7 +527,7 @@ ABISysV_mips64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) bool ABISysV_mips64::PrepareTrivialCall(Thread &thread, addr_t sp, addr_t func_addr, addr_t return_addr, llvm::ArrayRef<addr_t> args) const { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); if (log) { StreamString s; @@ -826,7 +827,7 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl( DataExtractor f2_data; reg_ctx->ReadRegister(f2_info, f2_value); DataExtractor *copy_from_extractor = nullptr; - DataBufferSP data_sp(new DataBufferHeap(16, 0)); + WritableDataBufferSP data_sp(new DataBufferHeap(16, 0)); DataExtractor return_ext( data_sp, target_byte_order, target->GetArchitecture().GetAddressByteSize()); @@ -866,7 +867,7 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl( type_flags & eTypeIsVector) { // Any structure of up to 16 bytes in size is returned in the registers. if (*byte_size <= 16) { - DataBufferSP data_sp(new DataBufferHeap(16, 0)); + WritableDataBufferSP data_sp(new DataBufferHeap(16, 0)); DataExtractor return_ext(data_sp, target_byte_order, target->GetArchitecture().GetAddressByteSize()); 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 70b9c46d353f..1ef3b8ca3961 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 @@ -25,6 +25,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" @@ -228,7 +229,7 @@ ABISysV_ppc::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { bool ABISysV_ppc::PrepareTrivialCall(Thread &thread, addr_t sp, addr_t func_addr, addr_t return_addr, llvm::ArrayRef<addr_t> args) const { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); if (log) { StreamString s; @@ -665,7 +666,7 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectImpl( bool is_memory = true; if (*bit_width <= 128) { ByteOrder target_byte_order = target->GetArchitecture().GetByteOrder(); - DataBufferSP data_sp(new DataBufferHeap(16, 0)); + WritableDataBufferSP data_sp(new DataBufferHeap(16, 0)); DataExtractor return_ext(data_sp, target_byte_order, target->GetArchitecture().GetAddressByteSize()); 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 f9a2851d3949..e6f030891d1f 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 @@ -28,6 +28,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" @@ -80,7 +81,7 @@ ABISysV_ppc64::CreateInstance(lldb::ProcessSP process_sp, bool ABISysV_ppc64::PrepareTrivialCall(Thread &thread, addr_t sp, addr_t func_addr, addr_t return_addr, llvm::ArrayRef<addr_t> args) const { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); if (log) { StreamString s; @@ -478,8 +479,7 @@ class ReturnValueExtractor { Type m_type; RegisterContext *m_reg_ctx; ByteOrder m_byte_order; - Log *m_log = - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + Log *m_log = GetLog(LLDBLog::Expressions); }; Register GetGPR(uint32_t index) const { @@ -555,7 +555,7 @@ private: int32_t m_src_offs = 0; int32_t m_dst_offs = 0; bool m_packed = false; - Log *m_log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + Log *m_log = GetLog(LLDBLog::Expressions); RegisterContext *m_reg_ctx; ProcessSP m_process_sp; ByteOrder m_byte_order; @@ -567,7 +567,7 @@ private: ReturnValueExtractor(Thread &thread, CompilerType &type, RegisterContext *reg_ctx, ProcessSP process_sp) : m_thread(thread), m_type(type), - m_byte_size(m_type.GetByteSize(&thread).getValueOr(0)), + m_byte_size(m_type.GetByteSize(&thread).value_or(0)), m_data_up(new DataBufferHeap(m_byte_size, 0)), m_reg_ctx(reg_ctx), m_process_sp(process_sp), m_byte_order(process_sp->GetByteOrder()), m_addr_size( @@ -934,7 +934,7 @@ ABISysV_ppc64::GetReturnValueObjectSimple(Thread &thread, auto exp_extractor = ReturnValueExtractor::Create(thread, type); if (!exp_extractor) { - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + Log *log = GetLog(LLDBLog::Expressions); LLDB_LOG_ERROR(log, exp_extractor.takeError(), "Extracting return value failed: {0}"); return ValueObjectSP(); 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 f8156deb7e30..f66143152576 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 @@ -25,6 +25,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" @@ -195,7 +196,7 @@ ABISysV_s390x::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) bool ABISysV_s390x::PrepareTrivialCall(Thread &thread, addr_t sp, addr_t func_addr, addr_t return_addr, llvm::ArrayRef<addr_t> args) const { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); if (log) { StreamString s; 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 b51ee5c48515..031ccf5f54cc 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 @@ -26,6 +26,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" @@ -107,7 +108,7 @@ ABISysV_x86_64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) bool ABISysV_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp, addr_t func_addr, addr_t return_addr, llvm::ArrayRef<addr_t> args) const { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); if (log) { StreamString s; @@ -644,7 +645,7 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectImpl( 0, aggregate_field_offsets, aggregate_compiler_types)) { ByteOrder byte_order = target->GetArchitecture().GetByteOrder(); - DataBufferSP data_sp(new DataBufferHeap(16, 0)); + WritableDataBufferSP data_sp(new DataBufferHeap(16, 0)); DataExtractor return_ext(data_sp, byte_order, target->GetArchitecture().GetAddressByteSize()); 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 5e8f8b16ec1a..b91ba32a97cf 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 @@ -26,6 +26,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" @@ -123,7 +124,7 @@ ABIWindows_x86_64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &ar bool ABIWindows_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp, addr_t func_addr, addr_t return_addr, llvm::ArrayRef<addr_t> args) const { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); if (log) { StreamString s; @@ -641,7 +642,7 @@ ValueObjectSP ABIWindows_x86_64::GetReturnValueObjectImpl( 0, aggregate_field_offsets, aggregate_compiler_types)) { ByteOrder byte_order = target->GetArchitecture().GetByteOrder(); - DataBufferSP data_sp( + WritableDataBufferSP data_sp( new DataBufferHeap(max_register_value_bit_width / 8, 0)); DataExtractor return_ext(data_sp, byte_order, target->GetArchitecture().GetAddressByteSize()); diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIX86.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIX86.cpp index f717fe596946..b8cd364ef6ff 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIX86.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIX86.cpp @@ -72,7 +72,7 @@ addPartialRegisters(std::vector<DynamicRegisterInfo::Register> ®s, uint32_t subreg_size, uint32_t subreg_offset = 0) { for (const RegData *subreg : subregs) { assert(subreg); - uint32_t base_index = subreg->base_index.getValue(); + uint32_t base_index = *subreg->base_index; DynamicRegisterInfo::Register &full_reg = regs[base_index]; if (full_reg.byte_size != base_size) continue; 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 865c72fed61c..a9f2e7af601d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp @@ -16,6 +16,7 @@ #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" #include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" using namespace lldb_private; @@ -71,7 +72,7 @@ addr_t ArchitectureMips::GetOpcodeLoadAddress(addr_t opcode_addr, lldb::addr_t ArchitectureMips::GetBreakableLoadAddress(lldb::addr_t addr, Target &target) const { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); Address resolved_addr; 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 edc5f005c7ac..c85c66442510 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp @@ -10,6 +10,7 @@ #include "llvm-c/Disassembler.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" @@ -22,6 +23,7 @@ #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCTargetOptions.h" #include "llvm/MC/TargetRegistry.h" +#include "llvm/Support/AArch64TargetParser.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ScopedPrinter.h" #include "llvm/Support/TargetSelect.h" @@ -36,6 +38,7 @@ #include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Stream.h" @@ -89,8 +92,7 @@ public: AddressClass addr_class) : Instruction(address, addr_class), m_disasm_wp(std::static_pointer_cast<DisassemblerLLVMC>( - disasm.shared_from_this())), - m_using_file_addr(false) {} + disasm.shared_from_this())) {} ~InstructionLLVMC() override = default; @@ -795,8 +797,7 @@ public: } } - if (Log *log = - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)) { + if (Log *log = GetLog(LLDBLog::Process)) { StreamString ss; ss.Printf("[%s] expands to %zu operands:\n", operands_string, @@ -822,7 +823,7 @@ protected: std::weak_ptr<DisassemblerLLVMC> m_disasm_wp; bool m_is_valid = false; - bool m_using_file_addr; + bool m_using_file_addr = false; bool m_has_visited_instruction = false; // Be conservative. If we didn't understand the instruction, say it: @@ -1178,15 +1179,36 @@ DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch, features_str += "+dspr2,"; } - // If any AArch64 variant, enable latest ISA with any optional - // extensions like MTE. + // If any AArch64 variant, enable latest ISA with all extensions. if (triple.isAArch64()) { - features_str += "+v9.3a,+mte"; + features_str += "+v9.3a,"; + std::vector<llvm::StringRef> features; + // Get all possible features + llvm::AArch64::getExtensionFeatures(-1, features); + features_str += llvm::join(features, ","); if (triple.getVendor() == llvm::Triple::Apple) cpu = "apple-latest"; } + if (triple.isRISCV()) { + uint32_t arch_flags = arch.GetFlags(); + if (arch_flags & ArchSpec::eRISCV_rvc) + features_str += "+c,"; + if (arch_flags & ArchSpec::eRISCV_rve) + features_str += "+e,"; + if ((arch_flags & ArchSpec::eRISCV_float_abi_single) == + ArchSpec::eRISCV_float_abi_single) + features_str += "+f,"; + if ((arch_flags & ArchSpec::eRISCV_float_abi_double) == + ArchSpec::eRISCV_float_abi_double) + features_str += "+f,+d,"; + if ((arch_flags & ArchSpec::eRISCV_float_abi_quad) == + ArchSpec::eRISCV_float_abi_quad) + features_str += "+f,+d,+q,"; + // FIXME: how do we detect features such as `+a`, `+m`? + } + // We use m_disasm_up.get() to tell whether we are valid or not, so if this // isn't good for some reason, we won't be valid and FindPlugin will fail and // we won't get used. @@ -1360,7 +1382,7 @@ const char *DisassemblerLLVMC::SymbolLookup(uint64_t value, uint64_t *type_ptr, // the ADRP's register and this ADD's register are the same, // then this is a pc-relative address calculation. if (*type_ptr == LLVMDisassembler_ReferenceType_In_ARM64_ADDXri && - m_adrp_insn.hasValue() && m_adrp_address == pc - 4 && + m_adrp_insn && m_adrp_address == pc - 4 && (m_adrp_insn.getValue() & 0x1f) == ((value >> 5) & 0x1f)) { uint32_t addxri_inst; uint64_t adrp_imm, addxri_imm; diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp index 82c50a32594b..1834402bb2b1 100644 --- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp @@ -16,6 +16,7 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlanRunToAddress.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "DynamicLoaderHexagonDYLD.h" @@ -254,7 +255,7 @@ void DynamicLoaderHexagonDYLD::UnloadSections(const ModuleSP module) { // Place a breakpoint on <_rtld_debug_state> bool DynamicLoaderHexagonDYLD::SetRendezvousBreakpoint() { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); // This is the original code, which want to look in the rendezvous structure // to find the breakpoint address. Its backwards for us, since we can easily @@ -304,7 +305,7 @@ bool DynamicLoaderHexagonDYLD::SetRendezvousBreakpoint() { bool DynamicLoaderHexagonDYLD::RendezvousBreakpointHit( void *baton, StoppointCallbackContext *context, user_id_t break_id, user_id_t break_loc_id) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); LLDB_LOGF(log, "Rendezvous breakpoint hit!"); @@ -337,7 +338,7 @@ bool DynamicLoaderHexagonDYLD::RendezvousBreakpointHit( /// Helper method for RendezvousBreakpointHit. Updates LLDB's current set /// of loaded modules. void DynamicLoaderHexagonDYLD::RefreshModules() { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); if (!m_rendezvous.Resolve()) return; @@ -457,7 +458,7 @@ void DynamicLoaderHexagonDYLD::LoadAllCurrentModules() { ModuleList module_list; if (!m_rendezvous.Resolve()) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); LLDB_LOGF( log, "DynamicLoaderHexagonDYLD::%s unable to resolve rendezvous address", @@ -478,7 +479,7 @@ void DynamicLoaderHexagonDYLD::LoadAllCurrentModules() { if (module_sp.get()) { module_list.Append(module_sp); } else { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); LLDB_LOGF(log, "DynamicLoaderHexagonDYLD::%s failed loading module %s at " "0x%" PRIx64, @@ -589,7 +590,7 @@ DynamicLoaderHexagonDYLD::GetThreadLocalData(const lldb::ModuleSP module, addr_t tls_block = ReadPointer(dtv_slot + metadata.tls_offset); Module *mod = module.get(); - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); LLDB_LOGF(log, "DynamicLoaderHexagonDYLD::Performed TLS lookup: " "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64 diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp index 7e80dc28e56b..4869cf0fd9c8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp @@ -14,6 +14,7 @@ #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Status.h" @@ -34,7 +35,7 @@ DYLDRendezvous::DYLDRendezvous(Process *process) } addr_t DYLDRendezvous::ResolveRendezvousAddress() { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); addr_t info_location; addr_t info_addr; Status error; @@ -113,7 +114,7 @@ addr_t DYLDRendezvous::ResolveRendezvousAddress() { void DYLDRendezvous::UpdateExecutablePath() { if (m_process) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); Module *exe_mod = m_process->GetTarget().GetExecutableModulePointer(); if (exe_mod) { m_exe_file_spec = exe_mod->GetPlatformFileSpec(); @@ -129,7 +130,7 @@ void DYLDRendezvous::UpdateExecutablePath() { } bool DYLDRendezvous::Resolve() { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); const size_t word_size = 4; Rendezvous info; @@ -209,14 +210,7 @@ DYLDRendezvous::RendezvousAction DYLDRendezvous::GetAction() const { case eAdd: case eDelete: - // Some versions of the android dynamic linker might send two - // notifications with state == eAdd back to back. Ignore them until we - // get an eConsistent notification. - if (!(m_previous.state == eConsistent || - (m_previous.state == eAdd && m_current.state == eDelete))) - return eNoAction; - - return eTakeSnapshot; + return eNoAction; } return eNoAction; @@ -228,9 +222,9 @@ bool DYLDRendezvous::UpdateSOEntriesFromRemote() { if (action == eNoAction) return false; + m_added_soentries.clear(); + m_removed_soentries.clear(); if (action == eTakeSnapshot) { - m_added_soentries.clear(); - m_removed_soentries.clear(); // We already have the loaded list from the previous update so no need to // find all the modules again. if (!m_loaded_modules.m_list.empty()) @@ -259,11 +253,11 @@ bool DYLDRendezvous::UpdateSOEntriesFromRemote() { } bool DYLDRendezvous::UpdateSOEntries() { + m_added_soentries.clear(); + m_removed_soentries.clear(); switch (GetAction()) { case eTakeSnapshot: m_soentries.clear(); - m_added_soentries.clear(); - m_removed_soentries.clear(); return TakeSnapshot(m_soentries); case eAddModules: return AddSOEntries(); diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp index 188b6da7a712..8a708c1f9898 100644 --- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp @@ -21,6 +21,7 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlanRunToAddress.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/ProcessInfo.h" @@ -76,7 +77,7 @@ DynamicLoaderPOSIXDYLD::~DynamicLoaderPOSIXDYLD() { } void DynamicLoaderPOSIXDYLD::DidAttach() { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64, __FUNCTION__, m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID); m_auxv = std::make_unique<AuxVector>(m_process->GetAuxvData()); @@ -85,10 +86,6 @@ void DynamicLoaderPOSIXDYLD::DidAttach() { log, "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " reloaded auxv data", __FUNCTION__, m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID); - // ask the process if it can load any of its own modules - auto error = m_process->LoadModules(); - LLDB_LOG_ERROR(log, std::move(error), "Couldn't load modules: {0}"); - ModuleSP executable_sp = GetTargetExecutable(); ResolveExecutableModule(executable_sp); m_rendezvous.UpdateExecutablePath(); @@ -166,7 +163,7 @@ void DynamicLoaderPOSIXDYLD::DidAttach() { } void DynamicLoaderPOSIXDYLD::DidLaunch() { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s()", __FUNCTION__); ModuleSP executable; @@ -214,7 +211,7 @@ void DynamicLoaderPOSIXDYLD::UnloadSections(const ModuleSP module) { } void DynamicLoaderPOSIXDYLD::ProbeEntry() { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); const addr_t entry = GetEntryPoint(); if (entry == LLDB_INVALID_ADDRESS) { @@ -257,7 +254,7 @@ bool DynamicLoaderPOSIXDYLD::EntryBreakpointHit( if (!baton) return false; - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); DynamicLoaderPOSIXDYLD *const dyld_instance = static_cast<DynamicLoaderPOSIXDYLD *>(baton); LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64, @@ -299,7 +296,7 @@ bool DynamicLoaderPOSIXDYLD::EntryBreakpointHit( } bool DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint() { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); if (m_dyld_bid != LLDB_INVALID_BREAK_ID) { LLDB_LOG(log, "Rendezvous breakpoint breakpoint id {0} for pid {1}" @@ -312,7 +309,7 @@ bool DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint() { addr_t break_addr; Target &target = m_process->GetTarget(); BreakpointSP dyld_break; - if (m_rendezvous.IsValid()) { + if (m_rendezvous.IsValid() && m_rendezvous.GetBreakAddress() != 0) { break_addr = m_rendezvous.GetBreakAddress(); LLDB_LOG(log, "Setting rendezvous break address for pid {0} at {1:x}", m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID, @@ -387,7 +384,7 @@ bool DynamicLoaderPOSIXDYLD::RendezvousBreakpointHit( if (!baton) return false; - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); DynamicLoaderPOSIXDYLD *const dyld_instance = static_cast<DynamicLoaderPOSIXDYLD *>(baton); LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64, @@ -436,27 +433,31 @@ void DynamicLoaderPOSIXDYLD::RefreshModules() { for (; I != E; ++I) { ModuleSP module_sp = LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true); - if (module_sp.get()) { - if (module_sp->GetObjectFile()->GetBaseAddress().GetLoadAddress( - &m_process->GetTarget()) == m_interpreter_base && - module_sp != m_interpreter_module.lock()) { - if (m_interpreter_module.lock() == nullptr) { - m_interpreter_module = module_sp; - } else { - // If this is a duplicate instance of ld.so, unload it. We may end - // up with it if we load it via a different path than before - // (symlink vs real path). - // TODO: remove this once we either fix library matching or avoid - // loading the interpreter when setting the rendezvous breakpoint. - UnloadSections(module_sp); - loaded_modules.Remove(module_sp); - continue; - } + if (!module_sp.get()) + continue; + + if (module_sp->GetObjectFile()->GetBaseAddress().GetLoadAddress( + &m_process->GetTarget()) == m_interpreter_base) { + ModuleSP interpreter_sp = m_interpreter_module.lock(); + if (m_interpreter_module.lock() == nullptr) { + m_interpreter_module = module_sp; + } else if (module_sp == interpreter_sp) { + // Module already loaded. + continue; + } else { + // If this is a duplicate instance of ld.so, unload it. We may end + // up with it if we load it via a different path than before + // (symlink vs real path). + // TODO: remove this once we either fix library matching or avoid + // loading the interpreter when setting the rendezvous breakpoint. + UnloadSections(module_sp); + loaded_modules.Remove(module_sp); + continue; } - - loaded_modules.AppendIfNeeded(module_sp); - new_modules.Append(module_sp); } + + loaded_modules.AppendIfNeeded(module_sp); + new_modules.Append(module_sp); } m_process->GetTarget().ModulesDidLoad(new_modules); } @@ -491,7 +492,7 @@ DynamicLoaderPOSIXDYLD::GetStepThroughTrampolinePlan(Thread &thread, if (sym == nullptr || !sym->IsTrampoline()) return thread_plan_sp; - ConstString sym_name = sym->GetName(); + ConstString sym_name = sym->GetMangled().GetName(Mangled::ePreferMangled); if (!sym_name) return thread_plan_sp; @@ -539,7 +540,7 @@ void DynamicLoaderPOSIXDYLD::LoadVDSO() { MemoryRegionInfo info; Status status = m_process->GetMemoryRegionInfo(m_vdso_base, info); if (status.Fail()) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); LLDB_LOG(log, "Failed to get vdso region info: {0}", status); return; } @@ -560,7 +561,7 @@ ModuleSP DynamicLoaderPOSIXDYLD::LoadInterpreterModule() { Status status = m_process->GetMemoryRegionInfo(m_interpreter_base, info); if (status.Fail() || info.GetMapped() != MemoryRegionInfo::eYes || info.GetName().IsEmpty()) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); LLDB_LOG(log, "Failed to get interpreter region info: {0}", status); return nullptr; } @@ -568,7 +569,7 @@ ModuleSP DynamicLoaderPOSIXDYLD::LoadInterpreterModule() { FileSpec file(info.GetName().GetCString()); ModuleSpec module_spec(file, target.GetArchitecture()); - if (ModuleSP module_sp = target.GetOrCreateModule(module_spec, + if (ModuleSP module_sp = target.GetOrCreateModule(module_spec, true /* notify */)) { UpdateLoadedSections(module_sp, LLDB_INVALID_ADDRESS, m_interpreter_base, false); @@ -578,11 +579,43 @@ ModuleSP DynamicLoaderPOSIXDYLD::LoadInterpreterModule() { return nullptr; } +ModuleSP DynamicLoaderPOSIXDYLD::LoadModuleAtAddress(const FileSpec &file, + addr_t link_map_addr, + addr_t base_addr, + bool base_addr_is_offset) { + if (ModuleSP module_sp = DynamicLoader::LoadModuleAtAddress( + file, link_map_addr, base_addr, base_addr_is_offset)) + return module_sp; + + // This works around an dynamic linker "bug" on android <= 23, where the + // dynamic linker would report the application name + // (e.g. com.example.myapplication) instead of the main process binary + // (/system/bin/app_process(32)). The logic is not sound in general (it + // assumes base_addr is the real address, even though it actually is a load + // bias), but it happens to work on adroid because app_process has a file + // address of zero. + // This should be removed after we drop support for android-23. + if (m_process->GetTarget().GetArchitecture().GetTriple().isAndroid()) { + MemoryRegionInfo memory_info; + Status error = m_process->GetMemoryRegionInfo(base_addr, memory_info); + if (error.Success() && memory_info.GetMapped() && + memory_info.GetRange().GetRangeBase() == base_addr && + !(memory_info.GetName().IsEmpty())) { + if (ModuleSP module_sp = DynamicLoader::LoadModuleAtAddress( + FileSpec(memory_info.GetName().GetStringRef()), link_map_addr, + base_addr, base_addr_is_offset)) + return module_sp; + } + } + + return nullptr; +} + void DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() { DYLDRendezvous::iterator I; DYLDRendezvous::iterator E; ModuleList module_list; - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); LoadVDSO(); @@ -613,7 +646,7 @@ void DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() { I->file_spec.GetFilename()); module_list.Append(module_sp); } else { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); LLDB_LOGF( log, "DynamicLoaderPOSIXDYLD::%s failed loading module %s at 0x%" PRIx64, @@ -722,7 +755,7 @@ DynamicLoaderPOSIXDYLD::GetThreadLocalData(const lldb::ModuleSP module_sp, addr_t dtv_slot = dtv + metadata.dtv_slot_size * modid; addr_t tls_block = ReadPointer(dtv_slot + metadata.tls_offset); - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::Performed TLS lookup: " "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64 @@ -738,7 +771,7 @@ DynamicLoaderPOSIXDYLD::GetThreadLocalData(const lldb::ModuleSP module_sp, void DynamicLoaderPOSIXDYLD::ResolveExecutableModule( lldb::ModuleSP &module_sp) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); if (m_process == nullptr) return; diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h index 422856e7a660..8d3e4cde54c7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h +++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h @@ -55,6 +55,11 @@ public: // PluginInterface protocol llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } + lldb::ModuleSP LoadModuleAtAddress(const lldb_private::FileSpec &file, + lldb::addr_t link_map_addr, + lldb::addr_t base_addr, + bool base_addr_is_offset) override; + protected: /// Runtime linker rendezvous structure. DYLDRendezvous m_rendezvous; 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 bf6dc57003d5..fa6356963fca 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 @@ -16,6 +16,7 @@ #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Target.h" #include "lldb/Target/ThreadPlanStepInstruction.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "llvm/ADT/Triple.h" @@ -117,37 +118,37 @@ lldb::addr_t DynamicLoaderWindowsDYLD::GetLoadAddress(ModuleSP executable) { } void DynamicLoaderWindowsDYLD::DidAttach() { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); - LLDB_LOGF(log, "DynamicLoaderWindowsDYLD::%s()", __FUNCTION__); + Log *log = GetLog(LLDBLog::DynamicLoader); + LLDB_LOGF(log, "DynamicLoaderWindowsDYLD::%s()", __FUNCTION__); - ModuleSP executable = GetTargetExecutable(); + ModuleSP executable = GetTargetExecutable(); - if (!executable.get()) - return; + if (!executable.get()) + return; - // Try to fetch the load address of the file from the process, since there - // could be randomization of the load address. - lldb::addr_t load_addr = GetLoadAddress(executable); - if (load_addr == LLDB_INVALID_ADDRESS) - return; + // Try to fetch the load address of the file from the process, since there + // could be randomization of the load address. + lldb::addr_t load_addr = GetLoadAddress(executable); + if (load_addr == LLDB_INVALID_ADDRESS) + return; - // Request the process base address. - lldb::addr_t image_base = m_process->GetImageInfoAddress(); - if (image_base == load_addr) - return; + // Request the process base address. + lldb::addr_t image_base = m_process->GetImageInfoAddress(); + if (image_base == load_addr) + return; - // Rebase the process's modules if there is a mismatch. - UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_addr, false); + // Rebase the process's modules if there is a mismatch. + UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_addr, false); - ModuleList module_list; - module_list.Append(executable); - m_process->GetTarget().ModulesDidLoad(module_list); - auto error = m_process->LoadModules(); - LLDB_LOG_ERROR(log, std::move(error), "failed to load modules: {0}"); + ModuleList module_list; + module_list.Append(executable); + m_process->GetTarget().ModulesDidLoad(module_list); + auto error = m_process->LoadModules(); + LLDB_LOG_ERROR(log, std::move(error), "failed to load modules: {0}"); } void DynamicLoaderWindowsDYLD::DidLaunch() { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); LLDB_LOGF(log, "DynamicLoaderWindowsDYLD::%s()", __FUNCTION__); ModuleSP executable = GetTargetExecutable(); diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp index 1634372bb905..d019415cb67a 100644 --- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp @@ -14,6 +14,7 @@ #include "lldb/Core/Section.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" using namespace lldb; @@ -51,7 +52,7 @@ DynamicLoader *DynamicLoaderWasmDYLD::CreateInstance(Process *process, } void DynamicLoaderWasmDYLD::DidAttach() { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); LLDB_LOGF(log, "DynamicLoaderWasmDYLD::%s()", __FUNCTION__); // Ask the process for the list of loaded WebAssembly modules. @@ -63,3 +64,19 @@ ThreadPlanSP DynamicLoaderWasmDYLD::GetStepThroughTrampolinePlan(Thread &thread, bool stop) { return ThreadPlanSP(); } + +lldb::ModuleSP DynamicLoaderWasmDYLD::LoadModuleAtAddress( + const lldb_private::FileSpec &file, lldb::addr_t link_map_addr, + lldb::addr_t base_addr, bool base_addr_is_offset) { + if (ModuleSP module_sp = DynamicLoader::LoadModuleAtAddress( + file, link_map_addr, base_addr, base_addr_is_offset)) + return module_sp; + + if (ModuleSP module_sp = m_process->ReadModuleFromMemory(file, base_addr)) { + UpdateLoadedSections(module_sp, link_map_addr, base_addr, false); + m_process->GetTarget().GetImages().AppendIfNeeded(module_sp); + return module_sp; + } + + return nullptr; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.h b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.h index fe67e5885904..5ed855395cca 100644 --- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.h +++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.h @@ -33,6 +33,11 @@ public: Status CanLoadImage() override { return Status(); } lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread, bool stop) override; + lldb::ModuleSP LoadModuleAtAddress(const lldb_private::FileSpec &file, + lldb::addr_t link_map_addr, + lldb::addr_t base_addr, + bool base_addr_is_offset) override; + /// \} /// PluginInterface protocol. 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 7844f27139cf..7a1ac7870547 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp @@ -14,6 +14,7 @@ #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Target/Target.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" @@ -53,7 +54,7 @@ void ASTResultSynthesizer::Initialize(ASTContext &Context) { } void ASTResultSynthesizer::TransformTopLevelDecl(Decl *D) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); if (NamedDecl *named_decl = dyn_cast<NamedDecl>(D)) { if (log && log->GetVerbose()) { @@ -112,7 +113,7 @@ bool ASTResultSynthesizer::HandleTopLevelDecl(DeclGroupRef D) { } bool ASTResultSynthesizer::SynthesizeFunctionResult(FunctionDecl *FunDecl) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); if (!m_sema) return false; @@ -154,7 +155,7 @@ bool ASTResultSynthesizer::SynthesizeFunctionResult(FunctionDecl *FunDecl) { bool ASTResultSynthesizer::SynthesizeObjCMethodResult( ObjCMethodDecl *MethodDecl) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); if (!m_sema) return false; @@ -198,7 +199,7 @@ bool ASTResultSynthesizer::SynthesizeObjCMethodResult( bool ASTResultSynthesizer::SynthesizeBodyResult(CompoundStmt *Body, DeclContext *DC) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); ASTContext &Ctx(*m_ast_context); @@ -407,7 +408,7 @@ void ASTResultSynthesizer::MaybeRecordPersistentType(TypeDecl *D) { if (name.size() == 0 || name[0] != '$') return; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); ConstString name_cs(name.str().c_str()); @@ -427,7 +428,7 @@ void ASTResultSynthesizer::RecordPersistentDecl(NamedDecl *D) { if (name.size() == 0) return; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); ConstString name_cs(name.str().c_str()); @@ -455,7 +456,7 @@ void ASTResultSynthesizer::CommitPersistentDecls() { &scratch_ctx->getASTContext(), decl); if (!D_scratch) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); if (log) { std::string s; 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 6ed3cc9384f0..9ef3c3671abf 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp @@ -8,6 +8,7 @@ #include "lldb/Core/Module.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" @@ -49,8 +50,7 @@ CompilerType ClangASTImporter::CopyType(TypeSystemClang &dst_ast, llvm::Expected<QualType> ret_or_error = delegate_sp->Import(src_qual_type); if (!ret_or_error) { - Log *log = - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + Log *log = GetLog(LLDBLog::Expressions); LLDB_LOG_ERROR(log, ret_or_error.takeError(), "Couldn't import type: {0}"); return CompilerType(); @@ -77,7 +77,7 @@ clang::Decl *ClangASTImporter::CopyDecl(clang::ASTContext *dst_ast, llvm::Expected<clang::Decl *> result = delegate_sp->Import(decl); if (!result) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); LLDB_LOG_ERROR(log, result.takeError(), "Couldn't import decl: {0}"); if (log) { lldb::user_id_t user_id = LLDB_INVALID_UID; @@ -170,7 +170,7 @@ private: void Override(clang::Decl *decl) { if (clang::Decl *escaped_child = GetEscapedChild(decl)) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); LLDB_LOG(log, " [ClangASTImporter] DeclContextOverride couldn't " @@ -240,7 +240,7 @@ public: m_delegate->SetImportListener(this); } - virtual ~CompleteTagDeclsScope() { + ~CompleteTagDeclsScope() override { ClangASTImporter::ASTContextMetadataSP to_context_md = importer.GetContextMetadata(m_dst_ctx); @@ -303,7 +303,7 @@ public: CompilerType ClangASTImporter::DeportType(TypeSystemClang &dst, const CompilerType &src_type) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); TypeSystemClang *src_ctxt = llvm::cast<TypeSystemClang>(src_type.GetTypeSystem()); @@ -326,7 +326,7 @@ CompilerType ClangASTImporter::DeportType(TypeSystemClang &dst, clang::Decl *ClangASTImporter::DeportDecl(clang::ASTContext *dst_ctx, clang::Decl *decl) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); clang::ASTContext *src_ctx = &decl->getASTContext(); LLDB_LOG(log, @@ -615,7 +615,7 @@ bool ClangASTImporter::CompleteAndFetchChildren(clang::QualType type) { if (!RequireCompleteType(type)) return false; - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + Log *log = GetLog(LLDBLog::Expressions); if (const TagType *tag_type = type->getAs<TagType>()) { TagDecl *tag_decl = tag_type->getDecl(); @@ -779,7 +779,7 @@ void ClangASTImporter::BuildNamespaceMap(const clang::NamespaceDecl *decl) { } void ClangASTImporter::ForgetDestination(clang::ASTContext *dst_ast) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); LLDB_LOG(log, " [ClangASTImporter] Forgetting destination (ASTContext*){0}", @@ -792,7 +792,7 @@ void ClangASTImporter::ForgetSource(clang::ASTContext *dst_ast, clang::ASTContext *src_ast) { ASTContextMetadataSP md = MaybeGetContextMetadata(dst_ast); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); LLDB_LOG(log, " [ClangASTImporter] Forgetting source->dest " @@ -806,7 +806,7 @@ void ClangASTImporter::ForgetSource(clang::ASTContext *dst_ast, md->removeOriginsWithContext(src_ast); } -ClangASTImporter::MapCompleter::~MapCompleter() {} +ClangASTImporter::MapCompleter::~MapCompleter() = default; llvm::Expected<Decl *> ClangASTImporter::ASTImporterDelegate::ImportImpl(Decl *From) { @@ -865,7 +865,7 @@ ClangASTImporter::ASTImporterDelegate::ImportImpl(Decl *From) { const ClangASTMetadata *md = m_main.GetDeclMetadata(From); auto *td = dyn_cast<TagDecl>(From); if (td && md && md->IsForcefullyCompleted()) { - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + Log *log = GetLog(LLDBLog::Expressions); LLDB_LOG(log, "[ClangASTImporter] Searching for a complete definition of {0} in " "other modules", @@ -903,7 +903,7 @@ void ClangASTImporter::ASTImporterDelegate::ImportDefinitionTo( MapImported(from, to); ASTImporter::Imported(from, to); - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + Log *log = GetLog(LLDBLog::Expressions); if (llvm::Error err = ImportDefinition(from)) { LLDB_LOG_ERROR(log, std::move(err), @@ -915,8 +915,7 @@ void ClangASTImporter::ASTImporterDelegate::ImportDefinitionTo( if (clang::TagDecl *from_tag = dyn_cast<clang::TagDecl>(from)) { to_tag->setCompleteDefinition(from_tag->isCompleteDefinition()); - if (Log *log_ast = - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST)) { + if (Log *log_ast = GetLog(LLDBLog::AST)) { std::string name_string; if (NamedDecl *from_named_decl = dyn_cast<clang::NamedDecl>(from)) { llvm::raw_string_ostream name_stream(name_string); @@ -1023,7 +1022,7 @@ RemapModule(OptionalClangModuleID from_id, void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from, clang::Decl *to) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); // Some decls shouldn't be tracked here because they were not created by // copying 'from' to 'to'. Just exit early for those. 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 510352e8c173..1bf29efb0bee 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp @@ -18,6 +18,7 @@ #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/TaggedASTType.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "clang/AST/ASTContext.h" #include "clang/AST/RecordLayout.h" @@ -183,7 +184,7 @@ bool ClangASTSource::FindExternalVisibleDeclsByName( } TagDecl *ClangASTSource::FindCompleteType(const TagDecl *decl) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(decl->getDeclContext())) { @@ -278,7 +279,7 @@ TagDecl *ClangASTSource::FindCompleteType(const TagDecl *decl) { } void ClangASTSource::CompleteType(TagDecl *tag_decl) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); if (log) { LLDB_LOG(log, @@ -307,7 +308,7 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) { } void ClangASTSource::CompleteType(clang::ObjCInterfaceDecl *interface_decl) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); LLDB_LOG(log, " [CompleteObjCInterfaceDecl] on (ASTContext*){0} '{1}' " @@ -387,7 +388,7 @@ void ClangASTSource::FindExternalLexicalDecls( llvm::function_ref<bool(Decl::Kind)> predicate, llvm::SmallVectorImpl<Decl *> &decls) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); const Decl *context_decl = dyn_cast<Decl>(decl_context); @@ -520,7 +521,7 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) { const ConstString name(context.m_decl_name.getAsString().c_str()); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); if (log) { if (!context.m_decl_context) @@ -597,7 +598,7 @@ void ClangASTSource::FindExternalVisibleDecls( CompilerDeclContext &namespace_decl) { assert(m_ast_context); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); SymbolContextList sc_list; @@ -668,7 +669,7 @@ void ClangASTSource::FillNamespaceMap( if (IgnoreName(name, true)) return; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); if (module_sp && namespace_decl) { CompilerDeclContext found_namespace_decl; @@ -833,7 +834,7 @@ bool ClangASTSource::FindObjCMethodDeclsWithOrigin( if (!copied_method_decl) continue; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); LLDB_LOG(log, " CAS::FOMD found ({0}) {1}", log_info, ClangUtil::DumpDecl(copied_method_decl)); @@ -846,7 +847,7 @@ bool ClangASTSource::FindObjCMethodDeclsWithOrigin( void ClangASTSource::FindDeclInModules(NameSearchContext &context, ConstString name) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); std::shared_ptr<ClangModulesDeclVendor> modules_decl_vendor = GetClangModulesDeclVendor(); @@ -886,7 +887,7 @@ void ClangASTSource::FindDeclInModules(NameSearchContext &context, void ClangASTSource::FindDeclInObjCRuntime(NameSearchContext &context, ConstString name) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); lldb::ProcessSP process(m_target->GetProcessSP()); @@ -928,7 +929,7 @@ void ClangASTSource::FindDeclInObjCRuntime(NameSearchContext &context, } void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); const DeclarationName &decl_name(context.m_decl_name); const DeclContext *decl_ctx(context.m_decl_context); @@ -1208,7 +1209,7 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { static bool FindObjCPropertyAndIvarDeclsWithOrigin( NameSearchContext &context, ClangASTSource &source, DeclFromUser<const ObjCInterfaceDecl> &origin_iface_decl) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); if (origin_iface_decl.IsInvalid()) return false; @@ -1255,7 +1256,7 @@ static bool FindObjCPropertyAndIvarDeclsWithOrigin( } void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); DeclFromParser<const ObjCInterfaceDecl> parser_iface_decl( cast<ObjCInterfaceDecl>(context.m_decl_context)); @@ -1391,7 +1392,7 @@ void ClangASTSource::LookupInNamespace(NameSearchContext &context) { const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(context.m_decl_context); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer_sp->GetNamespaceMap(namespace_context); @@ -1498,7 +1499,7 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, BaseOffsetMap &base_offsets, BaseOffsetMap &virtual_base_offsets) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); LLDB_LOG(log, "LayoutRecordType on (ASTContext*){0} '{1}' for (RecordDecl*)" @@ -1620,7 +1621,7 @@ void ClangASTSource::CompleteNamespaceMap( ClangASTImporter::NamespaceMapSP &namespace_map, ConstString name, ClangASTImporter::NamespaceMapSP &parent_map) const { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); if (log) { if (parent_map && parent_map->size()) 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 6313117c08d6..a9b2d4110ab2 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() = default; + ~ClangDeclVendor() override = 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 4af5d41a5921..cc45871bcd71 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp @@ -40,6 +40,7 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" @@ -252,7 +253,7 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl, return true; } - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx; Target *target = exe_ctx.GetTargetPtr(); if (target == nullptr) @@ -328,7 +329,7 @@ bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl, bool is_persistent_variable = false; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); m_struct_vars->m_struct_laid_out = false; @@ -646,7 +647,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( const ConstString name(context.m_decl_name.getAsString().c_str()); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); if (log) { if (!context.m_decl_context) @@ -728,7 +729,7 @@ clang::NamedDecl *ClangExpressionDeclMap::GetPersistentDecl(ConstString name) { void ClangExpressionDeclMap::SearchPersistenDecls(NameSearchContext &context, const ConstString name) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); NamedDecl *persistent_decl = GetPersistentDecl(name); @@ -756,7 +757,7 @@ void ClangExpressionDeclMap::SearchPersistenDecls(NameSearchContext &context, } void ClangExpressionDeclMap::LookUpLldbClass(NameSearchContext &context) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr(); SymbolContext sym_ctx; @@ -805,7 +806,7 @@ void ClangExpressionDeclMap::LookUpLldbClass(NameSearchContext &context) { TypeFromUser class_user_type(class_qual_type.getAsOpaquePtr(), function_decl_ctx.GetTypeSystem()); - LLDB_LOG(log, " CEDM::FEVD Adding type for $__lldb_class: {1}", + LLDB_LOG(log, " CEDM::FEVD Adding type for $__lldb_class: {0}", class_qual_type.getAsString()); AddContextClassType(context, class_user_type); @@ -847,7 +848,7 @@ void ClangExpressionDeclMap::LookUpLldbClass(NameSearchContext &context) { TypeFromUser pointee_type = this_type->GetForwardCompilerType().GetPointeeType(); - LLDB_LOG(log, " FEVD Adding type for $__lldb_class: {1}", + LLDB_LOG(log, " FEVD Adding type for $__lldb_class: {0}", ClangUtil::GetQualType(pointee_type).getAsString()); AddContextClassType(context, pointee_type); @@ -857,7 +858,7 @@ void ClangExpressionDeclMap::LookUpLldbClass(NameSearchContext &context) { } void ClangExpressionDeclMap::LookUpLldbObjCClass(NameSearchContext &context) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr(); @@ -1014,7 +1015,7 @@ void ClangExpressionDeclMap::LookupLocalVarNamespace( void ClangExpressionDeclMap::LookupInModulesDeclVendor( NameSearchContext &context, ConstString name) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); if (!m_target) return; @@ -1036,7 +1037,7 @@ void ClangExpressionDeclMap::LookupInModulesDeclVendor( LLDB_LOG(log, " CAS::FEVD Matching decl found for " - "\"{1}\" in the modules", + "\"{0}\" in the modules", name); clang::Decl *copied_decl = CopyDecl(decl_from_modules); @@ -1331,7 +1332,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( const CompilerDeclContext &namespace_decl) { assert(m_ast_context); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); const ConstString name(context.m_decl_name.getAsString().c_str()); if (IgnoreName(name, false)) @@ -1460,7 +1461,7 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var, lldb_private::Value &var_location, TypeFromUser *user_type, TypeFromParser *parser_type) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); Type *var_type = var->GetType(); @@ -1546,7 +1547,7 @@ void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, ValueObjectSP valobj) { assert(m_parser_vars.get()); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); TypeFromUser ut; TypeFromParser pt; @@ -1594,13 +1595,13 @@ void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, if (is_reference) entity->m_flags |= ClangExpressionVariable::EVTypeIsReference; - LLDB_LOG(log, " CEDM::FEVD Found variable {1}, returned\n{2} (original {3})", + LLDB_LOG(log, " CEDM::FEVD Found variable {0}, returned\n{1} (original {2})", decl_name, ClangUtil::DumpDecl(var_decl), ClangUtil::ToString(ut)); } void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, ExpressionVariableSP &pvar_sp) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); TypeFromUser user_type( llvm::cast<ClangExpressionVariable>(pvar_sp.get())->GetTypeFromUser()); @@ -1625,7 +1626,7 @@ void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, parser_vars->m_llvm_value = nullptr; parser_vars->m_lldb_value.Clear(); - LLDB_LOG(log, " CEDM::FEVD Added pvar {1}, returned\n{2}", + LLDB_LOG(log, " CEDM::FEVD Added pvar {0}, returned\n{1}", pvar_sp->GetName(), ClangUtil::DumpDecl(var_decl)); } @@ -1633,7 +1634,7 @@ void ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context, const Symbol &symbol) { assert(m_parser_vars.get()); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr(); @@ -1677,13 +1678,13 @@ void ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context, parser_vars->m_llvm_value = nullptr; parser_vars->m_lldb_sym = &symbol; - LLDB_LOG(log, " CEDM::FEVD Found variable {1}, returned\n{2}", decl_name, + LLDB_LOG(log, " CEDM::FEVD Found variable {0}, returned\n{1}", decl_name, ClangUtil::DumpDecl(var_decl)); } void ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context, const RegisterInfo *reg_info) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); CompilerType clang_type = m_clang_ast_context->GetBuiltinTypeForEncodingAndBitSize( @@ -1716,7 +1717,7 @@ void ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context, parser_vars->m_lldb_value.Clear(); entity->m_flags |= ClangExpressionVariable::EVBareRegister; - LLDB_LOG(log, " CEDM::FEVD Added register {1}, returned\n{2}", + LLDB_LOG(log, " CEDM::FEVD Added register {0}, returned\n{1}", context.m_decl_name.getAsString(), ClangUtil::DumpDecl(var_decl)); } @@ -1725,7 +1726,7 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, Symbol *symbol) { assert(m_parser_vars.get()); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); NamedDecl *function_decl = nullptr; Address fun_address; @@ -1766,7 +1767,7 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, LLDB_LOG(log, " CEDM::FEVD Imported decl for function template" - " {1} (description {2}), returned\n{3}", + " {0} (description {1}), returned\n{2}", copied_function_template->getNameAsString(), ss.GetData(), ClangUtil::DumpDecl(copied_function_template)); @@ -1784,8 +1785,8 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, function->DumpSymbolContext(&ss); LLDB_LOG(log, - " CEDM::FEVD Imported decl for function {1} " - "(description {2}), returned\n{3}", + " CEDM::FEVD Imported decl for function {0} " + "(description {1}), returned\n{2}", copied_function_decl->getNameAsString(), ss.GetData(), ClangUtil::DumpDecl(copied_function_decl)); } @@ -1884,8 +1885,8 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, Address::DumpStyleResolvedDescription); LLDB_LOG(log, - " CEDM::FEVD Found {1} function {2} (description {3}), " - "returned\n{4}", + " CEDM::FEVD Found {0} function {1} (description {2}), " + "returned\n{3}", (function ? "specific" : "generic"), decl_name, ss.GetData(), ClangUtil::DumpDecl(function_decl)); } @@ -1895,7 +1896,7 @@ void ClangExpressionDeclMap::AddContextClassType(NameSearchContext &context, const TypeFromUser &ut) { CompilerType copied_clang_type = GuardedCopyType(ut); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); if (!copied_clang_type) { LLDB_LOG(log, @@ -1961,7 +1962,7 @@ void ClangExpressionDeclMap::AddOneType(NameSearchContext &context, CompilerType copied_clang_type = GuardedCopyType(ut); if (!copied_clang_type) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); LLDB_LOG(log, "ClangExpressionDeclMap::AddOneType - Couldn't import the type"); 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 51f34369c383..fad0f724e4c8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp @@ -84,6 +84,7 @@ #include "lldb/Target/ThreadPlanCallFunction.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/ReproducerProvider.h" #include "lldb/Utility/Stream.h" @@ -189,7 +190,7 @@ public: // when we move the expression result ot the ScratchASTContext). Let's at // least log these diagnostics until we find a way to properly render // them and display them to the user. - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); if (log) { llvm::SmallVector<char, 32> diag_str; Info.FormatDiagnostic(diag_str); @@ -282,7 +283,7 @@ private: static void SetupModuleHeaderPaths(CompilerInstance *compiler, std::vector<std::string> include_directories, lldb::TargetSP target_sp) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); HeaderSearchOptions &search_opts = compiler->getHeaderSearchOpts(); @@ -364,7 +365,7 @@ ClangExpressionParser::ClangExpressionParser( m_pp_callbacks(nullptr), m_include_directories(std::move(include_directories)), m_filename(std::move(filename)) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); // We can't compile expressions without a target. So if the exe_scope is // null or doesn't have a target, then we just need to get out of here. I'll @@ -1325,7 +1326,7 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution( bool &can_interpret, ExecutionPolicy execution_policy) { func_addr = LLDB_INVALID_ADDRESS; func_end = LLDB_INVALID_ADDRESS; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); lldb_private::Status err; 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 977a461e3f6f..5168f637c443 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp @@ -88,8 +88,7 @@ class AddMacroState { public: AddMacroState(const FileSpec ¤t_file, const uint32_t current_file_line) - : m_state(CURRENT_FILE_NOT_YET_PUSHED), m_current_file(current_file), - m_current_file_line(current_file_line) {} + : m_current_file(current_file), m_current_file_line(current_file_line) {} void StartFile(const FileSpec &file) { m_file_stack.push_back(file); @@ -127,7 +126,7 @@ public: private: std::vector<FileSpec> m_file_stack; - State m_state; + State m_state = CURRENT_FILE_NOT_YET_PUSHED; FileSpec m_current_file; uint32_t m_current_file_line; }; 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 2cfa9a4c9ccf..f1449c02c9dc 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp @@ -37,6 +37,7 @@ #include "lldb/Target/ThreadPlan.h" #include "lldb/Target/ThreadPlanCallFunction.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/State.h" @@ -180,7 +181,7 @@ ClangFunctionCaller::CompileFunction(lldb::ThreadSP thread_to_use_sp, m_wrapper_function_text.append(args_list_buffer); m_wrapper_function_text.append(");\n}\n"); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); LLDB_LOGF(log, "Expression: \n\n%s\n\n", m_wrapper_function_text.c_str()); // Okay, now compile this expression diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp index b76fa6fbf690..2099cfaaefec 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp @@ -20,6 +20,7 @@ #include "lldb/Host/FileSystem.h" #include "lldb/Host/HostInfo.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include <string> @@ -29,7 +30,7 @@ using namespace lldb_private; static bool VerifyClangPath(const llvm::Twine &clang_path) { if (FileSystem::Instance().IsDirectory(clang_path)) return true; - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + Log *log = GetLog(LLDBLog::Host); LLDB_LOGF(log, "VerifyClangPath(): " "failed to stat clang resource directory at \"%s\"", @@ -47,7 +48,7 @@ static bool VerifyClangPath(const llvm::Twine &clang_path) { static bool DefaultComputeClangResourceDirectory(FileSpec &lldb_shlib_spec, FileSpec &file_spec, bool verify) { - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + Log *log = GetLog(LLDBLog::Host); std::string raw_path = lldb_shlib_spec.GetPath(); llvm::StringRef parent_dir = llvm::sys::path::parent_path(raw_path); @@ -157,7 +158,7 @@ FileSpec lldb_private::GetClangResourceDir() { if (FileSpec lldb_file_spec = HostInfo::GetShlibDir()) ComputeClangResourceDirectory(lldb_file_spec, g_cached_resource_dir, true); - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + Log *log = GetLog(LLDBLog::Host); LLDB_LOGF(log, "GetClangResourceDir() => '%s'", g_cached_resource_dir.GetPath().c_str()); }); 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 336058a5abb9..38dd55bc76d3 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp @@ -32,6 +32,7 @@ #include "lldb/Target/Target.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/ReproducerProvider.h" #include "lldb/Utility/StreamString.h" @@ -130,7 +131,7 @@ private: } // anonymous namespace StoringDiagnosticConsumer::StoringDiagnosticConsumer() { - m_log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + m_log = GetLog(LLDBLog::Expressions); clang::DiagnosticOptions *m_options = new clang::DiagnosticOptions(); m_os = std::make_shared<llvm::raw_string_ostream>(m_output); @@ -517,8 +518,9 @@ void ClangModulesDeclVendorImpl::ForEachMacro( bool first_token = true; - for (clang::MacroInfo::tokens_iterator ti = macro_info->tokens_begin(), - te = macro_info->tokens_end(); + for (clang::MacroInfo::const_tokens_iterator + ti = macro_info->tokens_begin(), + te = macro_info->tokens_end(); ti != te; ++ti) { if (!first_token) macro_expansion.append(" "); @@ -656,14 +658,16 @@ ClangModulesDeclVendor::Create(Target &target) { for (const std::string &arg : compiler_invocation_arguments) compiler_invocation_argument_cstrs.push_back(arg.c_str()); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); LLDB_LOG(log, "ClangModulesDeclVendor's compiler flags {0:$[ ]}", llvm::make_range(compiler_invocation_arguments.begin(), compiler_invocation_arguments.end())); + clang::CreateInvocationOptions CIOpts; + CIOpts.Diags = diagnostics_engine; std::shared_ptr<clang::CompilerInvocation> invocation = - clang::createInvocationFromCommandLine(compiler_invocation_argument_cstrs, - diagnostics_engine); + clang::createInvocation(compiler_invocation_argument_cstrs, + std::move(CIOpts)); if (!invocation) return nullptr; @@ -724,8 +728,8 @@ ClangModulesDeclVendor::Create(Target &target) { parser->Initialize(); clang::Parser::DeclGroupPtrTy parsed; - - while (!parser->ParseTopLevelDecl(parsed)) + auto ImportState = clang::Sema::ModuleImportState::NotACXX20Module; + while (!parser->ParseTopLevelDecl(parsed, ImportState)) ; return new ClangModulesDeclVendorImpl(std::move(diagnostics_engine), 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 1437d7b58293..78b8bf11220a 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp @@ -49,6 +49,7 @@ #include "lldb/Target/ThreadPlan.h" #include "lldb/Target/ThreadPlanCallUserExpression.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" @@ -89,7 +90,7 @@ ClangUserExpression::ClangUserExpression( ClangUserExpression::~ClangUserExpression() = default; void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); LLDB_LOGF(log, "ClangUserExpression::ScanContext()"); @@ -456,14 +457,14 @@ static bool SupportsCxxModuleImport(lldb::LanguageType language) { /// Utility method that puts a message into the expression log and /// returns an invalid module configuration. static CppModuleConfiguration LogConfigError(const std::string &msg) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); LLDB_LOG(log, "[C++ module config] {0}", msg); return CppModuleConfiguration(); } CppModuleConfiguration GetModuleConfig(lldb::LanguageType language, ExecutionContext &exe_ctx) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); // Don't do anything if this is not a C++ module configuration. if (!SupportsCxxModuleImport(language)) @@ -621,7 +622,7 @@ bool ClangUserExpression::TryParse( } void ClangUserExpression::SetupCppModuleImports(ExecutionContext &exe_ctx) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); CppModuleConfiguration module_config = GetModuleConfig(m_language, exe_ctx); m_imported_cpp_modules = module_config.GetImportedModules(); @@ -647,7 +648,7 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, lldb_private::ExecutionPolicy execution_policy, bool keep_result_in_memory, bool generate_debug_info) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); if (!PrepareForParsing(diagnostic_manager, exe_ctx, /*for_completion*/ false)) return false; @@ -806,7 +807,7 @@ static void AbsPosToLineColumnPos(size_t abs_pos, llvm::StringRef code, bool ClangUserExpression::Complete(ExecutionContext &exe_ctx, CompletionRequest &request, unsigned complete_pos) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); // We don't want any visible feedback when completing an expression. Mostly // because the results we get from an incomplete invocation are probably not @@ -857,7 +858,7 @@ bool ClangUserExpression::Complete(ExecutionContext &exe_ctx, // The line and column of the user expression inside the transformed source // code. unsigned user_expr_line, user_expr_column; - if (m_user_expression_start_pos.hasValue()) + if (m_user_expression_start_pos) AbsPosToLineColumnPos(*m_user_expression_start_pos, m_transformed_text, user_expr_line, user_expr_column); else 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 fecffd1183f8..9453cdc3a451 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp @@ -9,6 +9,7 @@ #include "Plugins/ExpressionParser/Clang/CxxModuleHandler.h" #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "clang/Sema/Lookup.h" #include "llvm/Support/Error.h" @@ -180,7 +181,7 @@ T *createDecl(ASTImporter &importer, Decl *from_d, Args &&... args) { } llvm::Optional<Decl *> CxxModuleHandler::tryInstantiateStdTemplate(Decl *d) { - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + Log *log = GetLog(LLDBLog::Expressions); // If we don't have a template to instiantiate, then there is nothing to do. auto td = dyn_cast<ClassTemplateSpecializationDecl>(d); diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp index 8b132b54b7e6..0a4af196857c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp @@ -22,6 +22,7 @@ #include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" @@ -136,8 +137,7 @@ public: /// The module being instrumented. Instrumenter(llvm::Module &module, std::shared_ptr<UtilityFunction> checker_function) - : m_module(module), m_checker_function(checker_function), - m_i8ptr_ty(nullptr), m_intptr_ty(nullptr) {} + : m_module(module), m_checker_function(checker_function) {} virtual ~Instrumenter() = default; @@ -301,8 +301,8 @@ protected: m_checker_function; ///< The dynamic checker function for the process private: - PointerType *m_i8ptr_ty; - IntegerType *m_intptr_ty; + PointerType *m_i8ptr_ty = nullptr; + IntegerType *m_intptr_ty = nullptr; }; class ValidPointerChecker : public Instrumenter { @@ -316,7 +316,7 @@ public: protected: bool InstrumentInstruction(llvm::Instruction *inst) override { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); LLDB_LOGF(log, "Instrumenting load/store instruction: %s\n", PrintValue(inst).c_str()); @@ -467,7 +467,7 @@ protected: } bool InspectInstruction(llvm::Instruction &i) override { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); CallInst *call_inst = dyn_cast<CallInst>(&i); @@ -538,7 +538,7 @@ IRDynamicChecks::IRDynamicChecks( IRDynamicChecks::~IRDynamicChecks() = default; bool IRDynamicChecks::runOnModule(llvm::Module &M) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); llvm::Function *function = M.getFunction(StringRef(m_func_name)); diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.h index a4de527e4512..4abd16c5c326 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.h +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.h @@ -30,7 +30,7 @@ public: ClangDynamicCheckerFunctions(); /// Destructor - virtual ~ClangDynamicCheckerFunctions(); + ~ClangDynamicCheckerFunctions() override; static bool classof(const DynamicCheckerFunctions *checker_funcs) { return checker_funcs->GetKind() == DCF_Clang; 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 e0e41925f7ef..047aa1e7c084 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp @@ -34,6 +34,7 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Scalar.h" #include "lldb/Utility/StreamString.h" @@ -41,6 +42,7 @@ #include <map> using namespace llvm; +using lldb_private::LLDBLog; typedef SmallVector<Instruction *, 2> InstrList; @@ -158,8 +160,7 @@ static bool isGuardVariableSymbol(llvm::StringRef mangled_symbol, } bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) { - lldb_private::Log *log( - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + lldb_private::Log *log(GetLog(LLDBLog::Expressions)); if (!m_resolve_vars) return true; @@ -322,14 +323,13 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) { LLDB_LOG(log, "Creating a new result global: \"{0}\" with size {1}", m_result_name, - m_result_type.GetByteSize(target_sp.get()).getValueOr(0)); + m_result_type.GetByteSize(target_sp.get()).value_or(0)); // Construct a new result global and set up its metadata GlobalVariable *new_result_global = new GlobalVariable( - (*m_module), result_global->getType()->getElementType(), - false, /* not constant */ - GlobalValue::ExternalLinkage, nullptr, /* no initializer */ + (*m_module), result_global->getValueType(), false, /* not constant */ + GlobalValue::ExternalLinkage, nullptr, /* no initializer */ m_result_name.GetCString()); // It's too late in compilation to create a new VarDecl for this, but we @@ -399,8 +399,7 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) { bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str, llvm::GlobalVariable *cstr) { - lldb_private::Log *log( - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + lldb_private::Log *log(GetLog(LLDBLog::Expressions)); Type *ns_str_ty = ns_str->getType(); @@ -537,8 +536,7 @@ bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str, } bool IRForTarget::RewriteObjCConstStrings() { - lldb_private::Log *log( - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + lldb_private::Log *log(GetLog(LLDBLog::Expressions)); ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable(); @@ -617,29 +615,7 @@ bool IRForTarget::RewriteObjCConstStrings() { return false; } - ConstantExpr *nsstring_expr = dyn_cast<ConstantExpr>(nsstring_member); - - if (!nsstring_expr) { - LLDB_LOG(log, - "NSString initializer's str element is not a ConstantExpr"); - - m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C " - "constant string's string initializer is not " - "constant\n"); - - return false; - } - - GlobalVariable *cstr_global = nullptr; - - if (nsstring_expr->getOpcode() == Instruction::GetElementPtr) { - Constant *nsstring_cstr = nsstring_expr->getOperand(0); - cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr); - } else if (nsstring_expr->getOpcode() == Instruction::BitCast) { - Constant *nsstring_cstr = nsstring_expr->getOperand(0); - cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr); - } - + auto *cstr_global = dyn_cast<GlobalVariable>(nsstring_member); if (!cstr_global) { LLDB_LOG(log, "NSString initializer's str element is not a GlobalVariable"); @@ -750,8 +726,7 @@ static bool IsObjCSelectorRef(Value *value) { // This function does not report errors; its callers are responsible. bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) { - lldb_private::Log *log( - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + lldb_private::Log *log(GetLog(LLDBLog::Expressions)); LoadInst *load = dyn_cast<LoadInst>(selector_load); @@ -761,17 +736,16 @@ bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) { // Unpack the message name from the selector. In LLVM IR, an objc_msgSend // gets represented as // - // %tmp = load i8** @"OBJC_SELECTOR_REFERENCES_" ; <i8*> %call = call - // i8* (i8*, i8*, ...)* @objc_msgSend(i8* %obj, i8* %tmp, ...) ; <i8*> + // %sel = load ptr, ptr @OBJC_SELECTOR_REFERENCES_, align 8 + // call i8 @objc_msgSend(ptr %obj, ptr %sel, ...) // - // where %obj is the object pointer and %tmp is the selector. + // where %obj is the object pointer and %sel is the selector. // // @"OBJC_SELECTOR_REFERENCES_" is a pointer to a character array called // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_". // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_" contains the string. - // Find the pointer's initializer (a ConstantExpr with opcode GetElementPtr) - // and get the string from its target + // Find the pointer's initializer and get the string from its target. GlobalVariable *_objc_selector_references_ = dyn_cast<GlobalVariable>(load->getPointerOperand()); @@ -781,22 +755,13 @@ bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) { return false; Constant *osr_initializer = _objc_selector_references_->getInitializer(); - - ConstantExpr *osr_initializer_expr = dyn_cast<ConstantExpr>(osr_initializer); - - if (!osr_initializer_expr || - osr_initializer_expr->getOpcode() != Instruction::GetElementPtr) - return false; - - Value *osr_initializer_base = osr_initializer_expr->getOperand(0); - - if (!osr_initializer_base) + if (!osr_initializer) return false; // Find the string's initializer (a ConstantArray) and get the string from it GlobalVariable *_objc_meth_var_name_ = - dyn_cast<GlobalVariable>(osr_initializer_base); + dyn_cast<GlobalVariable>(osr_initializer); if (!_objc_meth_var_name_ || !_objc_meth_var_name_->hasInitializer()) return false; @@ -877,8 +842,7 @@ bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) { } bool IRForTarget::RewriteObjCSelectors(BasicBlock &basic_block) { - lldb_private::Log *log( - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + lldb_private::Log *log(GetLog(LLDBLog::Expressions)); InstrList selector_loads; @@ -912,8 +876,7 @@ static bool IsObjCClassReference(Value *value) { // This function does not report errors; its callers are responsible. bool IRForTarget::RewriteObjCClassReference(Instruction *class_load) { - lldb_private::Log *log( - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + lldb_private::Log *log(GetLog(LLDBLog::Expressions)); LoadInst *load = dyn_cast<LoadInst>(class_load); @@ -1029,8 +992,7 @@ bool IRForTarget::RewriteObjCClassReference(Instruction *class_load) { } bool IRForTarget::RewriteObjCClassReferences(BasicBlock &basic_block) { - lldb_private::Log *log( - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + lldb_private::Log *log(GetLog(LLDBLog::Expressions)); InstrList class_loads; @@ -1057,8 +1019,7 @@ bool IRForTarget::RewriteObjCClassReferences(BasicBlock &basic_block) { // This function does not report errors; its callers are responsible. bool IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc) { - lldb_private::Log *log( - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + lldb_private::Log *log(GetLog(LLDBLog::Expressions)); AllocaInst *alloc = dyn_cast<AllocaInst>(persistent_alloc); @@ -1112,9 +1073,8 @@ bool IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc) { // Now, since the variable is a pointer variable, we will drop in a load of // that pointer variable. - LoadInst *persistent_load = - new LoadInst(persistent_global->getType()->getPointerElementType(), - persistent_global, "", alloc); + LoadInst *persistent_load = new LoadInst(persistent_global->getValueType(), + persistent_global, "", alloc); LLDB_LOG(log, "Replacing \"{0}\" with \"{1}\"", PrintValue(alloc), PrintValue(persistent_load)); @@ -1129,8 +1089,7 @@ bool IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) { if (!m_resolve_vars) return true; - lldb_private::Log *log( - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + lldb_private::Log *log(GetLog(LLDBLog::Expressions)); InstrList pvar_allocs; @@ -1171,8 +1130,7 @@ bool IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) { // This function does not report errors; its callers are responsible. bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) { - lldb_private::Log *log( - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + lldb_private::Log *log(GetLog(LLDBLog::Expressions)); LLDB_LOG(log, "MaybeHandleVariable ({0})", PrintValue(llvm_value_ptr)); @@ -1266,8 +1224,7 @@ bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) { // This function does not report errors; its callers are responsible. bool IRForTarget::HandleSymbol(Value *symbol) { - lldb_private::Log *log( - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + lldb_private::Log *log(GetLog(LLDBLog::Expressions)); lldb_private::ConstString name(symbol->getName().str().c_str()); @@ -1298,8 +1255,7 @@ bool IRForTarget::HandleSymbol(Value *symbol) { } bool IRForTarget::MaybeHandleCallArguments(CallInst *Old) { - lldb_private::Log *log( - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + lldb_private::Log *log(GetLog(LLDBLog::Expressions)); LLDB_LOG(log, "MaybeHandleCallArguments({0})", PrintValue(Old)); @@ -1317,8 +1273,7 @@ bool IRForTarget::MaybeHandleCallArguments(CallInst *Old) { } bool IRForTarget::HandleObjCClass(Value *classlist_reference) { - lldb_private::Log *log( - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + lldb_private::Log *log(GetLog(LLDBLog::Expressions)); GlobalVariable *global_variable = dyn_cast<GlobalVariable>(classlist_reference); @@ -1419,8 +1374,7 @@ bool IRForTarget::ResolveCalls(BasicBlock &basic_block) { } bool IRForTarget::ResolveExternals(Function &llvm_function) { - lldb_private::Log *log( - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + lldb_private::Log *log(GetLog(LLDBLog::Expressions)); for (GlobalVariable &global_var : m_module->globals()) { llvm::StringRef global_name = global_var.getName(); @@ -1638,8 +1592,7 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) { if (!m_resolve_vars) return true; - lldb_private::Log *log( - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + lldb_private::Log *log(GetLog(LLDBLog::Expressions)); m_decl_map->DoStructLayout(); @@ -1772,20 +1725,19 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) { llvm::Instruction *entry_instruction = llvm::cast<Instruction>( m_entry_instruction_finder.GetValue(function)); + Type *int8Ty = Type::getInt8Ty(function->getContext()); ConstantInt *offset_int( ConstantInt::get(offset_type, offset, true)); GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create( - argument->getType()->getPointerElementType(), argument, - offset_int, "", entry_instruction); + int8Ty, argument, offset_int, "", entry_instruction); if (name == m_result_name && !m_result_is_pointer) { BitCastInst *bit_cast = new BitCastInst( get_element_ptr, value->getType()->getPointerTo(), "", entry_instruction); - LoadInst *load = - new LoadInst(bit_cast->getType()->getPointerElementType(), - bit_cast, "", entry_instruction); + LoadInst *load = new LoadInst(value->getType(), bit_cast, "", + entry_instruction); return load; } else { @@ -1827,8 +1779,7 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) { } bool IRForTarget::runOnModule(Module &llvm_module) { - lldb_private::Log *log( - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + lldb_private::Log *log(GetLog(LLDBLog::Expressions)); m_module = &llvm_module; m_target_data = std::make_unique<DataLayout>(m_module); diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp index 8709c2b0dcea..a672045dfe31 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp @@ -8,6 +8,7 @@ #include "NameSearchContext.h" #include "ClangUtil.h" +#include "lldb/Utility/LLDBLog.h" using namespace clang; using namespace lldb_private; @@ -106,7 +107,7 @@ clang::NamedDecl *NameSearchContext::AddFunDecl(const CompilerType &type, func_decl->setParams(ArrayRef<ParmVarDecl *>(parm_var_decls)); } else { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); LLDB_LOG(log, "Function type wasn't a FunctionProtoType"); } 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 5a238c5d4ac7..5bc745cf3b8b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp @@ -13761,35 +13761,33 @@ EmulateInstructionARM::GetThumbOpcodeForInstruction(const uint32_t opcode, bool EmulateInstructionARM::SetArchitecture(const ArchSpec &arch) { m_arch = arch; m_arm_isa = 0; - const char *arch_cstr = arch.GetArchitectureName(); - if (arch_cstr) { - if (0 == ::strcasecmp(arch_cstr, "armv4t")) - m_arm_isa = ARMv4T; - else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) - m_arm_isa = ARMv5TEJ; - else if (0 == ::strcasecmp(arch_cstr, "armv5te")) - m_arm_isa = ARMv5TE; - else if (0 == ::strcasecmp(arch_cstr, "armv5t")) - m_arm_isa = ARMv5T; - else if (0 == ::strcasecmp(arch_cstr, "armv6k")) - m_arm_isa = ARMv6K; - else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) - m_arm_isa = ARMv6T2; - else if (0 == ::strcasecmp(arch_cstr, "armv7s")) - m_arm_isa = ARMv7S; - else if (0 == ::strcasecmp(arch_cstr, "arm")) - m_arm_isa = ARMvAll; - else if (0 == ::strcasecmp(arch_cstr, "thumb")) - m_arm_isa = ARMvAll; - else if (0 == ::strncasecmp(arch_cstr, "armv4", 5)) - m_arm_isa = ARMv4; - else if (0 == ::strncasecmp(arch_cstr, "armv6", 5)) - m_arm_isa = ARMv6; - else if (0 == ::strncasecmp(arch_cstr, "armv7", 5)) - m_arm_isa = ARMv7; - else if (0 == ::strncasecmp(arch_cstr, "armv8", 5)) - m_arm_isa = ARMv8; - } + llvm::StringRef arch_cstr = arch.GetArchitectureName(); + if (arch_cstr.equals_insensitive("armv4t")) + m_arm_isa = ARMv4T; + else if (arch_cstr.equals_insensitive("armv5tej")) + m_arm_isa = ARMv5TEJ; + else if (arch_cstr.equals_insensitive("armv5te")) + m_arm_isa = ARMv5TE; + else if (arch_cstr.equals_insensitive("armv5t")) + m_arm_isa = ARMv5T; + else if (arch_cstr.equals_insensitive("armv6k")) + m_arm_isa = ARMv6K; + else if (arch_cstr.equals_insensitive("armv6t2")) + m_arm_isa = ARMv6T2; + else if (arch_cstr.equals_insensitive("armv7s")) + m_arm_isa = ARMv7S; + else if (arch_cstr.equals_insensitive("arm")) + m_arm_isa = ARMvAll; + else if (arch_cstr.equals_insensitive("thumb")) + m_arm_isa = ARMvAll; + else if (arch_cstr.startswith_insensitive("armv4")) + m_arm_isa = ARMv4; + else if (arch_cstr.startswith_insensitive("armv6")) + m_arm_isa = ARMv6; + else if (arch_cstr.startswith_insensitive("armv7")) + m_arm_isa = ARMv7; + else if (arch_cstr.startswith_insensitive("armv8")) + m_arm_isa = ARMv8; return m_arm_isa != 0; } 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 4ef0a034b6dd..7aff11ede400 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp @@ -668,7 +668,7 @@ bool EmulateInstructionMIPS::GetRegisterInfo(RegisterKind reg_kind, } EmulateInstructionMIPS::MipsOpcode * -EmulateInstructionMIPS::GetOpcodeForInstruction(const char *op_name) { +EmulateInstructionMIPS::GetOpcodeForInstruction(llvm::StringRef name) { static EmulateInstructionMIPS::MipsOpcode g_opcodes[] = { // Prologue/Epilogue instructions {"ADDiu", &EmulateInstructionMIPS::Emulate_ADDiu, @@ -954,13 +954,10 @@ EmulateInstructionMIPS::GetOpcodeForInstruction(const char *op_name) { {"JALRS_MM", &EmulateInstructionMIPS::Emulate_JALRS, "JALRS rt, rs"}, }; - static const size_t k_num_mips_opcodes = llvm::array_lengthof(g_opcodes); - - for (size_t i = 0; i < k_num_mips_opcodes; ++i) { - if (!strcasecmp(g_opcodes[i].op_name, op_name)) - return &g_opcodes[i]; + for (MipsOpcode &opcode : g_opcodes) { + if (name.equals_insensitive(opcode.op_name)) + return &opcode; } - return nullptr; } @@ -1342,7 +1339,7 @@ bool EmulateInstructionMIPS::Emulate_SUBU_ADDU(llvm::MCInst &insn) { bool success = false; uint64_t result; uint8_t src, dst, rt; - const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); + llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); @@ -1363,7 +1360,7 @@ bool EmulateInstructionMIPS::Emulate_SUBU_ADDU(llvm::MCInst &insn) { if (!success) return false; - if (!strcasecmp(op_name, "SUBU")) + if (op_name.equals_insensitive("SUBU")) result = src_opd_val - rt_opd_val; else result = src_opd_val + rt_opd_val; @@ -1396,7 +1393,7 @@ bool EmulateInstructionMIPS::Emulate_SUBU_ADDU(llvm::MCInst &insn) { Context context; - if (!strcasecmp(op_name, "SUBU")) + if (op_name.equals_insensitive("SUBU")) result = src_opd_val - rt_opd_val; else result = src_opd_val + rt_opd_val; @@ -1794,7 +1791,7 @@ bool EmulateInstructionMIPS::Emulate_BXX_3ops(llvm::MCInst &insn) { bool success = false; uint32_t rs, rt; int32_t offset, pc, target = 0, rs_val, rt_val; - const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); + llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); @@ -1814,12 +1811,13 @@ bool EmulateInstructionMIPS::Emulate_BXX_3ops(llvm::MCInst &insn) { if (!success) return false; - if (!strcasecmp(op_name, "BEQ") || !strcasecmp(op_name, "BEQL")) { + if (op_name.equals_insensitive("BEQ") || op_name.equals_insensitive("BEQL")) { if (rs_val == rt_val) target = pc + offset; else target = pc + 8; - } else if (!strcasecmp(op_name, "BNE") || !strcasecmp(op_name, "BNEL")) { + } else if (op_name.equals_insensitive("BNE") || + op_name.equals_insensitive("BNEL")) { if (rs_val != rt_val) target = pc + offset; else @@ -1843,7 +1841,7 @@ bool EmulateInstructionMIPS::Emulate_BXX_3ops_C(llvm::MCInst &insn) { bool success = false; uint32_t rs, rt; int32_t offset, pc, target = 0, rs_val, rt_val; - const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); + llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize(); rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); @@ -1864,42 +1862,42 @@ bool EmulateInstructionMIPS::Emulate_BXX_3ops_C(llvm::MCInst &insn) { if (!success) return false; - if (!strcasecmp(op_name, "BEQC")) { + if (op_name.equals_insensitive("BEQC")) { if (rs_val == rt_val) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BNEC")) { + } else if (op_name.equals_insensitive("BNEC")) { if (rs_val != rt_val) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BLTC")) { + } else if (op_name.equals_insensitive("BLTC")) { if (rs_val < rt_val) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BGEC")) { + } else if (op_name.equals_insensitive("BGEC")) { if (rs_val >= rt_val) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BLTUC")) { + } else if (op_name.equals_insensitive("BLTUC")) { if (rs_val < rt_val) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BGEUC")) { + } else if (op_name.equals_insensitive("BGEUC")) { if ((uint32_t)rs_val >= (uint32_t)rt_val) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BOVC")) { + } else if (op_name.equals_insensitive("BOVC")) { if (IsAdd64bitOverflow(rs_val, rt_val)) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BNVC")) { + } else if (op_name.equals_insensitive("BNVC")) { if (!IsAdd64bitOverflow(rs_val, rt_val)) target = pc + offset; else @@ -1923,7 +1921,7 @@ bool EmulateInstructionMIPS::Emulate_Bcond_Link_C(llvm::MCInst &insn) { uint32_t rs; int32_t offset, pc, target = 0; int32_t rs_val; - const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); + llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); offset = insn.getOperand(1).getImm(); @@ -1937,32 +1935,32 @@ bool EmulateInstructionMIPS::Emulate_Bcond_Link_C(llvm::MCInst &insn) { if (!success) return false; - if (!strcasecmp(op_name, "BLEZALC")) { + if (op_name.equals_insensitive("BLEZALC")) { if (rs_val <= 0) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BGEZALC")) { + } else if (op_name.equals_insensitive("BGEZALC")) { if (rs_val >= 0) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BLTZALC")) { + } else if (op_name.equals_insensitive("BLTZALC")) { if (rs_val < 0) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BGTZALC")) { + } else if (op_name.equals_insensitive("BGTZALC")) { if (rs_val > 0) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BEQZALC")) { + } else if (op_name.equals_insensitive("BEQZALC")) { if (rs_val == 0) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BNEZALC")) { + } else if (op_name.equals_insensitive("BNEZALC")) { if (rs_val != 0) target = pc + offset; else @@ -1992,7 +1990,7 @@ bool EmulateInstructionMIPS::Emulate_Bcond_Link(llvm::MCInst &insn) { uint32_t rs; int32_t offset, pc, target = 0; int32_t rs_val; - const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); + llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); offset = insn.getOperand(1).getImm(); @@ -2006,13 +2004,14 @@ bool EmulateInstructionMIPS::Emulate_Bcond_Link(llvm::MCInst &insn) { if (!success) return false; - if (!strcasecmp(op_name, "BLTZAL") || !strcasecmp(op_name, "BLTZALL")) { + if (op_name.equals_insensitive("BLTZAL") || + op_name.equals_insensitive("BLTZALL")) { if ((int32_t)rs_val < 0) target = pc + offset; else target = pc + 8; - } else if (!strcasecmp(op_name, "BGEZAL") || - !strcasecmp(op_name, "BGEZALL")) { + } else if (op_name.equals_insensitive("BGEZAL") || + op_name.equals_insensitive("BGEZALL")) { if ((int32_t)rs_val >= 0) target = pc + offset; else @@ -2042,7 +2041,7 @@ bool EmulateInstructionMIPS::Emulate_BXX_2ops(llvm::MCInst &insn) { uint32_t rs; int32_t offset, pc, target = 0; int32_t rs_val; - const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); + llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); offset = insn.getOperand(1).getImm(); @@ -2056,22 +2055,26 @@ bool EmulateInstructionMIPS::Emulate_BXX_2ops(llvm::MCInst &insn) { if (!success) return false; - if (!strcasecmp(op_name, "BLTZL") || !strcasecmp(op_name, "BLTZ")) { + if (op_name.equals_insensitive("BLTZL") || + op_name.equals_insensitive("BLTZ")) { if (rs_val < 0) target = pc + offset; else target = pc + 8; - } else if (!strcasecmp(op_name, "BGEZL") || !strcasecmp(op_name, "BGEZ")) { + } else if (op_name.equals_insensitive("BGEZL") || + op_name.equals_insensitive("BGEZ")) { if (rs_val >= 0) target = pc + offset; else target = pc + 8; - } else if (!strcasecmp(op_name, "BGTZL") || !strcasecmp(op_name, "BGTZ")) { + } else if (op_name.equals_insensitive("BGTZL") || + op_name.equals_insensitive("BGTZ")) { if (rs_val > 0) target = pc + offset; else target = pc + 8; - } else if (!strcasecmp(op_name, "BLEZL") || !strcasecmp(op_name, "BLEZ")) { + } else if (op_name.equals_insensitive("BLEZL") || + op_name.equals_insensitive("BLEZ")) { if (rs_val <= 0) target = pc + offset; else @@ -2095,7 +2098,7 @@ bool EmulateInstructionMIPS::Emulate_BXX_2ops_C(llvm::MCInst &insn) { uint32_t rs; int32_t offset, pc, target = 0; int32_t rs_val; - const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); + llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize(); rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); @@ -2110,32 +2113,32 @@ bool EmulateInstructionMIPS::Emulate_BXX_2ops_C(llvm::MCInst &insn) { if (!success) return false; - if (!strcasecmp(op_name, "BLTZC")) { + if (op_name.equals_insensitive("BLTZC")) { if (rs_val < 0) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BLEZC")) { + } else if (op_name.equals_insensitive("BLEZC")) { if (rs_val <= 0) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BGEZC")) { + } else if (op_name.equals_insensitive("BGEZC")) { if (rs_val >= 0) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BGTZC")) { + } else if (op_name.equals_insensitive("BGTZC")) { if (rs_val > 0) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BEQZC")) { + } else if (op_name.equals_insensitive("BEQZC")) { if (rs_val == 0) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BNEZC")) { + } else if (op_name.equals_insensitive("BNEZC")) { if (rs_val != 0) target = pc + offset; else @@ -2181,7 +2184,7 @@ bool EmulateInstructionMIPS::Emulate_Branch_MM(llvm::MCInst &insn) { bool success = false; int32_t target = 0; uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize(); - const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); + llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); bool update_ra = false; uint32_t ra_offset = 0; @@ -2215,33 +2218,33 @@ bool EmulateInstructionMIPS::Emulate_Branch_MM(llvm::MCInst &insn) { if (!success) return false; - if (!strcasecmp(op_name, "BEQZ16_MM")) { + if (op_name.equals_insensitive("BEQZ16_MM")) { if (rs_val == 0) target = pc + offset; else target = pc + current_inst_size + m_next_inst_size; // Skip delay slot instruction. - } else if (!strcasecmp(op_name, "BNEZ16_MM")) { + } else if (op_name.equals_insensitive("BNEZ16_MM")) { if (rs_val != 0) target = pc + offset; else target = pc + current_inst_size + m_next_inst_size; // Skip delay slot instruction. - } else if (!strcasecmp(op_name, "BEQZC_MM")) { + } else if (op_name.equals_insensitive("BEQZC_MM")) { if (rs_val == 0) target = pc + 4 + offset; else target = pc + 4; // 32 bit instruction and does not have delay slot instruction. - } else if (!strcasecmp(op_name, "BNEZC_MM")) { + } else if (op_name.equals_insensitive("BNEZC_MM")) { if (rs_val != 0) target = pc + 4 + offset; else target = pc + 4; // 32 bit instruction and does not have delay slot instruction. - } else if (!strcasecmp(op_name, "BGEZALS_MM")) { + } else if (op_name.equals_insensitive("BGEZALS_MM")) { if (rs_val >= 0) target = pc + offset; else @@ -2249,7 +2252,7 @@ bool EmulateInstructionMIPS::Emulate_Branch_MM(llvm::MCInst &insn) { update_ra = true; ra_offset = 6; - } else if (!strcasecmp(op_name, "BLTZALS_MM")) { + } else if (op_name.equals_insensitive("BLTZALS_MM")) { if (rs_val >= 0) target = pc + offset; else @@ -2281,7 +2284,7 @@ bool EmulateInstructionMIPS::Emulate_Branch_MM(llvm::MCInst &insn) { bool EmulateInstructionMIPS::Emulate_JALRx16_MM(llvm::MCInst &insn) { bool success = false; uint32_t ra_offset = 0; - const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); + llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); uint32_t rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); @@ -2295,9 +2298,9 @@ bool EmulateInstructionMIPS::Emulate_JALRx16_MM(llvm::MCInst &insn) { if (!success) return false; - if (!strcasecmp(op_name, "JALR16_MM")) + if (op_name.equals_insensitive("JALR16_MM")) ra_offset = 6; // 2-byte instruction with 4-byte delay slot. - else if (!strcasecmp(op_name, "JALRS16_MM")) + else if (op_name.equals_insensitive("JALRS16_MM")) ra_offset = 4; // 2-byte instruction with 2-byte delay slot. Context context; @@ -2320,7 +2323,7 @@ bool EmulateInstructionMIPS::Emulate_JALRx16_MM(llvm::MCInst &insn) { bool EmulateInstructionMIPS::Emulate_JALx(llvm::MCInst &insn) { bool success = false; uint32_t offset = 0, target = 0, pc = 0, ra_offset = 0; - const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); + llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); /* * JALS target @@ -2339,11 +2342,11 @@ bool EmulateInstructionMIPS::Emulate_JALx(llvm::MCInst &insn) { return false; // These are PC-region branches and not PC-relative. - if (!strcasecmp(op_name, "JALS_MM")) { + if (op_name.equals_insensitive("JALS_MM")) { // target address is in the “current” 128 MB-aligned region target = (pc & 0xF8000000UL) | offset; ra_offset = 6; - } else if (!strcasecmp(op_name, "JALX_MM")) { + } else if (op_name.equals_insensitive("JALX_MM")) { // target address is in the “current” 256 MB-aligned region target = (pc & 0xF0000000UL) | offset; ra_offset = 8; @@ -2668,7 +2671,7 @@ bool EmulateInstructionMIPS::Emulate_FP_branch(llvm::MCInst &insn) { bool success = false; uint32_t cc, fcsr; int32_t pc, offset, target = 0; - const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); + llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); offset = insn.getOperand(1).getImm(); @@ -2684,12 +2687,14 @@ bool EmulateInstructionMIPS::Emulate_FP_branch(llvm::MCInst &insn) { /* fcsr[23], fcsr[25-31] are vaild condition bits */ fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01); - if (!strcasecmp(op_name, "BC1F") || !strcasecmp(op_name, "BC1FL")) { + if (op_name.equals_insensitive("BC1F") || + op_name.equals_insensitive("BC1FL")) { if ((fcsr & (1 << cc)) == 0) target = pc + offset; else target = pc + 8; - } else if (!strcasecmp(op_name, "BC1T") || !strcasecmp(op_name, "BC1TL")) { + } else if (op_name.equals_insensitive("BC1T") || + op_name.equals_insensitive("BC1TL")) { if ((fcsr & (1 << cc)) != 0) target = pc + offset; else @@ -2784,7 +2789,7 @@ bool EmulateInstructionMIPS::Emulate_3D_branch(llvm::MCInst &insn) { bool success = false; uint32_t cc, fcsr; int32_t pc, offset, target = 0; - const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); + llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); offset = insn.getOperand(1).getImm(); @@ -2801,25 +2806,25 @@ bool EmulateInstructionMIPS::Emulate_3D_branch(llvm::MCInst &insn) { /* fcsr[23], fcsr[25-31] are vaild condition bits */ fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01); - if (!strcasecmp(op_name, "BC1ANY2F")) { + if (op_name.equals_insensitive("BC1ANY2F")) { /* if any one bit is 0 */ if (((fcsr >> cc) & 3) != 3) target = pc + offset; else target = pc + 8; - } else if (!strcasecmp(op_name, "BC1ANY2T")) { + } else if (op_name.equals_insensitive("BC1ANY2T")) { /* if any one bit is 1 */ if (((fcsr >> cc) & 3) != 0) target = pc + offset; else target = pc + 8; - } else if (!strcasecmp(op_name, "BC1ANY4F")) { + } else if (op_name.equals_insensitive("BC1ANY4F")) { /* if any one bit is 0 */ if (((fcsr >> cc) & 0xf) != 0xf) target = pc + offset; else target = pc + 8; - } else if (!strcasecmp(op_name, "BC1ANY4T")) { + } else if (op_name.equals_insensitive("BC1ANY4T")) { /* if any one bit is 1 */ if (((fcsr >> cc) & 0xf) != 0) target = pc + offset; diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h b/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h index 48782186e065..4862f6c7e0dc 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h @@ -93,7 +93,7 @@ protected: const char *insn_name; } MipsOpcode; - static MipsOpcode *GetOpcodeForInstruction(const char *op_name); + static MipsOpcode *GetOpcodeForInstruction(llvm::StringRef name); uint32_t GetSizeOfInstruction(lldb_private::DataExtractor &data, uint64_t inst_addr); 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 26736f4c58ba..b4a860af54bd 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp @@ -655,7 +655,7 @@ bool EmulateInstructionMIPS64::GetRegisterInfo(RegisterKind reg_kind, } EmulateInstructionMIPS64::MipsOpcode * -EmulateInstructionMIPS64::GetOpcodeForInstruction(const char *op_name) { +EmulateInstructionMIPS64::GetOpcodeForInstruction(llvm::StringRef op_name) { static EmulateInstructionMIPS64::MipsOpcode g_opcodes[] = { // Prologue/Epilogue instructions {"DADDiu", &EmulateInstructionMIPS64::Emulate_DADDiu, @@ -919,13 +919,10 @@ EmulateInstructionMIPS64::GetOpcodeForInstruction(const char *op_name) { {"BZ_V", &EmulateInstructionMIPS64::Emulate_BZV, "BZ.V wt,s16"}, }; - static const size_t k_num_mips_opcodes = llvm::array_lengthof(g_opcodes); - - for (size_t i = 0; i < k_num_mips_opcodes; ++i) { - if (!strcasecmp(g_opcodes[i].op_name, op_name)) - return &g_opcodes[i]; + for (MipsOpcode &opcode : g_opcodes) { + if (op_name.equals_insensitive(opcode.op_name)) + return &opcode; } - return nullptr; } @@ -967,10 +964,7 @@ bool EmulateInstructionMIPS64::EvaluateInstruction(uint32_t evaluate_options) { * mc_insn.getOpcode() returns decoded opcode. However to make use * of llvm::Mips::<insn> we would need "MipsGenInstrInfo.inc". */ - const char *op_name = m_insn_info->getName(mc_insn.getOpcode()).data(); - - if (op_name == nullptr) - return false; + llvm::StringRef op_name = m_insn_info->getName(mc_insn.getOpcode()); /* * Decoding has been done already. Just get the call-back function @@ -1256,7 +1250,7 @@ bool EmulateInstructionMIPS64::Emulate_DSUBU_DADDU(llvm::MCInst &insn) { bool success = false; uint64_t result; uint8_t src, dst, rt; - const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); + llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); @@ -1277,7 +1271,8 @@ bool EmulateInstructionMIPS64::Emulate_DSUBU_DADDU(llvm::MCInst &insn) { if (!success) return false; - if (!strcasecmp(op_name, "DSUBU") || !strcasecmp(op_name, "SUBU")) + if (op_name.equals_insensitive("DSUBU") || + op_name.equals_insensitive("SUBU")) result = src_opd_val - rt_opd_val; else result = src_opd_val + rt_opd_val; @@ -1310,7 +1305,8 @@ bool EmulateInstructionMIPS64::Emulate_DSUBU_DADDU(llvm::MCInst &insn) { Context context; - if (!strcasecmp(op_name, "DSUBU") || !strcasecmp(op_name, "SUBU")) + if (op_name.equals_insensitive("DSUBU") || + op_name.equals_insensitive("SUBU")) result = src_opd_val - rt_opd_val; else result = src_opd_val + rt_opd_val; @@ -1335,7 +1331,7 @@ bool EmulateInstructionMIPS64::Emulate_BXX_3ops(llvm::MCInst &insn) { bool success = false; uint32_t rs, rt; int64_t offset, pc, rs_val, rt_val, target = 0; - const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); + llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); @@ -1355,14 +1351,15 @@ bool EmulateInstructionMIPS64::Emulate_BXX_3ops(llvm::MCInst &insn) { if (!success) return false; - if (!strcasecmp(op_name, "BEQ") || !strcasecmp(op_name, "BEQL") - || !strcasecmp(op_name, "BEQ64") ) { + if (op_name.equals_insensitive("BEQ") || op_name.equals_insensitive("BEQL") || + op_name.equals_insensitive("BEQ64")) { if (rs_val == rt_val) target = pc + offset; else target = pc + 8; - } else if (!strcasecmp(op_name, "BNE") || !strcasecmp(op_name, "BNEL") - || !strcasecmp(op_name, "BNE64")) { + } else if (op_name.equals_insensitive("BNE") || + op_name.equals_insensitive("BNEL") || + op_name.equals_insensitive("BNE64")) { if (rs_val != rt_val) target = pc + offset; else @@ -1387,7 +1384,7 @@ bool EmulateInstructionMIPS64::Emulate_Bcond_Link(llvm::MCInst &insn) { uint32_t rs; int64_t offset, pc, target = 0; int64_t rs_val; - const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); + llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); offset = insn.getOperand(1).getImm(); @@ -1401,13 +1398,14 @@ bool EmulateInstructionMIPS64::Emulate_Bcond_Link(llvm::MCInst &insn) { if (!success) return false; - if (!strcasecmp(op_name, "BLTZAL") || !strcasecmp(op_name, "BLTZALL")) { + if (op_name.equals_insensitive("BLTZAL") || + op_name.equals_insensitive("BLTZALL")) { if (rs_val < 0) target = pc + offset; else target = pc + 8; - } else if (!strcasecmp(op_name, "BGEZAL") || - !strcasecmp(op_name, "BGEZALL")) { + } else if (op_name.equals_insensitive("BGEZAL") || + op_name.equals_insensitive("BGEZALL")) { if (rs_val >= 0) target = pc + offset; else @@ -1497,7 +1495,7 @@ bool EmulateInstructionMIPS64::Emulate_Bcond_Link_C(llvm::MCInst &insn) { bool success = false; uint32_t rs; int64_t offset, pc, rs_val, target = 0; - const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); + llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); offset = insn.getOperand(1).getImm(); @@ -1511,32 +1509,32 @@ bool EmulateInstructionMIPS64::Emulate_Bcond_Link_C(llvm::MCInst &insn) { if (!success) return false; - if (!strcasecmp(op_name, "BLEZALC")) { + if (op_name.equals_insensitive("BLEZALC")) { if (rs_val <= 0) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BGEZALC")) { + } else if (op_name.equals_insensitive("BGEZALC")) { if (rs_val >= 0) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BLTZALC")) { + } else if (op_name.equals_insensitive("BLTZALC")) { if (rs_val < 0) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BGTZALC")) { + } else if (op_name.equals_insensitive("BGTZALC")) { if (rs_val > 0) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BEQZALC")) { + } else if (op_name.equals_insensitive("BEQZALC")) { if (rs_val == 0) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BNEZALC")) { + } else if (op_name.equals_insensitive("BNEZALC")) { if (rs_val != 0) target = pc + offset; else @@ -1565,7 +1563,7 @@ bool EmulateInstructionMIPS64::Emulate_BXX_2ops(llvm::MCInst &insn) { bool success = false; uint32_t rs; int64_t offset, pc, rs_val, target = 0; - const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); + llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); offset = insn.getOperand(1).getImm(); @@ -1579,26 +1577,30 @@ bool EmulateInstructionMIPS64::Emulate_BXX_2ops(llvm::MCInst &insn) { if (!success) return false; - if (!strcasecmp(op_name, "BLTZL") || !strcasecmp(op_name, "BLTZ") - || !strcasecmp(op_name, "BLTZ64")) { + if (op_name.equals_insensitive("BLTZL") || + op_name.equals_insensitive("BLTZ") || + op_name.equals_insensitive("BLTZ64")) { if (rs_val < 0) target = pc + offset; else target = pc + 8; - } else if (!strcasecmp(op_name, "BGEZL") || !strcasecmp(op_name, "BGEZ") - || !strcasecmp(op_name, "BGEZ64")) { + } else if (op_name.equals_insensitive("BGEZL") || + op_name.equals_insensitive("BGEZ") || + op_name.equals_insensitive("BGEZ64")) { if (rs_val >= 0) target = pc + offset; else target = pc + 8; - } else if (!strcasecmp(op_name, "BGTZL") || !strcasecmp(op_name, "BGTZ") - || !strcasecmp(op_name, "BGTZ64")) { + } else if (op_name.equals_insensitive("BGTZL") || + op_name.equals_insensitive("BGTZ") || + op_name.equals_insensitive("BGTZ64")) { if (rs_val > 0) target = pc + offset; else target = pc + 8; - } else if (!strcasecmp(op_name, "BLEZL") || !strcasecmp(op_name, "BLEZ") - || !strcasecmp(op_name, "BLEZ64")) { + } else if (op_name.equals_insensitive("BLEZL") || + op_name.equals_insensitive("BLEZ") || + op_name.equals_insensitive("BLEZ64")) { if (rs_val <= 0) target = pc + offset; else @@ -1650,7 +1652,7 @@ bool EmulateInstructionMIPS64::Emulate_BXX_3ops_C(llvm::MCInst &insn) { bool success = false; uint32_t rs, rt; int64_t offset, pc, rs_val, rt_val, target = 0; - const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); + llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize(); rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); @@ -1671,42 +1673,48 @@ bool EmulateInstructionMIPS64::Emulate_BXX_3ops_C(llvm::MCInst &insn) { if (!success) return false; - if (!strcasecmp(op_name, "BEQC") || !strcasecmp(op_name, "BEQC64")) { + if (op_name.equals_insensitive("BEQC") || + op_name.equals_insensitive("BEQC64")) { if (rs_val == rt_val) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BNEC") || !strcasecmp(op_name, "BNEC64")) { + } else if (op_name.equals_insensitive("BNEC") || + op_name.equals_insensitive("BNEC64")) { if (rs_val != rt_val) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BLTC") || !strcasecmp(op_name, "BLTC64")) { + } else if (op_name.equals_insensitive("BLTC") || + op_name.equals_insensitive("BLTC64")) { if (rs_val < rt_val) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BGEC64") || !strcasecmp(op_name, "BGEC")) { + } else if (op_name.equals_insensitive("BGEC64") || + op_name.equals_insensitive("BGEC")) { if (rs_val >= rt_val) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BLTUC") || !strcasecmp(op_name, "BLTUC64")) { + } else if (op_name.equals_insensitive("BLTUC") || + op_name.equals_insensitive("BLTUC64")) { if (rs_val < rt_val) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BGEUC") || !strcasecmp(op_name, "BGEUC64")) { + } else if (op_name.equals_insensitive("BGEUC") || + op_name.equals_insensitive("BGEUC64")) { if ((uint32_t)rs_val >= (uint32_t)rt_val) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BOVC")) { + } else if (op_name.equals_insensitive("BOVC")) { if (IsAdd64bitOverflow(rs_val, rt_val)) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BNVC")) { + } else if (op_name.equals_insensitive("BNVC")) { if (!IsAdd64bitOverflow(rs_val, rt_val)) target = pc + offset; else @@ -1730,7 +1738,7 @@ bool EmulateInstructionMIPS64::Emulate_BXX_2ops_C(llvm::MCInst &insn) { uint32_t rs; int64_t offset, pc, target = 0; int64_t rs_val; - const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); + llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize(); rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); @@ -1745,32 +1753,38 @@ bool EmulateInstructionMIPS64::Emulate_BXX_2ops_C(llvm::MCInst &insn) { if (!success) return false; - if (!strcasecmp(op_name, "BLTZC") || !strcasecmp(op_name, "BLTZC64")) { + if (op_name.equals_insensitive("BLTZC") || + op_name.equals_insensitive("BLTZC64")) { if (rs_val < 0) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BLEZC") || !strcasecmp(op_name, "BLEZC64")) { + } else if (op_name.equals_insensitive("BLEZC") || + op_name.equals_insensitive("BLEZC64")) { if (rs_val <= 0) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BGEZC") || !strcasecmp(op_name, "BGEZC64")) { + } else if (op_name.equals_insensitive("BGEZC") || + op_name.equals_insensitive("BGEZC64")) { if (rs_val >= 0) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BGTZC") || !strcasecmp(op_name, "BGTZC64")) { + } else if (op_name.equals_insensitive("BGTZC") || + op_name.equals_insensitive("BGTZC64")) { if (rs_val > 0) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BEQZC") || !strcasecmp(op_name, "BEQZC64")) { + } else if (op_name.equals_insensitive("BEQZC") || + op_name.equals_insensitive("BEQZC64")) { if (rs_val == 0) target = pc + offset; else target = pc + 4; - } else if (!strcasecmp(op_name, "BNEZC") || !strcasecmp(op_name, "BNEZC64")) { + } else if (op_name.equals_insensitive("BNEZC") || + op_name.equals_insensitive("BNEZC64")) { if (rs_val != 0) target = pc + offset; else @@ -1970,7 +1984,7 @@ bool EmulateInstructionMIPS64::Emulate_FP_branch(llvm::MCInst &insn) { bool success = false; uint32_t cc, fcsr; int64_t pc, offset, target = 0; - const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); + llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); /* * BC1F cc, offset @@ -1994,12 +2008,14 @@ bool EmulateInstructionMIPS64::Emulate_FP_branch(llvm::MCInst &insn) { /* fcsr[23], fcsr[25-31] are vaild condition bits */ fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01); - if (!strcasecmp(op_name, "BC1F") || !strcasecmp(op_name, "BC1FL")) { + if (op_name.equals_insensitive("BC1F") || + op_name.equals_insensitive("BC1FL")) { if ((fcsr & (1 << cc)) == 0) target = pc + offset; else target = pc + 8; - } else if (!strcasecmp(op_name, "BC1T") || !strcasecmp(op_name, "BC1TL")) { + } else if (op_name.equals_insensitive("BC1T") || + op_name.equals_insensitive("BC1TL")) { if ((fcsr & (1 << cc)) != 0) target = pc + offset; else @@ -2095,7 +2111,7 @@ bool EmulateInstructionMIPS64::Emulate_3D_branch(llvm::MCInst &insn) { bool success = false; uint32_t cc, fcsr; int64_t pc, offset, target = 0; - const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); + llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); offset = insn.getOperand(1).getImm(); @@ -2112,25 +2128,25 @@ bool EmulateInstructionMIPS64::Emulate_3D_branch(llvm::MCInst &insn) { /* fcsr[23], fcsr[25-31] are vaild condition bits */ fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01); - if (!strcasecmp(op_name, "BC1ANY2F")) { + if (op_name.equals_insensitive("BC1ANY2F")) { /* if any one bit is 0 */ if (((fcsr >> cc) & 3) != 3) target = pc + offset; else target = pc + 8; - } else if (!strcasecmp(op_name, "BC1ANY2T")) { + } else if (op_name.equals_insensitive("BC1ANY2T")) { /* if any one bit is 1 */ if (((fcsr >> cc) & 3) != 0) target = pc + offset; else target = pc + 8; - } else if (!strcasecmp(op_name, "BC1ANY4F")) { + } else if (op_name.equals_insensitive("BC1ANY4F")) { /* if any one bit is 0 */ if (((fcsr >> cc) & 0xf) != 0xf) target = pc + offset; else target = pc + 8; - } else if (!strcasecmp(op_name, "BC1ANY4T")) { + } else if (op_name.equals_insensitive("BC1ANY4T")) { /* if any one bit is 1 */ if (((fcsr >> cc) & 0xf) != 0) target = pc + offset; diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h b/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h index acd956e613d4..3f56bc658c16 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h @@ -85,7 +85,7 @@ protected: const char *insn_name; } MipsOpcode; - static MipsOpcode *GetOpcodeForInstruction(const char *op_name); + static MipsOpcode *GetOpcodeForInstruction(llvm::StringRef op_name); bool Emulate_DADDiu(llvm::MCInst &insn); 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 dcfad8e106aa..13cd4db22714 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp @@ -10,12 +10,12 @@ #include <cstdlib> +#include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h" #include "lldb/Core/PluginManager.h" #include "lldb/Symbol/UnwindPlan.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/ConstString.h" - -#include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h" +#include "lldb/Utility/LLDBLog.h" #define DECLARE_REGISTER_INFOS_PPC64LE_STRUCT #include "Plugins/Process/Utility/RegisterInfos_ppc64le.h" @@ -210,7 +210,7 @@ bool EmulateInstructionPPC64::EmulateMFSPR(uint32_t opcode) { if (rt != gpr_r0_ppc64le || spr != SPR_LR) return false; - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + Log *log = GetLog(LLDBLog::Unwind); LLDB_LOG(log, "EmulateMFSPR: {0:X+8}: mfspr r0, lr", m_addr); bool success; @@ -237,7 +237,7 @@ bool EmulateInstructionPPC64::EmulateLD(uint32_t opcode) { if (ra != gpr_r1_ppc64le || rt != gpr_r1_ppc64le || ids != 0) return false; - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + Log *log = GetLog(LLDBLog::Unwind); LLDB_LOG(log, "EmulateLD: {0:X+8}: ld r{1}, {2}(r{3})", m_addr, rt, ids, ra); RegisterInfo r1_info; @@ -274,7 +274,7 @@ bool EmulateInstructionPPC64::EmulateSTD(uint32_t opcode) { return false; int32_t ids = llvm::SignExtend32<16>(ds << 2); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + Log *log = GetLog(LLDBLog::Unwind); LLDB_LOG(log, "EmulateSTD: {0:X+8}: std{1} r{2}, {3}(r{4})", m_addr, u ? "u" : "", rs, ids, ra); @@ -331,7 +331,7 @@ bool EmulateInstructionPPC64::EmulateOR(uint32_t opcode) { (ra != gpr_r30_ppc64le && ra != gpr_r31_ppc64le) || rb != gpr_r1_ppc64le) return false; - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + Log *log = GetLog(LLDBLog::Unwind); LLDB_LOG(log, "EmulateOR: {0:X+8}: mr r{1}, r{2}", m_addr, ra, rb); // set context @@ -366,7 +366,7 @@ bool EmulateInstructionPPC64::EmulateADDI(uint32_t opcode) { return false; int32_t si_val = llvm::SignExtend32<16>(si); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + Log *log = GetLog(LLDBLog::Unwind); LLDB_LOG(log, "EmulateADDI: {0:X+8}: addi r1, r1, {1}", m_addr, si_val); // set context diff --git a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.cpp b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.cpp index 33b2b5dd5155..474611287311 100644 --- a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.cpp @@ -136,9 +136,11 @@ StructuredData::ObjectSP InstrumentationRuntimeASan::RetrieveReportData() { exe_ctx, options, address_sanitizer_retrieve_report_data_command, "", return_value_sp, eval_error); if (result != eExpressionCompleted) { - process_sp->GetTarget().GetDebugger().GetAsyncOutputStream()->Printf( - "Warning: Cannot evaluate AddressSanitizer expression:\n%s\n", - eval_error.AsCString()); + StreamString ss; + ss << "cannot evaluate AddressSanitizer expression:\n"; + ss << eval_error.AsCString(); + Debugger::ReportWarning(ss.GetString().str(), + process_sp->GetTarget().GetDebugger().GetID()); return StructuredData::ObjectSP(); } diff --git a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp index 977d8e4dbe07..55ef3d245411 100644 --- a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp @@ -327,9 +327,11 @@ StructuredData::ObjectSP InstrumentationRuntimeTSan::RetrieveReportData( exe_ctx, options, thread_sanitizer_retrieve_report_data_command, "", main_value, eval_error); if (result != eExpressionCompleted) { - process_sp->GetTarget().GetDebugger().GetAsyncOutputStream()->Printf( - "Warning: Cannot evaluate ThreadSanitizer expression:\n%s\n", - eval_error.AsCString()); + StreamString ss; + ss << "cannot evaluate ThreadSanitizer expression:\n"; + ss << eval_error.AsCString(); + Debugger::ReportWarning(ss.GetString().str(), + process_sp->GetTarget().GetDebugger().GetID()); return StructuredData::ObjectSP(); } 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 8e7799dc0761..5544c5f08f3b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp @@ -136,9 +136,11 @@ StructuredData::ObjectSP InstrumentationRuntimeUBSan::RetrieveReportData( exe_ctx, options, ub_sanitizer_retrieve_report_data_command, "", main_value, eval_error); if (result != eExpressionCompleted) { - target.GetDebugger().GetAsyncOutputStream()->Printf( - "Warning: Cannot evaluate UndefinedBehaviorSanitizer expression:\n%s\n", - eval_error.AsCString()); + StreamString ss; + ss << "cannot evaluate UndefinedBehaviorSanitizer expression:\n"; + ss << eval_error.AsCString(); + Debugger::ReportWarning(ss.GetString().str(), + process_sp->GetTarget().GetDebugger().GetID()); return StructuredData::ObjectSP(); } diff --git a/contrib/llvm-project/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp b/contrib/llvm-project/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp index ff5c82752b37..13633e8261e4 100644 --- a/contrib/llvm-project/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp @@ -25,6 +25,7 @@ #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" #include "llvm/Support/MathExtras.h" @@ -188,7 +189,7 @@ void JITLoaderGDB::SetJITBreakpoint(lldb_private::ModuleList &module_list) { if (DidSetJITBreakpoint()) return; - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER)); + Log *log = GetLog(LLDBLog::JITLoader); LLDB_LOGF(log, "JITLoaderGDB::%s looking for JIT register hook", __FUNCTION__); @@ -220,7 +221,7 @@ bool JITLoaderGDB::JITDebugBreakpointHit(void *baton, StoppointCallbackContext *context, user_id_t break_id, user_id_t break_loc_id) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER)); + Log *log = GetLog(LLDBLog::JITLoader); LLDB_LOGF(log, "JITLoaderGDB::%s hit JIT breakpoint", __FUNCTION__); JITLoaderGDB *instance = static_cast<JITLoaderGDB *>(baton); return instance->ReadJITDescriptor(false); @@ -284,7 +285,7 @@ bool JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries) { if (m_jit_descriptor_addr == LLDB_INVALID_ADDRESS) return false; - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER)); + Log *log = GetLog(LLDBLog::JITLoader); Target &target = m_process->GetTarget(); ModuleList &module_list = target.GetImages(); 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 1c498a2ddc11..1b3cf1ec0987 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp @@ -17,6 +17,7 @@ #include "lldb/Symbol/TypeSystem.h" #include "lldb/Target/Target.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" using namespace lldb; @@ -43,9 +44,8 @@ public: auto type_system_or_err = target_sp->GetScratchTypeSystemForLanguage( lldb::eLanguageTypeC_plus_plus); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR( - lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS), - std::move(err), "Failed to get scratch TypeSystemClang"); + LLDB_LOG_ERROR(GetLog(LLDBLog::DataFormatters), std::move(err), + "Failed to get scratch TypeSystemClang"); return; } 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 0fb65f5a317d..82f825871593 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -29,6 +29,7 @@ #include "lldb/DataFormatters/VectorType.h" #include "lldb/Symbol/SymbolFile.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegularExpression.h" @@ -267,6 +268,41 @@ std::string CPlusPlusLanguage::MethodName::GetScopeQualifiedName() { return res; } +bool CPlusPlusLanguage::MethodName::ContainsPath(llvm::StringRef path) { + if (!m_parsed) + Parse(); + // If we can't parse the incoming name, then just check that it contains path. + if (m_parse_error) + return m_full.GetStringRef().contains(path); + + llvm::StringRef identifier; + llvm::StringRef context; + std::string path_str = path.str(); + bool success + = CPlusPlusLanguage::ExtractContextAndIdentifier(path_str.c_str(), + context, + identifier); + if (!success) + return m_full.GetStringRef().contains(path); + + if (identifier != GetBasename()) + return false; + // Incoming path only had an identifier, so we match. + if (context.empty()) + return true; + // Incoming path has context but this method does not, no match. + if (m_context.empty()) + return false; + + llvm::StringRef haystack = m_context; + if (!haystack.consume_back(context)) + return false; + if (haystack.empty() || !isalnum(haystack.back())) + return true; + + return false; +} + bool CPlusPlusLanguage::IsCPPMangledName(llvm::StringRef name) { // FIXME!! we should really run through all the known C++ Language plugins // and ask each one if this is a C++ mangled name @@ -279,6 +315,12 @@ bool CPlusPlusLanguage::IsCPPMangledName(llvm::StringRef name) { return true; } +bool CPlusPlusLanguage::DemangledNameContainsPath(llvm::StringRef path, + ConstString demangled) const { + MethodName demangled_name(demangled); + return demangled_name.ContainsPath(path); +} + bool CPlusPlusLanguage::ExtractContextAndIdentifier( const char *name, llvm::StringRef &context, llvm::StringRef &identifier) { if (MSVCUndecoratedNameParser::IsMSVCUndecoratedName(name)) @@ -337,7 +379,7 @@ protected: } ConstString substituteImpl(llvm::StringRef Mangled) { - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE); + Log *log = GetLog(LLDBLog::Language); if (this->parse() == nullptr) { LLDB_LOG(log, "Failed to substitute mangling in {0}", Mangled); return ConstString(); @@ -714,6 +756,12 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator, "libc++ std::atomic synthetic children", ConstString("^std::__[[:alnum:]]+::atomic<.+>$"), stl_synth_flags, true); + AddCXXSynthetic( + cpp_category_sp, + lldb_private::formatters::LibcxxStdSpanSyntheticFrontEndCreator, + "libc++ std::span synthetic children", + ConstString("^std::__[[:alnum:]]+::span<.+>(( )?&)?$"), stl_deref_flags, + true); cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add( RegularExpression("^(std::__[[:alnum:]]+::)deque<.+>(( )?&)?$"), @@ -827,6 +875,11 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { "libc++ std::variant summary provider", ConstString("^std::__[[:alnum:]]+::variant<.+>(( )?&)?$"), stl_summary_flags, true); + AddCXXSummary(cpp_category_sp, + lldb_private::formatters::LibcxxContainerSummaryProvider, + "libc++ std::span summary provider", + ConstString("^std::__[[:alnum:]]+::span<.+>(( )?&)?$"), + stl_summary_flags, true); stl_summary_flags.SetSkipPointers(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 5547864a3763..53a01cfc4799 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h @@ -55,6 +55,8 @@ public: llvm::StringRef GetArguments(); llvm::StringRef GetQualifiers(); + + bool ContainsPath(llvm::StringRef path); protected: void Parse(); @@ -105,6 +107,9 @@ public: static llvm::StringRef GetPluginNameStatic() { return "cplusplus"; } bool SymbolNameFitsToLanguage(Mangled mangled) const override; + + bool DemangledNameContainsPath(llvm::StringRef path, + ConstString demangled) const override; ConstString GetDemangledFunctionNameWithoutArguments(Mangled mangled) const override; 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 21196393371e..eaaa16413b1e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp @@ -79,7 +79,7 @@ bool lldb_private::formatters::LibcxxFunctionSummaryProvider( switch (callable_info.callable_case) { case CPPLanguageRuntime::LibCppStdFunctionCallableCase::Invalid: - stream.Printf(" __f_ = %" PRIu64, callable_info.member__f_pointer_value); + stream.Printf(" __f_ = %" PRIu64, callable_info.member_f_pointer_value); return false; break; case CPPLanguageRuntime::LibCppStdFunctionCallableCase::Lambda: @@ -228,7 +228,7 @@ bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() { if (!valobj_sp) return false; - static ConstString g___i_("__i_"); + static ConstString g_i_("__i_"); // this must be a ValueObject* because it is a child of the ValueObject we // are producing children for it if were a ValueObjectSP, we would end up @@ -258,7 +258,7 @@ bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() { nullptr) .get(); if (m_pair_ptr) { - auto __i_(valobj_sp->GetChildMemberWithName(g___i_, true)); + auto __i_(valobj_sp->GetChildMemberWithName(g_i_, true)); if (!__i_) { m_pair_ptr = nullptr; return false; @@ -296,7 +296,7 @@ bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() { llvm::Optional<uint64_t> size = tree_node_type.GetByteSize(nullptr); if (!size) return false; - DataBufferSP buffer_sp(new DataBufferHeap(*size, 0)); + WritableDataBufferSP buffer_sp(new DataBufferHeap(*size, 0)); ProcessSP process_sp(target_sp->GetProcessSP()); Status error; process_sp->ReadMemory(addr, buffer_sp->GetBytes(), @@ -546,7 +546,7 @@ bool lldb_private::formatters::LibcxxContainerSummaryProvider( nullptr, nullptr, &valobj, false, false); } -// the field layout in a libc++ string (cap, side, data or data, size, cap) +/// The field layout in a libc++ string (cap, side, data or data, size, cap). enum LibcxxStringLayoutMode { eLibcxxStringLayoutModeCSD = 0, eLibcxxStringLayoutModeDSC = 1, @@ -555,14 +555,17 @@ enum LibcxxStringLayoutMode { /// Determine the size in bytes of \p valobj (a libc++ std::string object) and /// extract its data payload. Return the size + payload pair. +// TODO: Support big-endian architectures. static llvm::Optional<std::pair<uint64_t, ValueObjectSP>> ExtractLibcxxStringInfo(ValueObject &valobj) { - ValueObjectSP D(valobj.GetChildAtIndexPath({0, 0, 0, 0})); - if (!D) + ValueObjectSP dataval_sp(valobj.GetChildAtIndexPath({0, 0, 0, 0})); + if (!dataval_sp) + return {}; + if (!dataval_sp->GetError().Success()) return {}; ValueObjectSP layout_decider( - D->GetChildAtIndexPath(llvm::ArrayRef<size_t>({0, 0}))); + dataval_sp->GetChildAtIndexPath(llvm::ArrayRef<size_t>({0, 0}))); // this child should exist if (!layout_decider) @@ -572,27 +575,59 @@ ExtractLibcxxStringInfo(ValueObject &valobj) { ConstString g_size_name("__size_"); bool short_mode = false; // this means the string is in short-mode and the // data is stored inline + bool using_bitmasks = true; // Whether the class uses bitmasks for the mode + // flag (pre-D123580). + uint64_t size; LibcxxStringLayoutMode layout = (layout_decider->GetName() == g_data_name) ? eLibcxxStringLayoutModeDSC : eLibcxxStringLayoutModeCSD; uint64_t size_mode_value = 0; - if (layout == eLibcxxStringLayoutModeDSC) { - ValueObjectSP size_mode(D->GetChildAtIndexPath({1, 1, 0})); - if (!size_mode) - return {}; + ValueObjectSP short_sp(dataval_sp->GetChildAtIndex(1, true)); + if (!short_sp) + return {}; + + ValueObjectSP short_fields_sp; + ValueObjectSP is_long = + short_sp->GetChildMemberWithName(ConstString("__is_long_"), true); + if (is_long) { + short_fields_sp = short_sp; + } else { + // After D128285, we need to access the `__is_long_` and `__size_` fields + // from a packed anonymous struct + short_fields_sp = short_sp->GetChildAtIndex(0, true); + is_long = short_sp->GetChildMemberWithName(ConstString("__is_long_"), true); + } - if (size_mode->GetName() != g_size_name) { - // we are hitting the padding structure, move along - size_mode = D->GetChildAtIndexPath({1, 1, 1}); - if (!size_mode) - return {}; + if (is_long) { + using_bitmasks = false; + short_mode = !is_long->GetValueAsUnsigned(/*fail_value=*/0); + if (ValueObjectSP size_member = + dataval_sp->GetChildAtNamePath({ConstString("__s"), ConstString("__size_")})) + size = size_member->GetValueAsUnsigned(/*fail_value=*/0); + else + return {}; + } else if (layout == eLibcxxStringLayoutModeDSC) { + llvm::SmallVector<size_t, 3> size_mode_locations[] = { + {1, 2}, // Post-c3d0205ee771 layout. This was in use for only a brief + // period, so we can delete it if it becomes a burden. + {1, 1, 0}, + {1, 1, 1}, + }; + ValueObjectSP size_mode; + for (llvm::ArrayRef<size_t> loc : size_mode_locations) { + size_mode = dataval_sp->GetChildAtIndexPath(loc); + if (size_mode && size_mode->GetName() == g_size_name) + break; } + if (!size_mode) + return {}; + size_mode_value = (size_mode->GetValueAsUnsigned(0)); short_mode = ((size_mode_value & 0x80) == 0); } else { - ValueObjectSP size_mode(D->GetChildAtIndexPath({1, 0, 0})); + ValueObjectSP size_mode(dataval_sp->GetChildAtIndexPath({1, 0, 0})); if (!size_mode) return {}; @@ -601,14 +636,12 @@ ExtractLibcxxStringInfo(ValueObject &valobj) { } if (short_mode) { - ValueObjectSP s(D->GetChildAtIndex(1, true)); - if (!s) - return {}; - ValueObjectSP location_sp = s->GetChildAtIndex( - (layout == eLibcxxStringLayoutModeDSC) ? 0 : 1, true); - const uint64_t size = (layout == eLibcxxStringLayoutModeDSC) - ? size_mode_value - : ((size_mode_value >> 1) % 256); + ValueObjectSP location_sp = + short_sp->GetChildMemberWithName(g_data_name, true); + if (using_bitmasks) + size = (layout == eLibcxxStringLayoutModeDSC) + ? size_mode_value + : ((size_mode_value >> 1) % 256); // When the small-string optimization takes place, the data must fit in the // inline string buffer (23 bytes on x86_64/Darwin). If it doesn't, it's @@ -623,22 +656,31 @@ ExtractLibcxxStringInfo(ValueObject &valobj) { return std::make_pair(size, location_sp); } - ValueObjectSP l(D->GetChildAtIndex(0, true)); + ValueObjectSP l(dataval_sp->GetChildAtIndex(0, true)); if (!l) return {}; + // we can use the layout_decider object as the data pointer - ValueObjectSP location_sp = (layout == eLibcxxStringLayoutModeDSC) - ? layout_decider - : l->GetChildAtIndex(2, true); - ValueObjectSP size_vo(l->GetChildAtIndex(1, true)); - const unsigned capacity_index = - (layout == eLibcxxStringLayoutModeDSC) ? 2 : 0; - ValueObjectSP capacity_vo(l->GetChildAtIndex(capacity_index, true)); + ValueObjectSP location_sp = + l->GetChildMemberWithName(ConstString("__data_"), /*can_create=*/true); + ValueObjectSP size_vo = + l->GetChildMemberWithName(ConstString("__size_"), /*can_create=*/true); + ValueObjectSP capacity_vo = + l->GetChildMemberWithName(ConstString("__cap_"), /*can_create=*/true); + if (!capacity_vo) { + // After D128285, we need to access the `__cap_` field from a packed + // anonymous struct + if (ValueObjectSP packed_fields_sp = l->GetChildAtIndex(0, true)) { + ValueObjectSP capacity_vo = packed_fields_sp->GetChildMemberWithName( + ConstString("__cap_"), /*can_create=*/true); + } + } if (!size_vo || !location_sp || !capacity_vo) return {}; - const uint64_t size = size_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET); - const uint64_t capacity = - capacity_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET); + size = size_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET); + uint64_t capacity = capacity_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET); + if (!using_bitmasks && layout == eLibcxxStringLayoutModeCSD) + capacity *= 2; if (size == LLDB_INVALID_OFFSET || capacity == LLDB_INVALID_OFFSET || capacity < size) return {}; 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 0f166ae24912..b4e789e65b51 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h @@ -74,6 +74,10 @@ LibcxxVectorBoolSyntheticFrontEndCreator(CXXSyntheticChildren *, bool LibcxxContainerSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options); +/// Formatter for libc++ std::span<>. +bool LibcxxSpanSummaryProvider(ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &options); + class LibCxxMapIteratorSyntheticFrontEnd : public SyntheticChildrenFrontEnd { public: LibCxxMapIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); @@ -193,6 +197,10 @@ SyntheticChildrenFrontEnd * LibcxxVariantFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp); +SyntheticChildrenFrontEnd * +LibcxxStdSpanSyntheticFrontEndCreator(CXXSyntheticChildren *, + lldb::ValueObjectSP); + } // namespace formatters } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp index 45d4322e93d7..4eec79a27840 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp @@ -102,14 +102,14 @@ public: size_t GetIndexOfChildWithName(ConstString name) override; private: - ValueObject *m_real_child; + ValueObject *m_real_child = nullptr; }; } // namespace formatters } // namespace lldb_private lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd:: LibcxxStdAtomicSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) - : SyntheticChildrenFrontEnd(*valobj_sp), m_real_child(nullptr) {} + : SyntheticChildrenFrontEnd(*valobj_sp) {} bool lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::Update() { ValueObjectSP atomic_value = GetLibCxxAtomicValue(m_backend); diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp index 65e88d114fcc..d3be56e3f3c8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp @@ -36,18 +36,17 @@ public: size_t GetIndexOfChildWithName(ConstString name) override; private: - ValueObject *m_start; + ValueObject *m_start = nullptr; CompilerType m_element_type; - uint32_t m_element_size; - size_t m_num_elements; + uint32_t m_element_size = 0; + size_t m_num_elements = 0; }; } // namespace formatters } // namespace lldb_private lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd:: LibcxxInitializerListSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) - : SyntheticChildrenFrontEnd(*valobj_sp), m_start(nullptr), m_element_type(), - m_element_size(0), m_num_elements(0) { + : SyntheticChildrenFrontEnd(*valobj_sp), m_element_type() { if (valobj_sp) Update(); } @@ -61,9 +60,9 @@ lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd:: size_t lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd:: CalculateNumChildren() { - static ConstString g___size_("__size_"); + static ConstString g_size_("__size_"); m_num_elements = 0; - ValueObjectSP size_sp(m_backend.GetChildMemberWithName(g___size_, true)); + ValueObjectSP size_sp(m_backend.GetChildMemberWithName(g_size_, true)); if (size_sp) m_num_elements = size_sp->GetValueAsUnsigned(0); return m_num_elements; @@ -85,7 +84,7 @@ lldb::ValueObjectSP lldb_private::formatters:: bool lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd:: Update() { - static ConstString g___begin_("__begin_"); + static ConstString g_begin_("__begin_"); m_start = nullptr; m_num_elements = 0; @@ -96,7 +95,7 @@ bool lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd:: if (llvm::Optional<uint64_t> size = m_element_type.GetByteSize(nullptr)) { m_element_size = *size; // Store raw pointers or end up with a circular dependency. - m_start = m_backend.GetChildMemberWithName(g___begin_, true).get(); + m_start = m_backend.GetChildMemberWithName(g_begin_, true).get(); } return false; 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 47c6634ed65e..9f5624de4e63 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp @@ -158,8 +158,8 @@ public: bool Update() override; private: - lldb::addr_t m_node_address; - ValueObject *m_tail; + lldb::addr_t m_node_address = 0; + ValueObject *m_tail = nullptr; }; } // end anonymous namespace @@ -308,7 +308,7 @@ bool ForwardListFrontEnd::Update() { } ListFrontEnd::ListFrontEnd(lldb::ValueObjectSP valobj_sp) - : AbstractListFrontEnd(*valobj_sp), m_node_address(), m_tail(nullptr) { + : AbstractListFrontEnd(*valobj_sp) { if (valobj_sp) Update(); } 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 25c2bfd9387b..4aae524e3701 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp @@ -192,11 +192,11 @@ private: void GetValueOffset(const lldb::ValueObjectSP &node); - ValueObject *m_tree; - ValueObject *m_root_node; + ValueObject *m_tree = nullptr; + ValueObject *m_root_node = nullptr; CompilerType m_element_type; - uint32_t m_skip_size; - size_t m_count; + uint32_t m_skip_size = UINT32_MAX; + size_t m_count = UINT32_MAX; std::map<size_t, MapIterator> m_iterators; }; } // namespace formatters @@ -204,36 +204,34 @@ private: lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd:: LibcxxStdMapSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) - : SyntheticChildrenFrontEnd(*valobj_sp), m_tree(nullptr), - m_root_node(nullptr), m_element_type(), m_skip_size(UINT32_MAX), - m_count(UINT32_MAX), m_iterators() { + : SyntheticChildrenFrontEnd(*valobj_sp), m_element_type(), m_iterators() { if (valobj_sp) Update(); } size_t lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd:: CalculateNumChildren() { - static ConstString g___pair3_("__pair3_"); - static ConstString g___first_("__first_"); - static ConstString g___value_("__value_"); + static ConstString g_pair3_("__pair3_"); + static ConstString g_first_("__first_"); + static ConstString g_value_("__value_"); if (m_count != UINT32_MAX) return m_count; if (m_tree == nullptr) return 0; - ValueObjectSP m_item(m_tree->GetChildMemberWithName(g___pair3_, true)); + ValueObjectSP m_item(m_tree->GetChildMemberWithName(g_pair3_, true)); if (!m_item) return 0; switch (m_item->GetCompilerType().GetNumDirectBaseClasses()) { case 1: // Assume a pre llvm r300140 __compressed_pair implementation: - m_item = m_item->GetChildMemberWithName(g___first_, true); + m_item = m_item->GetChildMemberWithName(g_first_, true); break; case 2: { // Assume a post llvm r300140 __compressed_pair implementation: ValueObjectSP first_elem_parent = m_item->GetChildAtIndex(0, true); - m_item = first_elem_parent->GetChildMemberWithName(g___value_, true); + m_item = first_elem_parent->GetChildMemberWithName(g_value_, true); break; } default: @@ -247,7 +245,7 @@ size_t lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd:: } bool lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetDataType() { - static ConstString g___value_("__value_"); + static ConstString g_value_("__value_"); static ConstString g_tree_("__tree_"); static ConstString g_pair3("__pair3_"); @@ -259,7 +257,7 @@ bool lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetDataType() { deref = m_root_node->Dereference(error); if (!deref || error.Fail()) return false; - deref = deref->GetChildMemberWithName(g___value_, true); + deref = deref->GetChildMemberWithName(g_value_, true); if (deref) { m_element_type = deref->GetCompilerType(); return true; @@ -330,9 +328,9 @@ void lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset( lldb::ValueObjectSP lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex( size_t idx) { - static ConstString g___cc("__cc"); - static ConstString g___nc("__nc"); - static ConstString g___value_("__value_"); + static ConstString g_cc("__cc"); + static ConstString g_nc("__nc"); + static ConstString g_value_("__value_"); if (idx >= CalculateNumChildren()) return lldb::ValueObjectSP(); @@ -367,7 +365,7 @@ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex( return lldb::ValueObjectSP(); } GetValueOffset(iterated_sp); - auto child_sp = iterated_sp->GetChildMemberWithName(g___value_, true); + auto child_sp = iterated_sp->GetChildMemberWithName(g_value_, true); if (child_sp) iterated_sp = child_sp; else @@ -416,15 +414,15 @@ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex( switch (potential_child_sp->GetNumChildren()) { case 1: { auto child0_sp = potential_child_sp->GetChildAtIndex(0, true); - if (child0_sp && child0_sp->GetName() == g___cc) + if (child0_sp && child0_sp->GetName() == g_cc) potential_child_sp = child0_sp->Clone(ConstString(name.GetString())); break; } case 2: { auto child0_sp = potential_child_sp->GetChildAtIndex(0, true); auto child1_sp = potential_child_sp->GetChildAtIndex(1, true); - if (child0_sp && child0_sp->GetName() == g___cc && child1_sp && - child1_sp->GetName() == g___nc) + if (child0_sp && child0_sp->GetName() == g_cc && child1_sp && + child1_sp->GetName() == g_nc) potential_child_sp = child0_sp->Clone(ConstString(name.GetString())); break; } @@ -435,15 +433,15 @@ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex( } bool lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::Update() { - static ConstString g___tree_("__tree_"); - static ConstString g___begin_node_("__begin_node_"); + static ConstString g_tree_("__tree_"); + static ConstString g_begin_node_("__begin_node_"); m_count = UINT32_MAX; m_tree = m_root_node = nullptr; m_iterators.clear(); - m_tree = m_backend.GetChildMemberWithName(g___tree_, true).get(); + m_tree = m_backend.GetChildMemberWithName(g_tree_, true).get(); if (!m_tree) return false; - m_root_node = m_tree->GetChildMemberWithName(g___begin_node_, true).get(); + m_root_node = m_tree->GetChildMemberWithName(g_begin_node_, true).get(); return false; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxSpan.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxSpan.cpp new file mode 100644 index 000000000000..0379ba2d85ad --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxSpan.cpp @@ -0,0 +1,151 @@ +//===-- LibCxxSpan.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 "LibCxx.h" + +#include "lldb/Core/ValueObject.h" +#include "lldb/DataFormatters/FormattersHelpers.h" +#include "lldb/Utility/ConstString.h" +#include "llvm/ADT/APSInt.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::formatters; + +namespace lldb_private { +namespace formatters { + +class LibcxxStdSpanSyntheticFrontEnd : public SyntheticChildrenFrontEnd { +public: + LibcxxStdSpanSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); + + ~LibcxxStdSpanSyntheticFrontEnd() override = default; + + size_t CalculateNumChildren() override; + + lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; + + /// Determines properties of the std::span<> associated with this object + // + // std::span can either be instantiated with a compile-time known + // extent or a std::dynamic_extent (this is the default if only the + // type template argument is provided). The layout of std::span + // depends on whether the extent is dynamic or not. For static + // extents (e.g., std::span<int, 9>): + // + // (std::__1::span<const int, 9>) s = { + // __data = 0x000000016fdff494 + // } + // + // For dynamic extents, e.g., std::span<int>, the layout is: + // + // (std::__1::span<const int, 18446744073709551615>) s = { + // __data = 0x000000016fdff494 + // __size = 6 + // } + // + // This function checks for a '__size' member to determine the number + // of elements in the span. If no such member exists, we get the size + // from the only other place it can be: the template argument. + bool Update() override; + + bool MightHaveChildren() override; + + size_t GetIndexOfChildWithName(ConstString name) override; + +private: + ValueObject *m_start = nullptr; ///< First element of span. Held, not owned. + CompilerType m_element_type{}; ///< Type of span elements. + size_t m_num_elements = 0; ///< Number of elements in span. + uint32_t m_element_size = 0; ///< Size in bytes of each span element. +}; + +lldb_private::formatters::LibcxxStdSpanSyntheticFrontEnd:: + LibcxxStdSpanSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) + : SyntheticChildrenFrontEnd(*valobj_sp) { + if (valobj_sp) + Update(); +} + +size_t lldb_private::formatters::LibcxxStdSpanSyntheticFrontEnd:: + CalculateNumChildren() { + return m_num_elements; +} + +lldb::ValueObjectSP +lldb_private::formatters::LibcxxStdSpanSyntheticFrontEnd::GetChildAtIndex( + size_t idx) { + if (!m_start) + return {}; + + uint64_t offset = idx * m_element_size; + offset = offset + m_start->GetValueAsUnsigned(0); + StreamString name; + name.Printf("[%" PRIu64 "]", (uint64_t)idx); + return CreateValueObjectFromAddress(name.GetString(), offset, + m_backend.GetExecutionContextRef(), + m_element_type); +} + +bool lldb_private::formatters::LibcxxStdSpanSyntheticFrontEnd::Update() { + // Get element type. + ValueObjectSP data_type_finder_sp( + m_backend.GetChildMemberWithName(ConstString("__data"), true)); + if (!data_type_finder_sp) + return false; + + m_element_type = data_type_finder_sp->GetCompilerType().GetPointeeType(); + + // Get element size. + if (llvm::Optional<uint64_t> size = m_element_type.GetByteSize(nullptr)) { + m_element_size = *size; + + // Get data. + if (m_element_size > 0) { + m_start = data_type_finder_sp.get(); + } + + // Get number of elements. + if (auto size_sp = + m_backend.GetChildMemberWithName(ConstString("__size"), true)) { + m_num_elements = size_sp->GetValueAsUnsigned(0); + } else if (auto arg = + m_backend.GetCompilerType().GetIntegralTemplateArgument(1)) { + + m_num_elements = arg->value.getLimitedValue(); + } + } + + return true; +} + +bool lldb_private::formatters::LibcxxStdSpanSyntheticFrontEnd:: + MightHaveChildren() { + return true; +} + +size_t lldb_private::formatters::LibcxxStdSpanSyntheticFrontEnd:: + GetIndexOfChildWithName(ConstString name) { + if (!m_start) + return UINT32_MAX; + return ExtractIndexFromString(name.GetCString()); +} + +lldb_private::SyntheticChildrenFrontEnd * +LibcxxStdSpanSyntheticFrontEndCreator(CXXSyntheticChildren *, + lldb::ValueObjectSP valobj_sp) { + if (!valobj_sp) + return nullptr; + CompilerType type = valobj_sp->GetCompilerType(); + if (!type.IsValid() || type.GetNumTemplateArguments() != 2) + return nullptr; + return new LibcxxStdSpanSyntheticFrontEnd(valobj_sp); +} + +} // namespace formatters +} // namespace lldb_private diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp index 57c5ba87c397..85c04ea728f5 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp @@ -44,9 +44,9 @@ public: private: CompilerType m_element_type; CompilerType m_node_type; - ValueObject *m_tree; - size_t m_num_elements; - ValueObject *m_next_element; + ValueObject *m_tree = nullptr; + size_t m_num_elements = 0; + ValueObject *m_next_element = nullptr; std::vector<std::pair<ValueObject *, uint64_t>> m_elements_cache; }; } // namespace formatters @@ -54,8 +54,8 @@ private: lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd:: LibcxxStdUnorderedMapSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) - : SyntheticChildrenFrontEnd(*valobj_sp), m_element_type(), m_tree(nullptr), - m_num_elements(0), m_next_element(nullptr), m_elements_cache() { + : SyntheticChildrenFrontEnd(*valobj_sp), m_element_type(), + m_elements_cache() { if (valobj_sp) Update(); } diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp index 43f76b0df810..3e3727ac55a1 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp @@ -35,10 +35,10 @@ public: size_t GetIndexOfChildWithName(ConstString name) override; private: - ValueObject *m_start; - ValueObject *m_finish; + ValueObject *m_start = nullptr; + ValueObject *m_finish = nullptr; CompilerType m_element_type; - uint32_t m_element_size; + uint32_t m_element_size = 0; }; class LibcxxVectorBoolSyntheticFrontEnd : public SyntheticChildrenFrontEnd { @@ -58,8 +58,8 @@ public: private: CompilerType m_bool_type; ExecutionContextRef m_exe_ctx_ref; - uint64_t m_count; - lldb::addr_t m_base_data_address; + uint64_t m_count = 0; + lldb::addr_t m_base_data_address = 0; std::map<size_t, lldb::ValueObjectSP> m_children; }; @@ -68,8 +68,7 @@ private: lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd:: LibcxxStdVectorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) - : SyntheticChildrenFrontEnd(*valobj_sp), m_start(nullptr), - m_finish(nullptr), m_element_type(), m_element_size(0) { + : SyntheticChildrenFrontEnd(*valobj_sp), m_element_type() { if (valobj_sp) Update(); } @@ -173,7 +172,7 @@ size_t lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd:: lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd:: LibcxxVectorBoolSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) : SyntheticChildrenFrontEnd(*valobj_sp), m_bool_type(), m_exe_ctx_ref(), - m_count(0), m_base_data_address(0), m_children() { + m_children() { if (valobj_sp) { Update(); m_bool_type = @@ -215,7 +214,7 @@ lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::GetChildAtIndex( llvm::Optional<uint64_t> size = m_bool_type.GetByteSize(nullptr); if (!size) return {}; - DataBufferSP buffer_sp(new DataBufferHeap(*size, 0)); + WritableDataBufferSP buffer_sp(new DataBufferHeap(*size, 0)); if (bit_set && buffer_sp && buffer_sp->GetBytes()) { // regardless of endianness, anything non-zero is true *(buffer_sp->GetBytes()) = 1; diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp index 9e248d162cd2..d8623641b03f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp @@ -53,7 +53,7 @@ public: private: ExecutionContextRef m_exe_ctx_ref; - lldb::addr_t m_pair_address; + lldb::addr_t m_pair_address = 0; CompilerType m_pair_type; lldb::ValueObjectSP m_pair_sp; }; @@ -77,8 +77,8 @@ public: LibstdcppMapIteratorSyntheticFrontEnd::LibstdcppMapIteratorSyntheticFrontEnd( lldb::ValueObjectSP valobj_sp) - : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_pair_address(0), - m_pair_type(), m_pair_sp() { + : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_pair_type(), + m_pair_sp() { if (valobj_sp) Update(); } diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/CF.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/CF.cpp index 2610468b17fd..fa2130e4b01e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/CF.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/CF.cpp @@ -74,10 +74,10 @@ bool lldb_private::formatters::CFBagSummaryProvider( if (descriptor->IsCFType()) { ConstString type_name(valobj.GetTypeName()); - static ConstString g___CFBag("__CFBag"); + static ConstString g_CFBag("__CFBag"); static ConstString g_conststruct__CFBag("const struct __CFBag"); - if (type_name == g___CFBag || type_name == g_conststruct__CFBag) { + if (type_name == g_CFBag || type_name == g_conststruct__CFBag) { if (valobj.IsPointerType()) is_type_ok = true; } @@ -158,7 +158,7 @@ bool lldb_private::formatters::CFBitVectorSummaryProvider( // make sure we do not try to read huge amounts of data if (num_bytes > 1024) num_bytes = 1024; - DataBufferSP buffer_sp(new DataBufferHeap(num_bytes, 0)); + WritableDataBufferSP buffer_sp(new DataBufferHeap(num_bytes, 0)); num_bytes = process_sp->ReadMemory(data_ptr, buffer_sp->GetBytes(), num_bytes, error); if (error.Fail() || num_bytes == 0) @@ -257,12 +257,12 @@ bool lldb_private::formatters::CFBinaryHeapSummaryProvider( if (descriptor->IsCFType()) { ConstString type_name(valobj.GetTypeName()); - static ConstString g___CFBinaryHeap("__CFBinaryHeap"); + static ConstString g_CFBinaryHeap("__CFBinaryHeap"); static ConstString g_conststruct__CFBinaryHeap( "const struct __CFBinaryHeap"); static ConstString g_CFBinaryHeapRef("CFBinaryHeapRef"); - if (type_name == g___CFBinaryHeap || + if (type_name == g_CFBinaryHeap || type_name == g_conststruct__CFBinaryHeap || type_name == g_CFBinaryHeapRef) { if (valobj.IsPointerType()) 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 0d7cd6791b04..14cd64fe4b5e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/Cocoa.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/Cocoa.cpp @@ -25,6 +25,7 @@ #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" @@ -426,7 +427,7 @@ bool lldb_private::formatters::NSNumberSummaryProvider( if (!process_sp) return false; - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS); + Log *log = GetLog(LLDBLog::DataFormatters); ObjCLanguageRuntime *runtime = ObjCLanguageRuntime::Get(*process_sp); if (!runtime) @@ -918,8 +919,8 @@ bool lldb_private::formatters::NSDateSummaryProvider( ConstString class_name = descriptor->GetClassName(); static const ConstString g_NSDate("NSDate"); - static const ConstString g___NSDate("__NSDate"); - static const ConstString g___NSTaggedDate("__NSTaggedDate"); + static const ConstString g_dunder_NSDate("__NSDate"); + static const ConstString g_NSTaggedDate("__NSTaggedDate"); static const ConstString g_NSCalendarDate("NSCalendarDate"); static const ConstString g_NSConstantDate("NSConstantDate"); @@ -927,8 +928,8 @@ bool lldb_private::formatters::NSDateSummaryProvider( return false; uint64_t info_bits = 0, value_bits = 0; - if ((class_name == g_NSDate) || (class_name == g___NSDate) || - (class_name == g___NSTaggedDate) || (class_name == g_NSConstantDate)) { + if ((class_name == g_NSDate) || (class_name == g_dunder_NSDate) || + (class_name == g_NSTaggedDate) || (class_name == g_NSConstantDate)) { if (descriptor->GetTaggedPointerInfo(&info_bits, &value_bits)) { date_value_bits = ((value_bits << 8) | (info_bits << 4)); memcpy(&date_value, &date_value_bits, sizeof(date_value_bits)); @@ -966,7 +967,7 @@ bool lldb_private::formatters::NSDateSummaryProvider( } // Accomodate for the __NSTaggedDate format introduced in Foundation 1600. - if (class_name == g___NSTaggedDate) { + if (class_name == g_NSTaggedDate) { auto *runtime = llvm::dyn_cast_or_null<AppleObjCRuntime>( ObjCLanguageRuntime::Get(*process_sp)); if (runtime && runtime->GetFoundationVersion() >= 1600) diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSArray.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSArray.cpp index f18b59fb11ff..adda04e18629 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSArray.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSArray.cpp @@ -70,7 +70,7 @@ protected: virtual uint64_t GetSize() = 0; ExecutionContextRef m_exe_ctx_ref; - uint8_t m_ptr_size; + uint8_t m_ptr_size = 8; CompilerType m_id_type; }; @@ -226,7 +226,7 @@ public: private: ExecutionContextRef m_exe_ctx_ref; - uint8_t m_ptr_size; + uint8_t m_ptr_size = 8; D32 *m_data_32; D64 *m_data_64; @@ -459,10 +459,9 @@ bool lldb_private::formatters::NSArraySummaryProvider( return true; } -lldb_private::formatters::NSArrayMSyntheticFrontEndBase::NSArrayMSyntheticFrontEndBase( - lldb::ValueObjectSP valobj_sp) - : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8), - m_id_type() { +lldb_private::formatters::NSArrayMSyntheticFrontEndBase:: + NSArrayMSyntheticFrontEndBase(lldb::ValueObjectSP valobj_sp) + : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_id_type() { if (valobj_sp) { auto *clang_ast_context = ScratchTypeSystemClang::GetForTarget( *valobj_sp->GetExecutionContextRef().GetTargetSP()); @@ -605,9 +604,8 @@ lldb_private::formatters:: template <typename D32, typename D64, bool Inline> lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>:: - GenericNSArrayISyntheticFrontEnd( - lldb::ValueObjectSP valobj_sp) - : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8), + GenericNSArrayISyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) + : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_data_32(nullptr), m_data_64(nullptr) { if (valobj_sp) { CompilerType type = valobj_sp->GetCompilerType(); 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 73c40ba959a6..2c6998451ad6 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp @@ -70,16 +70,16 @@ static CompilerType GetLLDBNSPairType(TargetSP target_sp) { ScratchTypeSystemClang::GetForTarget(*target_sp); if (target_ast_context) { - ConstString g___lldb_autogen_nspair("__lldb_autogen_nspair"); + ConstString g_lldb_autogen_nspair("__lldb_autogen_nspair"); compiler_type = target_ast_context->GetTypeForIdentifier<clang::CXXRecordDecl>( - g___lldb_autogen_nspair); + g_lldb_autogen_nspair); if (!compiler_type) { compiler_type = target_ast_context->CreateRecordType( nullptr, OptionalClangModuleID(), lldb::eAccessPublic, - g___lldb_autogen_nspair.GetCString(), clang::TTK_Struct, + g_lldb_autogen_nspair.GetCString(), clang::TTK_Struct, lldb::eLanguageTypeC); if (compiler_type) { @@ -133,10 +133,10 @@ private: }; ExecutionContextRef m_exe_ctx_ref; - uint8_t m_ptr_size; - lldb::ByteOrder m_order; - DataDescriptor_32 *m_data_32; - DataDescriptor_64 *m_data_64; + uint8_t m_ptr_size = 8; + lldb::ByteOrder m_order = lldb::eByteOrderInvalid; + DataDescriptor_32 *m_data_32 = nullptr; + DataDescriptor_64 *m_data_64 = nullptr; lldb::addr_t m_data_ptr; CompilerType m_pair_type; std::vector<DictionaryItemDescriptor> m_children; @@ -196,8 +196,8 @@ private: }; ExecutionContextRef m_exe_ctx_ref; - uint8_t m_ptr_size; - lldb::ByteOrder m_order; + uint8_t m_ptr_size = 8; + lldb::ByteOrder m_order = lldb::eByteOrderInvalid; CFBasicHash m_hashtable; @@ -250,8 +250,8 @@ private: }; ExecutionContextRef m_exe_ctx_ref; - uint8_t m_ptr_size; - lldb::ByteOrder m_order; + uint8_t m_ptr_size = 8; + lldb::ByteOrder m_order = lldb::eByteOrderInvalid; D32 *m_data_32; D64 *m_data_64; CompilerType m_pair_type; @@ -301,10 +301,10 @@ namespace Foundation1100 { }; ExecutionContextRef m_exe_ctx_ref; - uint8_t m_ptr_size; - lldb::ByteOrder m_order; - DataDescriptor_32 *m_data_32; - DataDescriptor_64 *m_data_64; + uint8_t m_ptr_size = 8; + lldb::ByteOrder m_order = lldb::eByteOrderInvalid; + DataDescriptor_32 *m_data_32 = nullptr; + DataDescriptor_64 *m_data_64 = nullptr; CompilerType m_pair_type; std::vector<DictionaryItemDescriptor> m_children; }; @@ -592,9 +592,7 @@ lldb_private::formatters::NSDictionarySyntheticFrontEndCreator( lldb_private::formatters::NSDictionaryISyntheticFrontEnd:: NSDictionaryISyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) - : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8), - m_order(lldb::eByteOrderInvalid), m_data_32(nullptr), m_data_64(nullptr), - m_pair_type() {} + : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_pair_type() {} lldb_private::formatters::NSDictionaryISyntheticFrontEnd:: ~NSDictionaryISyntheticFrontEnd() { @@ -715,7 +713,7 @@ lldb_private::formatters::NSDictionaryISyntheticFrontEnd::GetChildAtIndex( if (!m_pair_type.IsValid()) return ValueObjectSP(); - DataBufferSP buffer_sp(new DataBufferHeap(2 * m_ptr_size, 0)); + WritableDataBufferSP buffer_sp(new DataBufferHeap(2 * m_ptr_size, 0)); if (m_ptr_size == 8) { uint64_t *data_ptr = (uint64_t *)buffer_sp->GetBytes(); @@ -738,8 +736,8 @@ lldb_private::formatters::NSDictionaryISyntheticFrontEnd::GetChildAtIndex( lldb_private::formatters::NSCFDictionarySyntheticFrontEnd:: NSCFDictionarySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) - : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8), - m_order(lldb::eByteOrderInvalid), m_hashtable(), m_pair_type() {} + : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_hashtable(), + m_pair_type() {} size_t lldb_private::formatters::NSCFDictionarySyntheticFrontEnd:: GetIndexOfChildWithName(ConstString name) { @@ -842,7 +840,7 @@ lldb_private::formatters::NSCFDictionarySyntheticFrontEnd::GetChildAtIndex( if (!m_pair_type.IsValid()) return ValueObjectSP(); - DataBufferSP buffer_sp(new DataBufferHeap(2 * m_ptr_size, 0)); + WritableDataBufferSP buffer_sp(new DataBufferHeap(2 * m_ptr_size, 0)); switch (m_ptr_size) { case 0: // architecture has no clue - fail @@ -963,7 +961,7 @@ lldb::ValueObjectSP lldb_private::formatters:: if (!m_pair_type.IsValid()) return ValueObjectSP(); - DataBufferSP buffer_sp(new DataBufferHeap(2 * m_ptr_size, 0)); + WritableDataBufferSP buffer_sp(new DataBufferHeap(2 * m_ptr_size, 0)); if (m_ptr_size == 8) { uint64_t *data_ptr = (uint64_t *)buffer_sp->GetBytes(); @@ -1040,7 +1038,7 @@ lldb_private::formatters::NSDictionary1SyntheticFrontEnd::GetChildAtIndex( auto pair_type = GetLLDBNSPairType(process_sp->GetTarget().shared_from_this()); - DataBufferSP buffer_sp(new DataBufferHeap(2 * ptr_size, 0)); + WritableDataBufferSP buffer_sp(new DataBufferHeap(2 * ptr_size, 0)); if (ptr_size == 8) { uint64_t *data_ptr = (uint64_t *)buffer_sp->GetBytes(); @@ -1060,11 +1058,10 @@ lldb_private::formatters::NSDictionary1SyntheticFrontEnd::GetChildAtIndex( } template <typename D32, typename D64> -lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>:: +lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32, D64>:: GenericNSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) - : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8), - m_order(lldb::eByteOrderInvalid), m_data_32(nullptr), m_data_64(nullptr), - m_pair_type() {} + : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), + m_data_32(nullptr), m_data_64(nullptr), m_pair_type() {} template <typename D32, typename D64> lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>:: @@ -1206,7 +1203,7 @@ lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd< if (!m_pair_type.IsValid()) return ValueObjectSP(); - DataBufferSP buffer_sp(new DataBufferHeap(2 * m_ptr_size, 0)); + WritableDataBufferSP buffer_sp(new DataBufferHeap(2 * m_ptr_size, 0)); if (m_ptr_size == 8) { uint64_t *data_ptr = (uint64_t *)buffer_sp->GetBytes(); @@ -1227,12 +1224,9 @@ lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd< return dict_item.valobj_sp; } -lldb_private::formatters::Foundation1100:: - NSDictionaryMSyntheticFrontEnd:: +lldb_private::formatters::Foundation1100::NSDictionaryMSyntheticFrontEnd:: NSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) - : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8), - m_order(lldb::eByteOrderInvalid), m_data_32(nullptr), m_data_64(nullptr), - m_pair_type() {} + : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_pair_type() {} lldb_private::formatters::Foundation1100:: NSDictionaryMSyntheticFrontEnd::~NSDictionaryMSyntheticFrontEnd() { @@ -1363,7 +1357,7 @@ lldb_private::formatters::Foundation1100:: if (!m_pair_type.IsValid()) return ValueObjectSP(); - DataBufferSP buffer_sp(new DataBufferHeap(2 * m_ptr_size, 0)); + WritableDataBufferSP buffer_sp(new DataBufferHeap(2 * m_ptr_size, 0)); if (m_ptr_size == 8) { uint64_t *data_ptr = (uint64_t *)buffer_sp->GetBytes(); diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSError.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSError.cpp index 4ffa072f9f53..937c7204d3c4 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSError.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSError.cpp @@ -164,8 +164,8 @@ public: bool MightHaveChildren() override { return true; } size_t GetIndexOfChildWithName(ConstString name) override { - static ConstString g___userInfo("_userInfo"); - if (name == g___userInfo) + static ConstString g_userInfo("_userInfo"); + if (name == g_userInfo) return 0; return UINT32_MAX; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSException.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSException.cpp index 7360abb8fdd2..cb6b712a908b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSException.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSException.cpp @@ -156,14 +156,14 @@ public: // NSString *reason; // NSDictionary *userInfo; // id reserved; - static ConstString g___name("name"); - static ConstString g___reason("reason"); - static ConstString g___userInfo("userInfo"); - static ConstString g___reserved("reserved"); - if (name == g___name) return 0; - if (name == g___reason) return 1; - if (name == g___userInfo) return 2; - if (name == g___reserved) return 3; + static ConstString g_name("name"); + static ConstString g_reason("reason"); + static ConstString g_userInfo("userInfo"); + static ConstString g_reserved("reserved"); + if (name == g_name) return 0; + if (name == g_reason) return 1; + if (name == g_userInfo) return 2; + if (name == g_reserved) return 3; return UINT32_MAX; } 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 068bca9e7b94..429633e5e6b8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp @@ -33,7 +33,7 @@ class NSIndexPathSyntheticFrontEnd : public SyntheticChildrenFrontEnd { public: NSIndexPathSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) : SyntheticChildrenFrontEnd(*valobj_sp.get()), m_descriptor_sp(nullptr), - m_impl(), m_ptr_size(0), m_uint_star_type() { + m_impl(), m_uint_star_type() { m_ptr_size = m_backend.GetTargetSP()->GetArchitecture().GetAddressByteSize(); } @@ -282,9 +282,17 @@ protected: }; void Clear() { + switch (m_mode) { + case Mode::Inlined: + m_inlined.Clear(); + break; + case Mode::Outsourced: + m_outsourced.Clear(); + break; + case Mode::Invalid: + break; + } m_mode = Mode::Invalid; - m_inlined.Clear(); - m_outsourced.Clear(); } Impl() {} @@ -292,7 +300,7 @@ protected: Mode m_mode = Mode::Invalid; } m_impl; - uint32_t m_ptr_size; + uint32_t m_ptr_size = 0; CompilerType m_uint_star_type; }; 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 43ef7b694bbe..0a6b445d97c8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSSet.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSSet.cpp @@ -73,9 +73,9 @@ private: }; ExecutionContextRef m_exe_ctx_ref; - uint8_t m_ptr_size; - DataDescriptor_32 *m_data_32; - DataDescriptor_64 *m_data_64; + uint8_t m_ptr_size = 8; + DataDescriptor_32 *m_data_32 = nullptr; + DataDescriptor_64 *m_data_64 = nullptr; lldb::addr_t m_data_ptr; std::vector<SetItemDescriptor> m_children; }; @@ -101,8 +101,8 @@ private: }; ExecutionContextRef m_exe_ctx_ref; - uint8_t m_ptr_size; - lldb::ByteOrder m_order; + uint8_t m_ptr_size = 8; + lldb::ByteOrder m_order = lldb::eByteOrderInvalid; CFBasicHash m_hashtable; @@ -135,7 +135,7 @@ private: }; ExecutionContextRef m_exe_ctx_ref; - uint8_t m_ptr_size; + uint8_t m_ptr_size = 8; D32 *m_data_32; D64 *m_data_64; std::vector<SetItemDescriptor> m_children; @@ -401,8 +401,7 @@ lldb_private::formatters::NSSetSyntheticFrontEndCreator( lldb_private::formatters::NSSetISyntheticFrontEnd::NSSetISyntheticFrontEnd( lldb::ValueObjectSP valobj_sp) - : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8), - m_data_32(nullptr), m_data_64(nullptr) { + : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref() { if (valobj_sp) Update(); } @@ -546,8 +545,8 @@ lldb_private::formatters::NSSetISyntheticFrontEnd::GetChildAtIndex(size_t idx) { lldb_private::formatters::NSCFSetSyntheticFrontEnd::NSCFSetSyntheticFrontEnd( lldb::ValueObjectSP valobj_sp) - : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8), - m_order(lldb::eByteOrderInvalid), m_hashtable(), m_pair_type() {} + : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_hashtable(), + m_pair_type() {} size_t lldb_private::formatters::NSCFSetSyntheticFrontEnd::GetIndexOfChildWithName( @@ -636,7 +635,7 @@ lldb_private::formatters::NSCFSetSyntheticFrontEnd::GetChildAtIndex( SetItemDescriptor &set_item = m_children[idx]; if (!set_item.valobj_sp) { - DataBufferSP buffer_sp(new DataBufferHeap(m_ptr_size, 0)); + WritableDataBufferSP buffer_sp(new DataBufferHeap(m_ptr_size, 0)); switch (m_ptr_size) { case 0: // architecture has no clue - fail @@ -667,10 +666,9 @@ lldb_private::formatters::NSCFSetSyntheticFrontEnd::GetChildAtIndex( } template <typename D32, typename D64> -lldb_private::formatters:: - GenericNSSetMSyntheticFrontEnd<D32, D64>::GenericNSSetMSyntheticFrontEnd( - lldb::ValueObjectSP valobj_sp) - : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8), +lldb_private::formatters::GenericNSSetMSyntheticFrontEnd< + D32, D64>::GenericNSSetMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) + : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_data_32(nullptr), m_data_64(nullptr) { if (valobj_sp) Update(); 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 bed2a98067e6..0028a5141287 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp @@ -63,7 +63,7 @@ bool contains_lambda_identifier(llvm::StringRef &str_ref) { CPPLanguageRuntime::LibCppStdFunctionCallableInfo line_entry_helper(Target &target, const SymbolContext &sc, Symbol *symbol, llvm::StringRef first_template_param_sref, - bool has___invoke) { + bool has_invoke) { CPPLanguageRuntime::LibCppStdFunctionCallableInfo optional_info; @@ -78,7 +78,7 @@ line_entry_helper(Target &target, const SymbolContext &sc, Symbol *symbol, LineEntry line_entry; addr.CalculateSymbolContextLineEntry(line_entry); - if (contains_lambda_identifier(first_template_param_sref) || has___invoke) { + if (contains_lambda_identifier(first_template_param_sref) || has_invoke) { // Case 1 and 2 optional_info.callable_case = lldb_private::CPPLanguageRuntime:: LibCppStdFunctionCallableCase::Lambda; @@ -138,25 +138,25 @@ CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo( // we will obtain the name from this pointer. // 5) a free function. A pointer to the function will stored after the vtable // we will obtain the name from this pointer. - ValueObjectSP member__f_( + ValueObjectSP member_f_( valobj_sp->GetChildMemberWithName(ConstString("__f_"), true)); - if (member__f_) { - ValueObjectSP sub_member__f_( - member__f_->GetChildMemberWithName(ConstString("__f_"), true)); + if (member_f_) { + ValueObjectSP sub_member_f_( + member_f_->GetChildMemberWithName(ConstString("__f_"), true)); - if (sub_member__f_) - member__f_ = sub_member__f_; + if (sub_member_f_) + member_f_ = sub_member_f_; } - if (!member__f_) + if (!member_f_) return optional_info; - lldb::addr_t member__f_pointer_value = member__f_->GetValueAsUnsigned(0); + lldb::addr_t member_f_pointer_value = member_f_->GetValueAsUnsigned(0); - optional_info.member__f_pointer_value = member__f_pointer_value; + optional_info.member_f_pointer_value = member_f_pointer_value; - if (!member__f_pointer_value) + if (!member_f_pointer_value) return optional_info; ExecutionContext exe_ctx(valobj_sp->GetExecutionContextRef()); @@ -171,7 +171,7 @@ CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo( // First item pointed to by __f_ should be the pointer to the vtable for // a __base object. lldb::addr_t vtable_address = - process->ReadPointerFromMemory(member__f_pointer_value, status); + process->ReadPointerFromMemory(member_f_pointer_value, status); if (status.Fail()) return optional_info; @@ -182,7 +182,7 @@ CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo( if (status.Fail()) return optional_info; - lldb::addr_t address_after_vtable = member__f_pointer_value + address_size; + lldb::addr_t address_after_vtable = member_f_pointer_value + address_size; // As commented above we may not have a function pointer but if we do we will // need it. lldb::addr_t possible_function_address = @@ -257,7 +257,7 @@ CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo( } // These conditions are used several times to simplify statements later on. - bool has___invoke = + bool has_invoke = (symbol ? symbol->GetName().GetStringRef().contains("__invoke") : false); auto calculate_symbol_context_helper = [](auto &t, SymbolContextList &sc_list) { @@ -267,17 +267,17 @@ CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo( }; // Case 2 - if (has___invoke) { + if (has_invoke) { SymbolContextList scl; calculate_symbol_context_helper(symbol, scl); return line_entry_helper(target, scl[0], symbol, first_template_parameter, - has___invoke); + has_invoke); } // Case 4 or 5 if (symbol && !symbol->GetName().GetStringRef().startswith("vtable for") && - !contains_lambda_identifier(first_template_parameter) && !has___invoke) { + !contains_lambda_identifier(first_template_parameter) && !has_invoke) { optional_info.callable_case = LibCppStdFunctionCallableCase::FreeOrMemberFunction; optional_info.callable_address = function_address_resolved; @@ -307,7 +307,7 @@ CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo( if (!contains_lambda_identifier(name_to_use)) return optional_info; - if (vtable_cu && !has___invoke) { + if (vtable_cu && !has_invoke) { lldb::FunctionSP func_sp = vtable_cu->FindFunction([name_to_use](const FunctionSP &f) { auto name = f->GetName().GetStringRef(); @@ -328,7 +328,7 @@ CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo( // Case 1 or 3 if (scl.GetSize() >= 1) { optional_info = line_entry_helper(target, scl[0], symbol, - first_template_parameter, has___invoke); + first_template_parameter, has_invoke); } CallableLookupCache[func_to_match] = optional_info; diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h index 3f5b99351872..1be58b7bf9ea 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h @@ -32,7 +32,7 @@ public: Symbol callable_symbol; Address callable_address; LineEntry callable_line_entry; - lldb::addr_t member__f_pointer_value = 0u; + lldb::addr_t member_f_pointer_value = 0u; LibCppStdFunctionCallableCase callable_case = LibCppStdFunctionCallableCase::Invalid; }; 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 92f732fe6827..1595335cfe33 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 @@ -31,6 +31,7 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" @@ -76,8 +77,7 @@ TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress( const char *name = symbol->GetMangled().GetDemangledName().AsCString(); if (name && strstr(name, vtable_demangled_prefix) == name) { - Log *log( - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); + Log *log = GetLog(LLDBLog::Object); LLDB_LOGF(log, "0x%16.16" PRIx64 ": static-type = '%s' has vtable symbol '%s'\n", 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 162ccad3cdcd..438842db4eec 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 @@ -10,6 +10,7 @@ #include "lldb/Expression/FunctionCaller.h" #include "lldb/Target/ABI.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" using namespace lldb; @@ -77,6 +78,7 @@ bool ClassDescriptorV2::objc_class_t::Read(Process *process, if (ABISP abi_sp = process->GetABI()) { m_isa = abi_sp->FixCodeAddress(m_isa); m_superclass = abi_sp->FixCodeAddress(m_superclass); + m_data_ptr = abi_sp->FixCodeAddress(m_data_ptr); } return true; } @@ -542,7 +544,7 @@ void ClassDescriptorV2::iVarsStorage::fill(AppleObjCRuntimeV2 &runtime, if (m_filled) return; std::lock_guard<std::recursive_mutex> guard(m_mutex); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES)); + Log *log = GetLog(LLDBLog::Types); LLDB_LOGV(log, "class_name = {0}", descriptor.GetClassName()); m_filled = true; ObjCLanguageRuntime::EncodingToTypeSP encoding_to_type_sp( @@ -567,7 +569,7 @@ void ClassDescriptorV2::iVarsStorage::fill(AppleObjCRuntimeV2 &runtime, "name = {0}, encoding = {1}, offset_ptr = {2:x}, size = " "{3}, type_size = {4}", name, type, offset_ptr, size, - ivar_type.GetByteSize(nullptr).getValueOr(0)); + ivar_type.GetByteSize(nullptr).value_or(0)); Scalar offset_scalar; Status error; const int offset_ptr_size = 4; 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 af11109ae45d..5f3ae3b12975 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 @@ -14,6 +14,7 @@ #include "lldb/Core/Module.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "clang/AST/ASTContext.h" @@ -31,8 +32,8 @@ public: bool FindExternalVisibleDeclsByName(const clang::DeclContext *decl_ctx, clang::DeclarationName name) override { - Log *log(GetLogIfAllCategoriesSet( - LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel? + Log *log(GetLog( + LLDBLog::Expressions)); // FIXME - a more appropriate log channel? if (log) { LLDB_LOGF(log, @@ -68,8 +69,8 @@ public: void CompleteType(clang::TagDecl *tag_decl) override { - Log *log(GetLogIfAllCategoriesSet( - LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel? + Log *log(GetLog( + LLDBLog::Expressions)); // FIXME - a more appropriate log channel? LLDB_LOGF(log, "AppleObjCExternalASTSource::CompleteType on " @@ -84,8 +85,8 @@ public: void CompleteType(clang::ObjCInterfaceDecl *interface_decl) override { - Log *log(GetLogIfAllCategoriesSet( - LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel? + Log *log(GetLog( + LLDBLog::Expressions)); // FIXME - a more appropriate log channel? if (log) { LLDB_LOGF(log, @@ -180,7 +181,7 @@ AppleObjCDeclVendor::GetDeclForISA(ObjCLanguageRuntime::ObjCISA isa) { class ObjCRuntimeMethodType { public: - ObjCRuntimeMethodType(const char *types) : m_is_valid(false) { + ObjCRuntimeMethodType(const char *types) { const char *cursor = types; enum ParserState { Start = 0, InType, InPos } state = Start; const char *type = nullptr; @@ -390,12 +391,12 @@ private: typedef std::vector<std::string> TypeVector; TypeVector m_type_vector; - bool m_is_valid; + bool m_is_valid = false; }; bool AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl) { - Log *log(GetLogIfAllCategoriesSet( - LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel? + Log *log( + GetLog(LLDBLog::Expressions)); // FIXME - a more appropriate log channel? ClangASTMetadata *metadata = m_ast_ctx.GetMetadata(interface_decl); ObjCLanguageRuntime::ObjCISA objc_isa = 0; @@ -525,8 +526,8 @@ uint32_t AppleObjCDeclVendor::FindDecls(ConstString name, bool append, uint32_t max_matches, std::vector<CompilerDecl> &decls) { - Log *log(GetLogIfAllCategoriesSet( - LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel? + Log *log( + GetLog(LLDBLog::Expressions)); // FIXME - a more appropriate log channel? LLDB_LOGF(log, "AppleObjCDeclVendor::FindDecls ('%s', %s, %u, )", (const char *)name.AsCString(), append ? "true" : "false", 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 88e86c51fe44..dfa2d4c05126 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 @@ -31,6 +31,7 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" @@ -318,7 +319,7 @@ bool AppleObjCRuntime::AppleIsModuleObjCLibrary(const ModuleSP &module_sp) { // we use the version of Foundation to make assumptions about the ObjC runtime // on a target uint32_t AppleObjCRuntime::GetFoundationVersion() { - if (!m_Foundation_major.hasValue()) { + if (!m_Foundation_major) { const ModuleList &modules = m_process->GetTarget().GetImages(); for (uint32_t idx = 0; idx < modules.GetSize(); idx++) { lldb::ModuleSP module_sp = modules.GetModuleAtIndex(idx); @@ -332,7 +333,7 @@ uint32_t AppleObjCRuntime::GetFoundationVersion() { } return LLDB_INVALID_MODULE_VERSION; } else - return m_Foundation_major.getValue(); + return *m_Foundation_major; } void AppleObjCRuntime::GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true, @@ -504,7 +505,7 @@ ValueObjectSP AppleObjCRuntime::GetExceptionObjectForThread( /// GetBacktraceThreadFromException. LLVM_NODISCARD static ThreadSP FailExceptionParsing(llvm::StringRef msg) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + Log *log = GetLog(LLDBLog::Language); LLDB_LOG(log, "Failed getting backtrace from exception: {0}", msg); return ThreadSP(); } 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 609e8e9bc1b6..65f00f5e4d02 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 @@ -25,6 +25,7 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" @@ -221,7 +222,7 @@ void AppleObjCRuntimeV1::ClassDescriptorV1::Initialize( return; } - lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024, 0)); + lldb::WritableDataBufferSP buffer_sp(new DataBufferHeap(1024, 0)); size_t count = process_sp->ReadCStringFromMemory( name_ptr, (char *)buffer_sp->GetBytes(), 1024, error); @@ -232,7 +233,7 @@ void AppleObjCRuntimeV1::ClassDescriptorV1::Initialize( } if (count) - m_name = ConstString((char *)buffer_sp->GetBytes()); + m_name = ConstString(reinterpret_cast<const char *>(buffer_sp->GetBytes())); else m_name = ConstString(); @@ -318,7 +319,7 @@ void AppleObjCRuntimeV1::UpdateISAToDescriptorMapIfNeeded() { // map, whether it was successful or not. m_isa_to_descriptor_stop_id = process->GetStopID(); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); ProcessSP process_sp = process->shared_from_this(); 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 f2cf25f93eb2..1c2447b2bec5 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,21 +6,11 @@ // //===----------------------------------------------------------------------===// -#include <cstdint> - -#include <memory> -#include <string> -#include <vector> - -#include "clang/AST/ASTContext.h" -#include "clang/AST/DeclObjC.h" - -#include "lldb/Host/OptionParser.h" -#include "lldb/Symbol/CompilerType.h" -#include "lldb/lldb-enumerations.h" - +#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" + #include "lldb/Core/Debugger.h" +#include "lldb/Core/DebuggerEvents.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" @@ -29,11 +19,13 @@ #include "lldb/Expression/DiagnosticManager.h" #include "lldb/Expression/FunctionCaller.h" #include "lldb/Expression/UtilityFunction.h" +#include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandObject.h" #include "lldb/Interpreter/CommandObjectMultiword.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Interpreter/OptionValueBoolean.h" +#include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Symbol/TypeList.h" @@ -48,12 +40,14 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timer.h" +#include "lldb/lldb-enumerations.h" #include "AppleObjCClassDescriptorV2.h" #include "AppleObjCDeclVendor.h" @@ -64,9 +58,11 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/DeclObjC.h" #include "clang/Basic/TargetInfo.h" +#include "llvm/ADT/ScopeExit.h" -#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" - +#include <cstdint> +#include <memory> +#include <string> #include <vector> using namespace lldb; @@ -203,13 +199,13 @@ __lldb_apple_objc_v2_get_dynamic_class_info2(void *gdb_objc_realized_classes_ptr DEBUG_PRINTF ("count = %u\n", count); uint32_t idx = 0; - for (uint32_t i=0; i<=count; ++i) + 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) + if (!name_ptr) continue; const char *s = name_ptr; uint32_t h = 5381; @@ -233,6 +229,83 @@ __lldb_apple_objc_v2_get_dynamic_class_info2(void *gdb_objc_realized_classes_ptr } )"; +static const char *g_get_dynamic_class_info3_name = + "__lldb_apple_objc_v2_get_dynamic_class_info3"; + +static const char *g_get_dynamic_class_info3_body = R"( + +extern "C" { + int printf(const char * format, ...); + void free(void *ptr); + size_t objc_getRealizedClassList_trylock(Class *buffer, size_t len); + const char* objc_debug_class_getNameRaw(Class cls); + const char* class_getName(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_info3(void *gdb_objc_realized_classes_ptr, + void *class_infos_ptr, + uint32_t class_infos_byte_size, + void *class_buffer, + uint32_t class_buffer_len, + 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; + + Class *realized_class_list = (Class*)class_buffer; + + uint32_t count = objc_getRealizedClassList_trylock(realized_class_list, + class_buffer_len); + 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) { + class_getName(isa); // Realize name of lazy classes. + name_ptr = objc_debug_class_getNameRaw(isa); + } + if (!name_ptr) + 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; + } + + 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"( @@ -661,16 +734,21 @@ AppleObjCRuntimeV2::AppleObjCRuntimeV2(Process *process, 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_has_objc_getRealizedClassList_trylock(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_realized_class_generation_count(0) { + m_encoding_to_type_sp(), m_CFBoolean_values(), + m_realized_class_generation_count(0) { static const ConstString g_gdb_object_getClass("gdb_object_getClass"); m_has_object_getClass = HasSymbol(g_gdb_object_getClass); static const ConstString g_objc_copyRealizedClassList( "_ZL33objc_copyRealizedClassList_nolockPj"); + static const ConstString g_objc_getRealizedClassList_trylock( + "_objc_getRealizedClassList_trylock"); m_has_objc_copyRealizedClassList = HasSymbol(g_objc_copyRealizedClassList); + m_has_objc_getRealizedClassList_trylock = + HasSymbol(g_objc_getRealizedClassList_trylock); WarnIfNoExpandedSharedCache(); RegisterObjCExceptionRecognizer(process); } @@ -1465,8 +1543,14 @@ AppleObjCRuntimeV2::GetClassDescriptor(ValueObject &valobj) { return objc_class_sp; objc_class_sp = GetClassDescriptorFromISA(isa); + if (!objc_class_sp) { + if (ABISP abi_sp = process->GetABI()) + isa = abi_sp->FixCodeAddress(isa); + objc_class_sp = GetClassDescriptorFromISA(isa); + } + if (isa && !objc_class_sp) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TYPES)); + Log *log = GetLog(LLDBLog::Process | LLDBLog::Types); LLDB_LOGF(log, "0x%" PRIx64 ": AppleObjCRuntimeV2::GetClassDescriptor() ISA was " "not in class descriptor cache 0x%" PRIx64, @@ -1537,8 +1621,9 @@ lldb::addr_t AppleObjCRuntimeV2::GetISAHashTablePointer() { 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)); + ExecutionContext &exe_ctx, Helper helper, std::string code, + std::string name) { + Log *log = GetLog(LLDBLog::Process | LLDBLog::Types); LLDB_LOG(log, "Creating utility function {0}", name); @@ -1552,7 +1637,7 @@ AppleObjCRuntimeV2::DynamicClassInfoExtractor::GetClassInfoUtilityFunctionImpl( if (!utility_fn_or_error) { LLDB_LOG_ERROR( log, utility_fn_or_error.takeError(), - "Failed to get utility function for implementation lookup: {0}"); + "Failed to get utility function for dynamic info extractor: {0}"); return {}; } @@ -1572,6 +1657,15 @@ AppleObjCRuntimeV2::DynamicClassInfoExtractor::GetClassInfoUtilityFunctionImpl( value.SetValueType(Value::ValueType::Scalar); value.SetCompilerType(clang_uint32_t_type); arguments.PushValue(value); + + // objc_getRealizedClassList_trylock takes an additional buffer and length. + if (helper == Helper::objc_getRealizedClassList_trylock) { + value.SetCompilerType(clang_void_pointer_type); + arguments.PushValue(value); + value.SetCompilerType(clang_uint32_t_type); + arguments.PushValue(value); + } + arguments.PushValue(value); std::unique_ptr<UtilityFunction> utility_fn = std::move(*utility_fn_or_error); @@ -1597,7 +1691,7 @@ AppleObjCRuntimeV2::DynamicClassInfoExtractor::GetClassInfoUtilityFunction( 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, + GetClassInfoUtilityFunctionImpl(exe_ctx, helper, g_get_dynamic_class_info_body, g_get_dynamic_class_info_name); return m_gdb_objc_realized_classes_helper.utility_function.get(); @@ -1605,11 +1699,19 @@ AppleObjCRuntimeV2::DynamicClassInfoExtractor::GetClassInfoUtilityFunction( case objc_copyRealizedClassList: { if (!m_objc_copyRealizedClassList_helper.utility_function) m_objc_copyRealizedClassList_helper.utility_function = - GetClassInfoUtilityFunctionImpl(exe_ctx, + GetClassInfoUtilityFunctionImpl(exe_ctx, helper, g_get_dynamic_class_info2_body, g_get_dynamic_class_info2_name); return m_objc_copyRealizedClassList_helper.utility_function.get(); } + case objc_getRealizedClassList_trylock: { + if (!m_objc_getRealizedClassList_trylock_helper.utility_function) + m_objc_getRealizedClassList_trylock_helper.utility_function = + GetClassInfoUtilityFunctionImpl(exe_ctx, helper, + g_get_dynamic_class_info3_body, + g_get_dynamic_class_info3_name); + return m_objc_getRealizedClassList_trylock_helper.utility_function.get(); + } } llvm_unreachable("Unexpected helper"); } @@ -1621,19 +1723,37 @@ AppleObjCRuntimeV2::DynamicClassInfoExtractor::GetClassInfoArgs(Helper helper) { return m_gdb_objc_realized_classes_helper.args; case objc_copyRealizedClassList: return m_objc_copyRealizedClassList_helper.args; + case objc_getRealizedClassList_trylock: + return m_objc_getRealizedClassList_trylock_helper.args; } llvm_unreachable("Unexpected helper"); } AppleObjCRuntimeV2::DynamicClassInfoExtractor::Helper -AppleObjCRuntimeV2::DynamicClassInfoExtractor::ComputeHelper() const { - if (!m_runtime.m_has_objc_copyRealizedClassList) +AppleObjCRuntimeV2::DynamicClassInfoExtractor::ComputeHelper( + ExecutionContext &exe_ctx) const { + if (!m_runtime.m_has_objc_copyRealizedClassList && + !m_runtime.m_has_objc_getRealizedClassList_trylock) return DynamicClassInfoExtractor::gdb_objc_realized_classes; if (Process *process = m_runtime.GetProcess()) { if (DynamicLoader *loader = process->GetDynamicLoader()) { - if (loader->IsFullyInitialized()) - return DynamicClassInfoExtractor::objc_copyRealizedClassList; + if (loader->IsFullyInitialized()) { + switch (exe_ctx.GetTargetRef().GetDynamicClassInfoHelper()) { + case eDynamicClassInfoHelperAuto: + [[clang::fallthrough]]; + case eDynamicClassInfoHelperGetRealizedClassList: + if (m_runtime.m_has_objc_getRealizedClassList_trylock) + return DynamicClassInfoExtractor::objc_getRealizedClassList_trylock; + [[clang::fallthrough]]; + case eDynamicClassInfoHelperCopyRealizedClassList: + if (m_runtime.m_has_objc_copyRealizedClassList) + return DynamicClassInfoExtractor::objc_copyRealizedClassList; + [[clang::fallthrough]]; + case eDynamicClassInfoHelperRealizedClassesStruct: + return DynamicClassInfoExtractor::gdb_objc_realized_classes; + } + } } } @@ -1643,7 +1763,7 @@ AppleObjCRuntimeV2::DynamicClassInfoExtractor::ComputeHelper() const { std::unique_ptr<UtilityFunction> AppleObjCRuntimeV2::SharedCacheClassInfoExtractor:: GetClassInfoUtilityFunctionImpl(ExecutionContext &exe_ctx) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TYPES)); + Log *log = GetLog(LLDBLog::Process | LLDBLog::Types); LLDB_LOG(log, "Creating utility function {0}", g_get_shared_cache_class_info_name); @@ -1682,7 +1802,7 @@ AppleObjCRuntimeV2::SharedCacheClassInfoExtractor:: if (!utility_fn_or_error) { LLDB_LOG_ERROR( log, utility_fn_or_error.takeError(), - "Failed to get utility function for implementation lookup: {0}"); + "Failed to get utility function for shared class info extractor: {0}"); return nullptr; } @@ -1746,7 +1866,7 @@ AppleObjCRuntimeV2::DynamicClassInfoExtractor::UpdateISAToDescriptorMap( uint32_t num_class_infos = 0; - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TYPES)); + Log *log = GetLog(LLDBLog::Process | LLDBLog::Types); ExecutionContext exe_ctx; @@ -1769,7 +1889,7 @@ AppleObjCRuntimeV2::DynamicClassInfoExtractor::UpdateISAToDescriptorMap( Status err; // Compute which helper we're going to use for this update. - const DynamicClassInfoExtractor::Helper helper = ComputeHelper(); + const DynamicClassInfoExtractor::Helper helper = ComputeHelper(exe_ctx); // Read the total number of classes from the hash table const uint32_t num_classes = @@ -1813,19 +1933,55 @@ AppleObjCRuntimeV2::DynamicClassInfoExtractor::UpdateISAToDescriptorMap( return DescriptorMapUpdateResult::Fail(); } + auto deallocate_class_infos = llvm::make_scope_exit([&] { + // Deallocate the memory we allocated for the ClassInfo array + if (class_infos_addr != LLDB_INVALID_ADDRESS) + process->DeallocateMemory(class_infos_addr); + }); + + lldb::addr_t class_buffer_addr = LLDB_INVALID_ADDRESS; + const uint32_t class_byte_size = addr_size; + const uint32_t class_buffer_len = num_classes; + const uint32_t class_buffer_byte_size = class_buffer_len * class_byte_size; + if (helper == Helper::objc_getRealizedClassList_trylock) { + class_buffer_addr = process->AllocateMemory( + class_buffer_byte_size, ePermissionsReadable | ePermissionsWritable, + err); + if (class_buffer_addr == LLDB_INVALID_ADDRESS) { + LLDB_LOGF(log, + "unable to allocate %" PRIu32 + " bytes in process for shared cache read", + class_buffer_byte_size); + return DescriptorMapUpdateResult::Fail(); + } + } + + auto deallocate_class_buffer = llvm::make_scope_exit([&] { + // Deallocate the memory we allocated for the Class array + if (class_buffer_addr != LLDB_INVALID_ADDRESS) + process->DeallocateMemory(class_buffer_addr); + }); + 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; + uint32_t index = 0; + arguments.GetValueAtIndex(index++)->GetScalar() = + hash_table.GetTableLoadAddress(); + arguments.GetValueAtIndex(index++)->GetScalar() = class_infos_addr; + arguments.GetValueAtIndex(index++)->GetScalar() = class_infos_byte_size; + + if (class_buffer_addr != LLDB_INVALID_ADDRESS) { + arguments.GetValueAtIndex(index++)->GetScalar() = class_buffer_addr; + arguments.GetValueAtIndex(index++)->GetScalar() = class_buffer_byte_size; + } // Only dump the runtime classes from the expression evaluation if the log is // verbose: - Log *type_log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES); + Log *type_log = GetLog(LLDBLog::Types); bool dump_log = type_log && type_log->GetVerbose(); - arguments.GetValueAtIndex(3)->GetScalar() = dump_log ? 1 : 0; + arguments.GetValueAtIndex(index++)->GetScalar() = dump_log ? 1 : 0; bool success = false; @@ -1886,9 +2042,6 @@ AppleObjCRuntimeV2::DynamicClassInfoExtractor::UpdateISAToDescriptorMap( } } - // Deallocate the memory we allocated for the ClassInfo array - process->DeallocateMemory(class_infos_addr); - return DescriptorMapUpdateResult(success, num_class_infos); } @@ -1902,7 +2055,7 @@ uint32_t AppleObjCRuntimeV2::ParseClassInfoArray(const DataExtractor &data, // uint32_t hash; // } __attribute__((__packed__)); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES)); + Log *log = GetLog(LLDBLog::Types); bool should_log = log && log->GetVerbose(); uint32_t num_parsed = 0; @@ -1975,7 +2128,7 @@ AppleObjCRuntimeV2::SharedCacheClassInfoExtractor::UpdateISAToDescriptorMap() { if (process == nullptr) return DescriptorMapUpdateResult::Fail(); - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TYPES)); + Log *log = GetLog(LLDBLog::Process | LLDBLog::Types); ExecutionContext exe_ctx; @@ -2007,7 +2160,9 @@ AppleObjCRuntimeV2::SharedCacheClassInfoExtractor::UpdateISAToDescriptorMap() { shared_cache_base_addr == LLDB_INVALID_ADDRESS) return DescriptorMapUpdateResult::Fail(); - const uint32_t num_classes = 128 * 1024; + // The number of entries to pre-allocate room for. + // Each entry is (addrsize + 4) bytes + const uint32_t max_num_classes = 163840; UtilityFunction *get_class_info_code = GetClassInfoUtilityFunction(exe_ctx); if (!get_class_info_code) { @@ -2029,7 +2184,7 @@ AppleObjCRuntimeV2::SharedCacheClassInfoExtractor::UpdateISAToDescriptorMap() { 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; + const uint32_t class_infos_byte_size = max_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; @@ -2055,7 +2210,7 @@ AppleObjCRuntimeV2::SharedCacheClassInfoExtractor::UpdateISAToDescriptorMap() { 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); + Log *type_log = GetLog(LLDBLog::Types); bool dump_log = type_log && type_log->GetVerbose(); arguments.GetValueAtIndex(5)->GetScalar() = dump_log ? 1 : 0; @@ -2095,10 +2250,12 @@ AppleObjCRuntimeV2::SharedCacheClassInfoExtractor::UpdateISAToDescriptorMap() { num_class_infos = return_value.GetScalar().ULong(); LLDB_LOG(log, "Discovered {0} Objective-C classes in the shared cache", num_class_infos); - assert(num_class_infos <= num_classes); + // Assert if there were more classes than we pre-allocated + // room for. + assert(num_class_infos <= max_num_classes); if (num_class_infos > 0) { - if (num_class_infos > num_classes) { - num_class_infos = num_classes; + if (num_class_infos > max_num_classes) { + num_class_infos = max_num_classes; success = false; } else { @@ -2213,7 +2370,7 @@ lldb::addr_t AppleObjCRuntimeV2::GetSharedCacheBaseAddress() { void AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded() { LLDB_SCOPED_TIMER(); - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TYPES)); + Log *log = GetLog(LLDBLog::Process | LLDBLog::Types); // Else we need to check with our process to see when the map was updated. Process *process = GetProcess(); @@ -2300,7 +2457,7 @@ bool AppleObjCRuntimeV2::RealizedClassGenerationCountChanged() { objc_debug_realized_class_generation_count) return false; - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TYPES)); + Log *log = GetLog(LLDBLog::Process | LLDBLog::Types); LLDB_LOG(log, "objc_debug_realized_class_generation_count changed from {0} to {1}", m_realized_class_generation_count, @@ -2326,32 +2483,27 @@ static bool DoesProcessHaveSharedCache(Process &process) { void AppleObjCRuntimeV2::WarnIfNoClassesCached( SharedCacheWarningReason reason) { - if (m_noclasses_warning_emitted) - return; - if (GetProcess() && !DoesProcessHaveSharedCache(*GetProcess())) { // Simulators do not have the objc_opt_ro class table so don't actually // complain to the user - m_noclasses_warning_emitted = true; return; } Debugger &debugger(GetProcess()->GetTarget().GetDebugger()); - if (auto stream = debugger.GetAsyncOutputStream()) { - switch (reason) { - case SharedCacheWarningReason::eNotEnoughClassesRead: - stream->PutCString("warning: could not find Objective-C class data in " - "the process. This may reduce the quality of type " - "information available.\n"); - m_noclasses_warning_emitted = true; - break; - case SharedCacheWarningReason::eExpressionExecutionFailure: - stream->PutCString("warning: could not execute support code to read " - "Objective-C class data in the process. This may " - "reduce the quality of type information available.\n"); - m_noclasses_warning_emitted = true; - break; - } + switch (reason) { + case SharedCacheWarningReason::eNotEnoughClassesRead: + Debugger::ReportWarning("could not find Objective-C class data in " + "the process. This may reduce the quality of type " + "information available.\n", + debugger.GetID(), &m_no_classes_cached_warning); + break; + case SharedCacheWarningReason::eExpressionExecutionFailure: + Debugger::ReportWarning( + "could not execute support code to read " + "Objective-C class data in the process. This may " + "reduce the quality of type information available.\n", + debugger.GetID(), &m_no_classes_cached_warning); + break; } } @@ -2368,17 +2520,25 @@ void AppleObjCRuntimeV2::WarnIfNoExpandedSharedCache() { Target &target = GetProcess()->GetTarget(); Debugger &debugger = target.GetDebugger(); - if (auto stream = debugger.GetAsyncOutputStream()) { - const char *msg = "read from the shared cache"; - if (PlatformSP platform_sp = target.GetPlatform()) - msg = platform_sp->IsHost() - ? "read from the host's in-memory shared cache" - : "find the on-disk shared cache for this device"; - stream->Printf("warning: libobjc.A.dylib is being read from process " - "memory. This indicates that LLDB could not %s. This will " - "likely reduce debugging performance.\n", - msg); + + std::string buffer; + llvm::raw_string_ostream os(buffer); + + os << "libobjc.A.dylib is being read from process memory. This " + "indicates that LLDB could not "; + if (PlatformSP platform_sp = target.GetPlatform()) { + if (platform_sp->IsHost()) { + os << "read from the host's in-memory shared cache"; + } else { + os << "find the on-disk shared cache for this device"; + } + } else { + os << "read from the shared cache"; } + os << ". This will likely reduce debugging performance.\n"; + + Debugger::ReportWarning(os.str(), debugger.GetID(), + &m_no_expanded_cache_warning); } DeclVendor *AppleObjCRuntimeV2::GetDeclVendor() { @@ -2454,7 +2614,7 @@ AppleObjCRuntimeV2::NonPointerISACache::CreateInstance( Status error; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES)); + Log *log = GetLog(LLDBLog::Types); auto objc_debug_isa_magic_mask = ExtractRuntimeGlobalSymbol( process, ConstString("objc_debug_isa_magic_mask"), objc_module_sp, error); @@ -2741,17 +2901,23 @@ AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::GetClassDescriptor( return nullptr; actual_class_descriptor_sp = m_runtime.GetClassDescriptorFromISA((ObjCISA)slot_data); + if (!actual_class_descriptor_sp) { + if (ABISP abi_sp = process->GetABI()) { + ObjCISA fixed_isa = abi_sp->FixCodeAddress((ObjCISA)slot_data); + actual_class_descriptor_sp = + m_runtime.GetClassDescriptorFromISA(fixed_isa); + } + } if (!actual_class_descriptor_sp) return ObjCLanguageRuntime::ClassDescriptorSP(); m_cache[slot] = actual_class_descriptor_sp; } uint64_t data_payload = - (((uint64_t)unobfuscated << m_objc_debug_taggedpointer_payload_lshift) >> + ((unobfuscated << m_objc_debug_taggedpointer_payload_lshift) >> m_objc_debug_taggedpointer_payload_rshift); int64_t data_payload_signed = - ((int64_t)((int64_t)unobfuscated - << m_objc_debug_taggedpointer_payload_lshift) >> + ((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)); @@ -2884,7 +3050,7 @@ AppleObjCRuntimeV2::NonPointerISACache::GetClassDescriptor(ObjCISA isa) { bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA( ObjCISA isa, ObjCISA &ret_isa) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES)); + Log *log = GetLog(LLDBLog::Types); LLDB_LOGF(log, "AOCRT::NPI Evaluate(isa = 0x%" PRIx64 ")", (uint64_t)isa); @@ -3007,8 +3173,8 @@ bool AppleObjCRuntimeV2::GetCFBooleanValuesIfNeeded() { if (m_CFBoolean_values) return true; - static ConstString g___kCFBooleanFalse("__kCFBooleanFalse"); - static ConstString g___kCFBooleanTrue("__kCFBooleanTrue"); + static ConstString g_dunder_kCFBooleanFalse("__kCFBooleanFalse"); + static ConstString g_dunder_kCFBooleanTrue("__kCFBooleanTrue"); static ConstString g_kCFBooleanFalse("kCFBooleanFalse"); static ConstString g_kCFBooleanTrue("kCFBooleanTrue"); @@ -3041,8 +3207,8 @@ bool AppleObjCRuntimeV2::GetCFBooleanValuesIfNeeded() { return addr; }; - lldb::addr_t false_addr = get_symbol(g___kCFBooleanFalse, g_kCFBooleanFalse); - lldb::addr_t true_addr = get_symbol(g___kCFBooleanTrue, g_kCFBooleanTrue); + lldb::addr_t false_addr = get_symbol(g_dunder_kCFBooleanFalse, g_kCFBooleanFalse); + lldb::addr_t true_addr = get_symbol(g_dunder_kCFBooleanTrue, g_kCFBooleanTrue); return (m_CFBoolean_values = {false_addr, true_addr}).operator bool(); } 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 e1a6b7cde48a..1a8e9d4aa339 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 @@ -313,13 +313,15 @@ private: }; /// 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. + /// gdb_objc_realized_classes, objc_copyRealizedClassList or + /// objc_getRealizedClassList_trylock. The RealizedClassList variants are + /// preferred because they include lazily named classes, but they are 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. + /// We potentially need more than one helper 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 or + /// objc_getRealizedClassList_trylock for lazily named classes. class DynamicClassInfoExtractor : public ClassInfoExtractor { public: DynamicClassInfoExtractor(AppleObjCRuntimeV2 &runtime) @@ -329,35 +331,34 @@ private: UpdateISAToDescriptorMap(RemoteNXMapTable &hash_table); private: - enum Helper { gdb_objc_realized_classes, objc_copyRealizedClassList }; + enum Helper { + gdb_objc_realized_classes, + objc_copyRealizedClassList, + objc_getRealizedClassList_trylock + }; - /// 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; + /// Compute which helper to use. If dyld is not yet fully initialized we + /// must use gdb_objc_realized_classes. Otherwise, we prefer + /// objc_getRealizedClassList_trylock and objc_copyRealizedClassList + /// respectively, depending on availability. + Helper ComputeHelper(ExecutionContext &exe_ctx) 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; - }; + GetClassInfoUtilityFunctionImpl(ExecutionContext &exe_ctx, Helper helper, + std::string code, std::string name); - /// Helper to read class info using objc_copyRealizedClassList. - struct objc_copyRealizedClassList_helper { + struct UtilityFunctionHelper { 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; + UtilityFunctionHelper m_gdb_objc_realized_classes_helper; + UtilityFunctionHelper m_objc_copyRealizedClassList_helper; + UtilityFunctionHelper m_objc_getRealizedClassList_trylock_helper; }; /// Abstraction to read the Objective-C class info from the shared cache. @@ -429,11 +430,13 @@ private: HashTableSignature m_hash_signature; bool m_has_object_getClass; bool m_has_objc_copyRealizedClassList; + bool m_has_objc_getRealizedClassList_trylock; 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; + std::once_flag m_no_classes_cached_warning; + std::once_flag m_no_expanded_cache_warning; llvm::Optional<std::pair<lldb::addr_t, lldb::addr_t>> m_CFBoolean_values; uint64_t m_realized_class_generation_count; }; 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 ff41f187ba9d..f9ccaf0115a2 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 @@ -29,9 +29,11 @@ #include "lldb/Target/ThreadPlanRunToAddress.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/ScopeExit.h" #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" @@ -44,244 +46,142 @@ const char *AppleObjCTrampolineHandler::g_lookup_implementation_function_name = "__lldb_objc_find_implementation_for_selector"; const char *AppleObjCTrampolineHandler:: g_lookup_implementation_with_stret_function_code = - " \n\ -extern \"C\" \n\ -{ \n\ - extern void *class_getMethodImplementation(void *objc_class, void *sel); \n\ - extern void *class_getMethodImplementation_stret(void *objc_class, \n\ - void *sel); \n\ - extern void * object_getClass (id object); \n\ - extern void * sel_getUid(char *name); \n\ - extern int printf(const char *format, ...); \n\ -} \n\ -extern \"C\" void * __lldb_objc_find_implementation_for_selector ( \n\ - void *object, \n\ - void *sel, \n\ - int is_stret, \n\ - int is_super, \n\ - int is_super2, \n\ - int is_fixup, \n\ - int is_fixed, \n\ - int debug) \n\ -{ \n\ - struct __lldb_imp_return_struct \n\ - { \n\ - void *class_addr; \n\ - void *sel_addr; \n\ - void *impl_addr; \n\ - }; \n\ - \n\ - struct __lldb_objc_class { \n\ - void *isa; \n\ - void *super_ptr; \n\ - }; \n\ - struct __lldb_objc_super { \n\ - void *receiver; \n\ - struct __lldb_objc_class *class_ptr; \n\ - }; \n\ - struct __lldb_msg_ref { \n\ - void *dont_know; \n\ - void *sel; \n\ - }; \n\ - \n\ - struct __lldb_imp_return_struct return_struct; \n\ - \n\ - if (debug) \n\ - printf (\"\\n*** Called with obj: 0x%p sel: 0x%p is_stret: %d is_super: %d, \"\n\ - \"is_super2: %d, is_fixup: %d, is_fixed: %d\\n\", \n\ - object, sel, is_stret, is_super, is_super2, is_fixup, is_fixed);\n\ - if (is_super) \n\ - { \n\ - if (is_super2) \n\ - { \n\ - return_struct.class_addr = ((__lldb_objc_super *) object)->class_ptr->super_ptr;\n\ - } \n\ - else \n\ - { \n\ - return_struct.class_addr = ((__lldb_objc_super *) object)->class_ptr;\n\ - } \n\ - } \n\ - else \n\ - { \n\ - // This code seems a little funny, but has its reasons... \n\ - \n\ - // The call to [object class] is here because if this is a \n\ - // class, and has not been called into yet, we need to do \n\ - // something to force the class to initialize itself. \n\ - // Then the call to object_getClass will actually return the \n\ - // correct class, either the class if object is a class \n\ - // instance, or the meta-class if it is a class pointer. \n\ - void *class_ptr = (void *) [(id) object class]; \n\ - return_struct.class_addr = (id) object_getClass((id) object); \n\ - if (debug) \n\ - { \n\ - if (class_ptr == object) \n\ - { \n\ - printf (\"Found a class object, need to use the meta class %p -> %p\\n\",\n\ - class_ptr, return_struct.class_addr); \n\ - } \n\ - else \n\ - { \n\ - printf (\"[object class] returned: %p object_getClass: %p.\\n\", \n\ - class_ptr, return_struct.class_addr); \n\ - } \n\ - } \n\ - } \n\ - \n\ - if (is_fixup) \n\ - { \n\ - if (is_fixed) \n\ - { \n\ - return_struct.sel_addr = ((__lldb_msg_ref *) sel)->sel; \n\ - } \n\ - else \n\ - { \n\ - char *sel_name = (char *) ((__lldb_msg_ref *) sel)->sel; \n\ - return_struct.sel_addr = sel_getUid (sel_name); \n\ - if (debug) \n\ - printf (\"\\n*** Got fixed up selector: %p for name %s.\\n\",\n\ - return_struct.sel_addr, sel_name); \n\ - } \n\ - } \n\ - else \n\ - { \n\ - return_struct.sel_addr = sel; \n\ - } \n\ - \n\ - if (is_stret) \n\ - { \n\ - return_struct.impl_addr = \n\ - class_getMethodImplementation_stret (return_struct.class_addr, \n\ - return_struct.sel_addr); \n\ - } \n\ - else \n\ - { \n\ - return_struct.impl_addr = \n\ - class_getMethodImplementation (return_struct.class_addr, \n\ - return_struct.sel_addr); \n\ - } \n\ - if (debug) \n\ - printf (\"\\n*** Returning implementation: %p.\\n\", \n\ - return_struct.impl_addr); \n\ - \n\ - return return_struct.impl_addr; \n\ -} \n\ -"; + R"( + if (is_stret) { + return_struct.impl_addr = + class_getMethodImplementation_stret (return_struct.class_addr, + return_struct.sel_addr); + } else { + return_struct.impl_addr = + class_getMethodImplementation (return_struct.class_addr, + return_struct.sel_addr); + } + if (debug) + printf ("\n*** Returning implementation: %p.\n", + return_struct.impl_addr); + + return return_struct.impl_addr; +} +)"; const char * AppleObjCTrampolineHandler::g_lookup_implementation_no_stret_function_code = - " \n\ -extern \"C\" \n\ -{ \n\ - extern void *class_getMethodImplementation(void *objc_class, void *sel); \n\ - extern void * object_getClass (id object); \n\ - extern void * sel_getUid(char *name); \n\ - extern int printf(const char *format, ...); \n\ -} \n\ -extern \"C\" void * __lldb_objc_find_implementation_for_selector (void *object, \n\ - void *sel, \n\ - int is_stret, \n\ - int is_super, \n\ - int is_super2, \n\ - int is_fixup, \n\ - int is_fixed, \n\ - int debug) \n\ -{ \n\ - struct __lldb_imp_return_struct \n\ - { \n\ - void *class_addr; \n\ - void *sel_addr; \n\ - void *impl_addr; \n\ - }; \n\ - \n\ - struct __lldb_objc_class { \n\ - void *isa; \n\ - void *super_ptr; \n\ - }; \n\ - struct __lldb_objc_super { \n\ - void *receiver; \n\ - struct __lldb_objc_class *class_ptr; \n\ - }; \n\ - struct __lldb_msg_ref { \n\ - void *dont_know; \n\ - void *sel; \n\ - }; \n\ - \n\ - struct __lldb_imp_return_struct return_struct; \n\ - \n\ - if (debug) \n\ - printf (\"\\n*** Called with obj: 0x%p sel: 0x%p is_stret: %d is_super: %d, \" \n\ - \"is_super2: %d, is_fixup: %d, is_fixed: %d\\n\", \n\ - object, sel, is_stret, is_super, is_super2, is_fixup, is_fixed); \n\ - if (is_super) \n\ - { \n\ - if (is_super2) \n\ - { \n\ - return_struct.class_addr = ((__lldb_objc_super *) object)->class_ptr->super_ptr; \n\ - } \n\ - else \n\ - { \n\ - return_struct.class_addr = ((__lldb_objc_super *) object)->class_ptr; \n\ - } \n\ - } \n\ - else \n\ - { \n\ - // This code seems a little funny, but has its reasons... \n\ - // The call to [object class] is here because if this is a class, and has not been called into \n\ - // yet, we need to do something to force the class to initialize itself. \n\ - // Then the call to object_getClass will actually return the correct class, either the class \n\ - // if object is a class instance, or the meta-class if it is a class pointer. \n\ - void *class_ptr = (void *) [(id) object class]; \n\ - return_struct.class_addr = (id) object_getClass((id) object); \n\ - if (debug) \n\ - { \n\ - if (class_ptr == object) \n\ - { \n\ - printf (\"Found a class object, need to return the meta class %p -> %p\\n\", \n\ - class_ptr, return_struct.class_addr); \n\ - } \n\ - else \n\ - { \n\ - printf (\"[object class] returned: %p object_getClass: %p.\\n\", \n\ - class_ptr, return_struct.class_addr); \n\ - } \n\ - } \n\ - } \n\ - \n\ - if (is_fixup) \n\ - { \n\ - if (is_fixed) \n\ - { \n\ - return_struct.sel_addr = ((__lldb_msg_ref *) sel)->sel; \n\ - } \n\ - else \n\ - { \n\ - char *sel_name = (char *) ((__lldb_msg_ref *) sel)->sel; \n\ - return_struct.sel_addr = sel_getUid (sel_name); \n\ - if (debug) \n\ - printf (\"\\n*** Got fixed up selector: %p for name %s.\\n\",\n\ - return_struct.sel_addr, sel_name); \n\ - } \n\ - } \n\ - else \n\ - { \n\ - return_struct.sel_addr = sel; \n\ - } \n\ - \n\ - return_struct.impl_addr = \n\ - class_getMethodImplementation (return_struct.class_addr, \n\ - return_struct.sel_addr); \n\ - if (debug) \n\ - printf (\"\\n*** Returning implementation: 0x%p.\\n\", \n\ - return_struct.impl_addr); \n\ - \n\ - return return_struct.impl_addr; \n\ -} \n\ -"; + R"( + return_struct.impl_addr = + class_getMethodImplementation (return_struct.class_addr, + return_struct.sel_addr); + if (debug) + printf ("\n*** getMethodImpletation for addr: 0x%p sel: 0x%p result: 0x%p.\n", + return_struct.class_addr, return_struct.sel_addr, return_struct.impl_addr); + + return return_struct.impl_addr; +} +)"; + +const char + *AppleObjCTrampolineHandler::g_lookup_implementation_function_common_code = + R"( +extern "C" +{ + extern void *class_getMethodImplementation(void *objc_class, void *sel); + extern void *class_getMethodImplementation_stret(void *objc_class, void *sel); + extern void * object_getClass (id object); + extern void * sel_getUid(char *name); + extern int printf(const char *format, ...); +} +extern "C" void * +__lldb_objc_find_implementation_for_selector (void *object, + void *sel, + int is_str_ptr, + int is_stret, + int is_super, + int is_super2, + int is_fixup, + int is_fixed, + int debug) +{ + struct __lldb_imp_return_struct { + void *class_addr; + void *sel_addr; + void *impl_addr; + }; + + struct __lldb_objc_class { + void *isa; + void *super_ptr; + }; + struct __lldb_objc_super { + void *receiver; + struct __lldb_objc_class *class_ptr; + }; + struct __lldb_msg_ref { + void *dont_know; + void *sel; + }; + + struct __lldb_imp_return_struct return_struct; + + if (debug) + printf ("\n*** Called with obj: %p sel: %p is_str_ptr: %d " + "is_stret: %d is_super: %d, " + "is_super2: %d, is_fixup: %d, is_fixed: %d\n", + object, sel, is_str_ptr, is_stret, + is_super, is_super2, is_fixup, is_fixed); + + if (is_str_ptr) { + if (debug) + printf("*** Turning string: '%s'", sel); + sel = sel_getUid((char *)sel); + if (debug) + printf("*** into sel to %p", sel); + } + if (is_super) { + if (is_super2) { + return_struct.class_addr + = ((__lldb_objc_super *) object)->class_ptr->super_ptr; + } else { + return_struct.class_addr = ((__lldb_objc_super *) object)->class_ptr; + } + if (debug) + printf("*** Super, class addr: %p\n", return_struct.class_addr); + } else { + // This code seems a little funny, but has its reasons... + // The call to [object class] is here because if this is a class, and has + // not been called into yet, we need to do something to force the class to + // initialize itself. + // Then the call to object_getClass will actually return the correct class, + // either the class if object is a class instance, or the meta-class if it + // is a class pointer. + void *class_ptr = (void *) [(id) object class]; + return_struct.class_addr = (id) object_getClass((id) object); + if (debug) { + if (class_ptr == object) { + printf ("Found a class object, need to return the meta class %p -> %p\n", + class_ptr, return_struct.class_addr); + } else { + printf ("[object class] returned: %p object_getClass: %p.\n", + class_ptr, return_struct.class_addr); + } + } + } + + if (is_fixup) { + if (is_fixed) { + return_struct.sel_addr = ((__lldb_msg_ref *) sel)->sel; + } else { + char *sel_name = (char *) ((__lldb_msg_ref *) sel)->sel; + return_struct.sel_addr = sel_getUid (sel_name); + if (debug) + printf ("\n*** Got fixed up selector: %p for name %s.\n", + return_struct.sel_addr, sel_name); + } + } else { + return_struct.sel_addr = sel; + } +)"; AppleObjCTrampolineHandler::AppleObjCVTables::VTableRegion::VTableRegion( AppleObjCVTables *owner, lldb::addr_t header_addr) - : m_valid(true), m_owner(owner), m_header_addr(header_addr), - m_code_start_addr(0), m_code_end_addr(0), m_next_region(0) { + : m_valid(true), m_owner(owner), m_header_addr(header_addr) { SetUpRegion(); } @@ -343,7 +243,7 @@ void AppleObjCTrampolineHandler::AppleObjCVTables::VTableRegion::SetUpRegion() { // Ingest the whole descriptor array: const lldb::addr_t desc_ptr = m_header_addr + header_size; const size_t desc_array_size = num_descriptors * descriptor_size; - DataBufferSP data_sp(new DataBufferHeap(desc_array_size, '\0')); + WritableDataBufferSP data_sp(new DataBufferHeap(desc_array_size, '\0')); uint8_t *dst = (uint8_t *)data_sp->GetBytes(); DataExtractor desc_extractor(dst, desc_array_size, process_sp->GetByteOrder(), @@ -575,7 +475,7 @@ bool AppleObjCTrampolineHandler::AppleObjCVTables::ReadRegions( if (!process_sp) return false; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); // We aren't starting at the trampoline symbol. InitializeVTableSymbols(); @@ -676,7 +576,6 @@ const char *AppleObjCTrampolineHandler::g_opt_dispatch_names[] = { AppleObjCTrampolineHandler::AppleObjCTrampolineHandler( const ProcessSP &process_sp, const ModuleSP &objc_module_sp) : m_process_wp(), m_objc_module_sp(objc_module_sp), - m_lookup_implementation_function_code(nullptr), m_impl_fn_addr(LLDB_INVALID_ADDRESS), m_impl_stret_fn_addr(LLDB_INVALID_ADDRESS), m_msg_forward_addr(LLDB_INVALID_ADDRESS) { @@ -729,17 +628,24 @@ AppleObjCTrampolineHandler::AppleObjCTrampolineHandler( get_impl_name.AsCString()); } return; - } else if (m_impl_stret_fn_addr == LLDB_INVALID_ADDRESS) { + } + + // We will either set the implementation to the _stret or non_stret version, + // so either way it's safe to start filling the m_lookup_..._code here. + m_lookup_implementation_function_code.assign( + g_lookup_implementation_function_common_code); + + if (m_impl_stret_fn_addr == LLDB_INVALID_ADDRESS) { // It there is no stret return lookup function, assume that it is the same // as the straight lookup: m_impl_stret_fn_addr = m_impl_fn_addr; // Also we will use the version of the lookup code that doesn't rely on the // stret version of the function. - m_lookup_implementation_function_code = - g_lookup_implementation_no_stret_function_code; + m_lookup_implementation_function_code.append( + g_lookup_implementation_no_stret_function_code); } else { - m_lookup_implementation_function_code = - g_lookup_implementation_with_stret_function_code; + m_lookup_implementation_function_code.append( + g_lookup_implementation_with_stret_function_code); } // Look up the addresses for the objc dispatch functions and cache @@ -794,7 +700,7 @@ AppleObjCTrampolineHandler::SetupDispatchFunction(Thread &thread, ValueList &dispatch_values) { ThreadSP thread_sp(thread.shared_from_this()); ExecutionContext exe_ctx(thread_sp); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); lldb::addr_t args_addr = LLDB_INVALID_ADDRESS; FunctionCaller *impl_function_caller = nullptr; @@ -806,7 +712,7 @@ AppleObjCTrampolineHandler::SetupDispatchFunction(Thread &thread, // First stage is to make the ClangUtility to hold our injected function: if (!m_impl_code) { - if (m_lookup_implementation_function_code != nullptr) { + if (!m_lookup_implementation_function_code.empty()) { auto utility_fn_or_error = exe_ctx.GetTargetRef().CreateUtilityFunction( m_lookup_implementation_function_code, g_lookup_implementation_function_name, eLanguageTypeC, exe_ctx); @@ -891,13 +797,43 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, DispatchFunction vtable_dispatch = {"vtable", false, false, false, DispatchFunction::eFixUpFixed}; - - // First step is to look and see if we are in one of the known ObjC + // The selector specific stubs are a wrapper for objc_msgSend. They don't get + // passed a SEL, but instead the selector string is encoded in the stub + // name, in the form: + // objc_msgSend$SelectorName + // and the stub figures out the uniqued selector. If we find ourselves in + // one of these stubs, we strip off the selector string and pass that to the + // implementation finder function, which looks up the SEL (you have to do this + // in process) and passes that to the runtime lookup function. + DispatchFunction sel_stub_dispatch = {"sel-specific-stub", false, false, + false, DispatchFunction::eFixUpNone}; + + // First step is to see if we're in a selector-specific dispatch stub. + // Those are of the form _objc_msgSend$<SELECTOR>, so see if the current + // function has that name: + Address func_addr; + Target &target = thread.GetProcess()->GetTarget(); + llvm::StringRef sym_name; + const DispatchFunction *this_dispatch = nullptr; + + if (target.ResolveLoadAddress(curr_pc, func_addr)) { + Symbol *curr_sym = func_addr.CalculateSymbolContextSymbol(); + if (curr_sym) + sym_name = curr_sym->GetName().GetStringRef(); + + if (!sym_name.empty() && !sym_name.consume_front("objc_msgSend$")) + sym_name = {}; + else + this_dispatch = &sel_stub_dispatch; + } + bool in_selector_stub = !sym_name.empty(); + // Second step is to look and see if we are in one of the known ObjC // dispatch functions. We've already compiled a table of same, so // consult it. - const DispatchFunction *this_dispatch = FindDispatchFunction(curr_pc); - + if (!in_selector_stub) + this_dispatch = FindDispatchFunction(curr_pc); + // Next check to see if we are in a vtable region: if (!this_dispatch && m_vtables_up) { @@ -910,11 +846,15 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, } } + // Since we set this_dispatch in both the vtable & sel specific stub cases + // this if will be used for all three of those cases. if (this_dispatch) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); // We are decoding a method dispatch. First job is to pull the - // arguments out: + // arguments out. If we are in a regular stub, we get self & selector, + // but if we are in a selector-specific stub, we'll have to get that from + // the string sym_name. lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0); @@ -944,11 +884,17 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, int obj_index; int sel_index; + // If this is a selector-specific stub then just push one value, 'cause + // we only get the object. // If this is a struct return dispatch, then the first argument is // the return struct pointer, and the object is the second, and - // the selector is the third. Otherwise the object is the first - // and the selector the second. - if (this_dispatch->stret_return) { + // the selector is the third. + // Otherwise the object is the first and the selector the second. + if (in_selector_stub) { + obj_index = 0; + sel_index = 1; + argument_values.PushValue(void_ptr_value); + } else if (this_dispatch->stret_return) { obj_index = 1; sel_index = 2; argument_values.PushValue(void_ptr_value); @@ -975,15 +921,17 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, } ExecutionContext exe_ctx(thread.shared_from_this()); - Process *process = exe_ctx.GetProcessPtr(); // isa_addr will store the class pointer that the method is being // dispatched to - so either the class directly or the super class // if this is one of the objc_msgSendSuper flavors. That's mostly // used to look up the class/selector pair in our cache. lldb::addr_t isa_addr = LLDB_INVALID_ADDRESS; - lldb::addr_t sel_addr = - argument_values.GetValueAtIndex(sel_index)->GetScalar().ULongLong(); + lldb::addr_t sel_addr = LLDB_INVALID_ADDRESS; + // If we are not in a selector stub, get the sel address from the arguments. + if (!in_selector_stub) + sel_addr = + argument_values.GetValueAtIndex(sel_index)->GetScalar().ULongLong(); // Figure out the class this is being dispatched to and see if // we've already cached this method call, If so we can push a @@ -998,14 +946,14 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, // to dig the super out of the class and use that. Value super_value(*(argument_values.GetValueAtIndex(obj_index))); - super_value.GetScalar() += process->GetAddressByteSize(); + super_value.GetScalar() += process_sp->GetAddressByteSize(); super_value.ResolveValue(&exe_ctx); if (super_value.GetScalar().IsValid()) { // isa_value now holds the class pointer. The second word of the // class pointer is the super-class pointer: - super_value.GetScalar() += process->GetAddressByteSize(); + super_value.GetScalar() += process_sp->GetAddressByteSize(); super_value.ResolveValue(&exe_ctx); if (super_value.GetScalar().IsValid()) isa_addr = super_value.GetScalar().ULongLong(); @@ -1024,7 +972,7 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, // this structure. Value super_value(*(argument_values.GetValueAtIndex(obj_index))); - super_value.GetScalar() += process->GetAddressByteSize(); + super_value.GetScalar() += process_sp->GetAddressByteSize(); super_value.ResolveValue(&exe_ctx); if (super_value.GetScalar().IsValid()) { @@ -1060,20 +1008,22 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, // Okay, we've got the address of the class for which we're resolving this, // let's see if it's in our cache: lldb::addr_t impl_addr = LLDB_INVALID_ADDRESS; - + // If this is a regular dispatch, look up the sel in our addr to sel cache: if (isa_addr != LLDB_INVALID_ADDRESS) { - if (log) { - LLDB_LOGF(log, - "Resolving call for class - 0x%" PRIx64 - " and selector - 0x%" PRIx64, - isa_addr, sel_addr); - } ObjCLanguageRuntime *objc_runtime = ObjCLanguageRuntime::Get(*thread.GetProcess()); assert(objc_runtime != nullptr); - - impl_addr = objc_runtime->LookupInMethodCache(isa_addr, sel_addr); + if (!in_selector_stub) { + LLDB_LOG(log, "Resolving call for class - {0} and selector - {1}", + isa_addr, sel_addr); + impl_addr = objc_runtime->LookupInMethodCache(isa_addr, sel_addr); + } else { + LLDB_LOG(log, "Resolving call for class - {0} and selector - {1}", + isa_addr, sym_name); + impl_addr = objc_runtime->LookupInMethodCache(isa_addr, sym_name); + } } + // If it is a selector-specific stub dispatch, look in the string cache: if (impl_addr != LLDB_INVALID_ADDRESS) { // Yup, it was in the cache, so we can run to that address directly. @@ -1091,20 +1041,52 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, ValueList dispatch_values; // We've will inject a little function in the target that takes the - // object, selector and some flags, + // object, selector/selector string and some flags, // and figures out the implementation. Looks like: // void *__lldb_objc_find_implementation_for_selector (void *object, // void *sel, + // int + // is_str_ptr, // int is_stret, // int is_super, // int is_super2, // int is_fixup, // int is_fixed, // int debug) + // If we don't have an actual SEL, but rather a string version of the + // selector WE injected, set is_str_ptr to true, and sel to the address + // of the string. // So set up the arguments for that call. dispatch_values.PushValue(*(argument_values.GetValueAtIndex(obj_index))); - dispatch_values.PushValue(*(argument_values.GetValueAtIndex(sel_index))); + lldb::addr_t sel_str_addr = LLDB_INVALID_ADDRESS; + if (!in_selector_stub) { + // If we don't have a selector string, push the selector from arguments. + dispatch_values.PushValue( + *(argument_values.GetValueAtIndex(sel_index))); + } else { + // Otherwise, inject the string into the target, and push that value for + // the sel argument. + Status error; + sel_str_addr = process_sp->AllocateMemory( + sym_name.size() + 1, ePermissionsReadable | ePermissionsWritable, + error); + if (sel_str_addr == LLDB_INVALID_ADDRESS || error.Fail()) { + LLDB_LOG(log, + "Could not allocate memory for selector string {0}: {1}", + sym_name, error); + return ret_plan_sp; + } + process_sp->WriteMemory(sel_str_addr, sym_name.str().c_str(), + sym_name.size() + 1, error); + if (error.Fail()) { + LLDB_LOG(log, "Could not write string to address {0}", sel_str_addr); + return ret_plan_sp; + } + Value sel_ptr_value(void_ptr_value); + sel_ptr_value.GetScalar() = sel_str_addr; + dispatch_values.PushValue(sel_ptr_value); + } Value flag_value; CompilerType clang_int_type = @@ -1114,6 +1096,12 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, // flag_value.SetContext (Value::eContextTypeClangType, clang_int_type); flag_value.SetCompilerType(clang_int_type); + if (in_selector_stub) + flag_value.GetScalar() = 1; + else + flag_value.GetScalar() = 0; + dispatch_values.PushValue(flag_value); + if (this_dispatch->stret_return) flag_value.GetScalar() = 1; else @@ -1158,7 +1146,8 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, dispatch_values.PushValue(flag_value); ret_plan_sp = std::make_shared<AppleThreadPlanStepThroughObjCTrampoline>( - thread, *this, dispatch_values, isa_addr, sel_addr); + thread, *this, dispatch_values, isa_addr, sel_addr, sel_str_addr, + sym_name); if (log) { StreamString s; ret_plan_sp->GetDescription(&s, eDescriptionLevelFull); 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 546b500b4529..a6e1e16d1ee0 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 @@ -38,11 +38,11 @@ public: public: enum FixUpState { eFixUpNone, eFixUpFixed, eFixUpToFix }; - const char *name; - bool stret_return; - bool is_super; - bool is_super2; - FixUpState fixedup; + const char *name = nullptr; + bool stret_return = false; + bool is_super = false; + bool is_super2 = false; + FixUpState fixedup = eFixUpNone; }; lldb::addr_t SetupDispatchFunction(Thread &thread, @@ -52,9 +52,19 @@ public: const DispatchFunction &)>); private: + /// These hold the code for the function that finds the implementation of + /// an ObjC message send given the class & selector and the kind of dispatch. + /// There are two variants depending on whether the platform uses a separate + /// _stret passing convention (e.g. Intel) or not (e.g. ARM). The difference + /// is only at the very end of the function, so the code is broken into the + /// common prefix and the suffix, which get composed appropriately before + /// the function gets compiled. + /// \{ static const char *g_lookup_implementation_function_name; + static const char *g_lookup_implementation_function_common_code; static const char *g_lookup_implementation_with_stret_function_code; static const char *g_lookup_implementation_no_stret_function_code; + /// \} class AppleObjCVTables { public: @@ -144,7 +154,7 @@ private: MsgsendMap m_opt_dispatch_map; lldb::ProcessWP m_process_wp; lldb::ModuleSP m_objc_module_sp; - const char *m_lookup_implementation_function_code; + std::string m_lookup_implementation_function_code; std::unique_ptr<UtilityFunction> m_impl_code; std::mutex m_impl_function_mutex; lldb::addr_t m_impl_fn_addr; 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 f935ae7db8c0..547a1f6db976 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 @@ -18,6 +18,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlanRunToAddress.h" #include "lldb/Target/ThreadPlanStepOut.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" @@ -31,13 +32,15 @@ using namespace lldb_private; AppleThreadPlanStepThroughObjCTrampoline:: AppleThreadPlanStepThroughObjCTrampoline( Thread &thread, AppleObjCTrampolineHandler &trampoline_handler, - ValueList &input_values, lldb::addr_t isa_addr, lldb::addr_t sel_addr) + ValueList &input_values, lldb::addr_t isa_addr, lldb::addr_t sel_addr, + lldb::addr_t sel_str_addr, llvm::StringRef sel_str) : 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_isa_addr(isa_addr), m_sel_addr(sel_addr), m_impl_function(nullptr), + m_sel_str_addr(sel_str_addr), m_sel_str(sel_str) {} // Destructor AppleThreadPlanStepThroughObjCTrampoline:: @@ -125,8 +128,10 @@ bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) { } } - // Second stage, if all went well with the function calling, then fetch the - // target address, and queue up a "run to that address" plan. + // Second stage, if all went well with the function calling, get the + // implementation function address, and queue up a "run to that address" plan. + Log *log = GetLog(LLDBLog::Step); + if (!m_run_to_sp) { Value target_addr_value; ExecutionContext exc_ctx; @@ -141,7 +146,6 @@ bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) { } Address target_so_addr; target_so_addr.SetOpcodeLoadAddress(target_addr, exc_ctx.GetTargetPtr()); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); if (target_addr == 0) { LLDB_LOGF(log, "Got target implementation of 0x0, stopping."); SetPlanComplete(); @@ -173,13 +177,25 @@ bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) { ObjCLanguageRuntime *objc_runtime = ObjCLanguageRuntime::Get(*GetThread().GetProcess()); assert(objc_runtime != nullptr); - objc_runtime->AddToMethodCache(m_isa_addr, m_sel_addr, target_addr); - LLDB_LOGF(log, - "Adding {isa-addr=0x%" PRIx64 ", sel-addr=0x%" PRIx64 - "} = addr=0x%" PRIx64 " to cache.", - m_isa_addr, m_sel_addr, target_addr); - - // Extract the target address from the value: + if (m_sel_str_addr != LLDB_INVALID_ADDRESS) { + // Cache the string -> implementation and free the string in the target. + Status dealloc_error = + GetThread().GetProcess()->DeallocateMemory(m_sel_str_addr); + // For now just log this: + if (dealloc_error.Fail()) + LLDB_LOG(log, "Failed to deallocate the sel str at {0} - error: {1}", + m_sel_str_addr, dealloc_error); + objc_runtime->AddToMethodCache(m_isa_addr, m_sel_str, target_addr); + LLDB_LOG(log, + "Adding \\{isa-addr={0}, sel-addr={1}\\} = addr={2} to cache.", + m_isa_addr, m_sel_str, target_addr); + } else { + objc_runtime->AddToMethodCache(m_isa_addr, m_sel_addr, target_addr); + LLDB_LOGF(log, + "Adding {isa-addr=0x%" PRIx64 ", sel-addr=0x%" PRIx64 + "} = addr=0x%" PRIx64 " to cache.", + m_isa_addr, m_sel_addr, target_addr); + } m_run_to_sp = std::make_shared<ThreadPlanRunToAddress>( GetThread(), target_so_addr, false); @@ -354,7 +370,7 @@ bool AppleThreadPlanStepThroughDirectDispatch::ShouldStop(Event *event_ptr) { // If we have a step through plan, then w're in the process of getting // through an ObjC msgSend. If we arrived at the target function, then // check whether we have debug info, and if we do, stop. - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (m_objc_step_through_sp && m_objc_step_through_sp->IsPlanComplete()) { // If the plan failed for some reason, we should probably just let the 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 b5b45079094c..ba4fb5ace1ed 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,7 +24,8 @@ class AppleThreadPlanStepThroughObjCTrampoline : public ThreadPlan { public: AppleThreadPlanStepThroughObjCTrampoline( Thread &thread, AppleObjCTrampolineHandler &trampoline_handler, - ValueList &values, lldb::addr_t isa_addr, lldb::addr_t sel_addr); + ValueList &values, lldb::addr_t isa_addr, lldb::addr_t sel_addr, + lldb::addr_t sel_str_addr, llvm::StringRef sel_str); ~AppleThreadPlanStepThroughObjCTrampoline() override; @@ -70,6 +71,13 @@ private: FunctionCaller *m_impl_function; /// This is a pointer to a impl function that /// is owned by the client that pushes this /// plan. + lldb::addr_t m_sel_str_addr; /// If this is not LLDB_INVALID_ADDRESS then it + /// is the address we wrote the selector string + /// to. We need to deallocate it when the + /// function call is done. + std::string m_sel_str; /// This is the string we wrote to memory - we + /// use it for caching, but only if + /// m_sel_str_addr is non-null. }; class AppleThreadPlanStepThroughDirectDispatch: public ThreadPlanStepOut { 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 0cc96e43e195..b387de38d3bf 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp @@ -19,8 +19,9 @@ #include "lldb/Symbol/Type.h" #include "lldb/Symbol/TypeList.h" #include "lldb/Symbol/Variable.h" -#include "lldb/Target/Target.h" #include "lldb/Target/ABI.h" +#include "lldb/Target/Target.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Timer.h" @@ -36,7 +37,7 @@ char ObjCLanguageRuntime::ID = 0; ObjCLanguageRuntime::~ObjCLanguageRuntime() = default; ObjCLanguageRuntime::ObjCLanguageRuntime(Process *process) - : LanguageRuntime(process), m_impl_cache(), + : LanguageRuntime(process), m_impl_cache(), m_impl_str_cache(), m_has_new_literals_and_indexing(eLazyBoolCalculate), m_isa_to_descriptor(), m_hash_to_isa_map(), m_type_size_cache(), m_isa_to_descriptor_stop_id(UINT32_MAX), m_complete_class_cache(), @@ -63,7 +64,7 @@ bool ObjCLanguageRuntime::AddClass(ObjCISA isa, void ObjCLanguageRuntime::AddToMethodCache(lldb::addr_t class_addr, lldb::addr_t selector, lldb::addr_t impl_addr) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (log) { LLDB_LOGF(log, "Caching: class 0x%" PRIx64 " selector 0x%" PRIx64 @@ -74,6 +75,18 @@ void ObjCLanguageRuntime::AddToMethodCache(lldb::addr_t class_addr, ClassAndSel(class_addr, selector), impl_addr)); } +void ObjCLanguageRuntime::AddToMethodCache(lldb::addr_t class_addr, + llvm::StringRef sel_str, + lldb::addr_t impl_addr) { + Log *log = GetLog(LLDBLog::Step); + + LLDB_LOG(log, "Caching: class {0} selector {1} implementation {2}.", + class_addr, sel_str, impl_addr); + + m_impl_str_cache.insert(std::pair<ClassAndSelStr, lldb::addr_t>( + ClassAndSelStr(class_addr, sel_str), impl_addr)); +} + lldb::addr_t ObjCLanguageRuntime::LookupInMethodCache(lldb::addr_t class_addr, lldb::addr_t selector) { MsgImplMap::iterator pos, end = m_impl_cache.end(); @@ -83,6 +96,15 @@ lldb::addr_t ObjCLanguageRuntime::LookupInMethodCache(lldb::addr_t class_addr, return LLDB_INVALID_ADDRESS; } +lldb::addr_t ObjCLanguageRuntime::LookupInMethodCache(lldb::addr_t class_addr, + llvm::StringRef sel_str) { + MsgImplStrMap::iterator pos, end = m_impl_str_cache.end(); + pos = m_impl_str_cache.find(ClassAndSelStr(class_addr, sel_str)); + if (pos != end) + return (*pos).second; + return LLDB_INVALID_ADDRESS; +} + lldb::TypeSP ObjCLanguageRuntime::LookupInCompleteClassCache(ConstString &name) { CompleteClassMap::iterator complete_class_iter = 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 15fce04ea465..9431b4250240 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h @@ -22,6 +22,7 @@ #include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/Type.h" #include "lldb/Target/LanguageRuntime.h" +#include "lldb/Utility/ConstString.h" #include "lldb/lldb-private.h" class CommandObjectObjC_ClassTable_Dump; @@ -242,11 +243,19 @@ public: virtual bool HasReadObjCLibrary() = 0; + // These two methods actually use different caches. The only time we'll + // cache a sel_str is if we found a "selector specific stub" for the selector + // and conversely we only add to the SEL cache if we saw a regular dispatch. lldb::addr_t LookupInMethodCache(lldb::addr_t class_addr, lldb::addr_t sel); + lldb::addr_t LookupInMethodCache(lldb::addr_t class_addr, + llvm::StringRef sel_str); void AddToMethodCache(lldb::addr_t class_addr, lldb::addr_t sel, lldb::addr_t impl_addr); + void AddToMethodCache(lldb::addr_t class_addr, llvm::StringRef sel_str, + lldb::addr_t impl_addr); + TypeAndOrName LookupInClassNameCache(lldb::addr_t class_addr); void AddToClassNameCache(lldb::addr_t class_addr, const char *name, @@ -343,20 +352,22 @@ protected: } private: - // We keep a map of <Class,Selector>->Implementation so we don't have to call - // the resolver function over and over. + // We keep two maps of <Class,Selector>->Implementation so we don't have + // to call the resolver function over and over. + // The first comes from regular obj_msgSend type dispatch, and maps the + // class + uniqued SEL value to an implementation. + // The second comes from the "selector-specific stubs", which are always + // of the form _objc_msgSend$SelectorName, so we don't know the uniqued + // selector, only the string name. // FIXME: We need to watch for the loading of Protocols, and flush the cache // for any // class that we see so changed. struct ClassAndSel { - ClassAndSel() { - sel_addr = LLDB_INVALID_ADDRESS; - class_addr = LLDB_INVALID_ADDRESS; - } + ClassAndSel() = default; - ClassAndSel(lldb::addr_t in_sel_addr, lldb::addr_t in_class_addr) + ClassAndSel(lldb::addr_t in_class_addr, lldb::addr_t in_sel_addr) : class_addr(in_class_addr), sel_addr(in_sel_addr) {} bool operator==(const ClassAndSel &rhs) { @@ -379,11 +390,35 @@ private: } } - lldb::addr_t class_addr; - lldb::addr_t sel_addr; + lldb::addr_t class_addr = LLDB_INVALID_ADDRESS; + lldb::addr_t sel_addr = LLDB_INVALID_ADDRESS; + }; + + struct ClassAndSelStr { + ClassAndSelStr() = default; + + ClassAndSelStr(lldb::addr_t in_class_addr, llvm::StringRef in_sel_name) + : class_addr(in_class_addr), sel_name(in_sel_name) {} + + bool operator==(const ClassAndSelStr &rhs) { + return class_addr == rhs.class_addr && sel_name == rhs.sel_name; + } + + bool operator<(const ClassAndSelStr &rhs) const { + if (class_addr < rhs.class_addr) + return true; + else if (class_addr > rhs.class_addr) + return false; + else + return ConstString::Compare(sel_name, rhs.sel_name); + } + + lldb::addr_t class_addr = LLDB_INVALID_ADDRESS; + ConstString sel_name; }; typedef std::map<ClassAndSel, lldb::addr_t> MsgImplMap; + typedef std::map<ClassAndSelStr, lldb::addr_t> MsgImplStrMap; typedef std::map<ObjCISA, ClassDescriptorSP> ISAToDescriptorMap; typedef std::multimap<uint32_t, ObjCISA> HashToISAMap; typedef ISAToDescriptorMap::iterator ISAToDescriptorIterator; @@ -391,6 +426,7 @@ private: typedef ThreadSafeDenseMap<void *, uint64_t> TypeSizeCache; MsgImplMap m_impl_cache; + MsgImplStrMap m_impl_str_cache; LazyBool m_has_new_literals_and_indexing; ISAToDescriptorMap m_isa_to_descriptor; HashToISAMap m_hash_to_isa_map; 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 c990c733d24c..7078c059adc7 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 @@ -22,6 +22,7 @@ #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "RenderScriptExpressionOpts.h" @@ -77,8 +78,7 @@ static bool registerRSDefaultTargetOpts(clang::TargetOptions &proto, bool RenderScriptRuntimeModulePass::runOnModule(llvm::Module &module) { bool changed_module = false; - Log *log( - GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Language | LLDBLog::Expressions); std::string err; llvm::StringRef real_triple = diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h index e0b4f388dcc5..61af4dc1d764 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h @@ -11,6 +11,7 @@ #include "llvm/IR/Module.h" #include "llvm/MC/TargetRegistry.h" +#include "llvm/Pass.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" 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 d6de65809c18..bc8e43764af6 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 @@ -32,6 +32,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/Args.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/RegularExpression.h" @@ -120,7 +121,7 @@ struct GetArgsCtx { }; bool GetArgsX86(const GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) { - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE); + Log *log = GetLog(LLDBLog::Language); Status err; @@ -148,7 +149,7 @@ bool GetArgsX86(const GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) { } bool GetArgsX86_64(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) { - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE); + Log *log = GetLog(LLDBLog::Language); // number of arguments passed in registers static const uint32_t args_in_reg = 6; @@ -224,7 +225,7 @@ bool GetArgsArm(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) { // number of arguments passed in registers static const uint32_t args_in_reg = 4; - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE); + Log *log = GetLog(LLDBLog::Language); Status err; @@ -268,7 +269,7 @@ bool GetArgsAarch64(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) { // number of arguments passed in registers static const uint32_t args_in_reg = 8; - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE); + Log *log = GetLog(LLDBLog::Language); for (size_t i = 0; i < num_args; ++i) { bool success = false; @@ -301,7 +302,7 @@ bool GetArgsMipsel(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) { // register file offset to first argument static const uint32_t reg_offset = 4; - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE); + Log *log = GetLog(LLDBLog::Language); Status err; @@ -346,7 +347,7 @@ bool GetArgsMips64el(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) { // register file offset to first argument static const uint32_t reg_offset = 4; - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE); + Log *log = GetLog(LLDBLog::Language); Status err; @@ -388,7 +389,7 @@ bool GetArgsMips64el(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) { } bool GetArgs(ExecutionContext &exe_ctx, ArgItem *arg_list, size_t num_args) { - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE); + Log *log = GetLog(LLDBLog::Language); // verify that we have a target if (!exe_ctx.GetTargetPtr()) { @@ -465,7 +466,7 @@ bool ParseCoordinate(llvm::StringRef coord_s, RSCoordinate &coord) { } bool SkipPrologue(lldb::ModuleSP &module, Address &addr) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + Log *log = GetLog(LLDBLog::Language); SymbolContext sc; uint32_t resolved_flags = module->ResolveSymbolContextForAddress(addr, eSymbolContextFunction, sc); @@ -833,7 +834,7 @@ RSReduceBreakpointResolver::SearchCallback(lldb_private::SearchFilter &filter, // identifiable by parsing the .rs.info packet, or finding the expand symbol. // We therefore need access to the list of parsed rs modules to properly // resolve reduction names. - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); ModuleSP module = context.module_sp; if (!module || !IsRenderScriptScriptModule(module)) @@ -893,7 +894,7 @@ Searcher::CallbackReturn RSScriptGroupBreakpointResolver::SearchCallback( if (!breakpoint_sp) return eCallbackReturnContinue; - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); ModuleSP &module = context.module_sp; if (!module || !IsRenderScriptScriptModule(module)) @@ -1105,7 +1106,7 @@ bool RenderScriptRuntime::HookCallback(void *baton, void RenderScriptRuntime::HookCallback(RuntimeHook *hook, ExecutionContext &exe_ctx) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + Log *log = GetLog(LLDBLog::Language); LLDB_LOGF(log, "%s - '%s'", __FUNCTION__, hook->defn->name); @@ -1116,7 +1117,7 @@ void RenderScriptRuntime::HookCallback(RuntimeHook *hook, void RenderScriptRuntime::CaptureDebugHintScriptGroup2( RuntimeHook *hook_info, ExecutionContext &context) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + Log *log = GetLog(LLDBLog::Language); enum { eGroupName = 0, @@ -1254,7 +1255,7 @@ void RenderScriptRuntime::CaptureDebugHintScriptGroup2( void RenderScriptRuntime::CaptureScriptInvokeForEachMulti( RuntimeHook *hook, ExecutionContext &exe_ctx) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + Log *log = GetLog(LLDBLog::Language); enum { eRsContext = 0, @@ -1354,7 +1355,7 @@ void RenderScriptRuntime::CaptureScriptInvokeForEachMulti( void RenderScriptRuntime::CaptureSetGlobalVar(RuntimeHook *hook, ExecutionContext &context) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + Log *log = GetLog(LLDBLog::Language); enum { eRsContext, @@ -1401,7 +1402,7 @@ void RenderScriptRuntime::CaptureSetGlobalVar(RuntimeHook *hook, void RenderScriptRuntime::CaptureAllocationInit(RuntimeHook *hook, ExecutionContext &exe_ctx) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + Log *log = GetLog(LLDBLog::Language); enum { eRsContext, eRsAlloc, eRsForceZero }; @@ -1429,7 +1430,7 @@ void RenderScriptRuntime::CaptureAllocationInit(RuntimeHook *hook, void RenderScriptRuntime::CaptureAllocationDestroy(RuntimeHook *hook, ExecutionContext &exe_ctx) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + Log *log = GetLog(LLDBLog::Language); enum { eRsContext, @@ -1466,7 +1467,7 @@ void RenderScriptRuntime::CaptureAllocationDestroy(RuntimeHook *hook, void RenderScriptRuntime::CaptureScriptInit(RuntimeHook *hook, ExecutionContext &exe_ctx) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + Log *log = GetLog(LLDBLog::Language); Status err; Process *process = exe_ctx.GetProcessPtr(); @@ -1527,7 +1528,7 @@ void RenderScriptRuntime::CaptureScriptInit(RuntimeHook *hook, void RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + Log *log = GetLog(LLDBLog::Language); if (!module) { return; @@ -1619,7 +1620,7 @@ void RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp) { if (!rsmodule_sp) return; - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + Log *log = GetLog(LLDBLog::Language); const ModuleSP module = rsmodule_sp->m_module; const FileSpec &file = module->GetPlatformFileSpec(); @@ -1675,7 +1676,7 @@ void RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp) { bool RenderScriptRuntime::EvalRSExpression(const char *expr, StackFrame *frame_ptr, uint64_t *result) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + Log *log = GetLog(LLDBLog::Language); LLDB_LOGF(log, "%s(%s)", __FUNCTION__, expr); ValueObjectSP expr_result; @@ -1822,7 +1823,7 @@ const char *JITTemplate(ExpressionStrings e) { bool RenderScriptRuntime::JITDataPointer(AllocationDetails *alloc, StackFrame *frame_ptr, uint32_t x, uint32_t y, uint32_t z) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + Log *log = GetLog(LLDBLog::Language); if (!alloc->address.isValid()) { LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__); @@ -1857,7 +1858,7 @@ bool RenderScriptRuntime::JITDataPointer(AllocationDetails *alloc, // success, false otherwise bool RenderScriptRuntime::JITTypePointer(AllocationDetails *alloc, StackFrame *frame_ptr) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + Log *log = GetLog(LLDBLog::Language); if (!alloc->address.isValid() || !alloc->context.isValid()) { LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__); @@ -1892,7 +1893,7 @@ bool RenderScriptRuntime::JITTypePointer(AllocationDetails *alloc, // the result. Returns true on success, false otherwise bool RenderScriptRuntime::JITTypePacked(AllocationDetails *alloc, StackFrame *frame_ptr) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + Log *log = GetLog(LLDBLog::Language); if (!alloc->type_ptr.isValid() || !alloc->context.isValid()) { LLDB_LOGF(log, "%s - Failed to find allocation details.", __FUNCTION__); @@ -1953,7 +1954,7 @@ bool RenderScriptRuntime::JITTypePacked(AllocationDetails *alloc, bool RenderScriptRuntime::JITElementPacked(Element &elem, const lldb::addr_t context, StackFrame *frame_ptr) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + Log *log = GetLog(LLDBLog::Language); if (!elem.element_ptr.isValid()) { LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__); @@ -2010,7 +2011,7 @@ bool RenderScriptRuntime::JITElementPacked(Element &elem, bool RenderScriptRuntime::JITSubelements(Element &elem, const lldb::addr_t context, StackFrame *frame_ptr) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + Log *log = GetLog(LLDBLog::Language); if (!elem.element_ptr.isValid() || !elem.field_count.isValid()) { LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__); @@ -2093,7 +2094,7 @@ bool RenderScriptRuntime::JITSubelements(Element &elem, // allocation. Returns true on success, false otherwise bool RenderScriptRuntime::JITAllocationSize(AllocationDetails *alloc, StackFrame *frame_ptr) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + Log *log = GetLog(LLDBLog::Language); if (!alloc->address.isValid() || !alloc->dimension.isValid() || !alloc->data_ptr.isValid() || !alloc->element.datum_size.isValid()) { @@ -2159,7 +2160,7 @@ bool RenderScriptRuntime::JITAllocationSize(AllocationDetails *alloc, // 16-byte aligned. Returns true on success, false otherwise bool RenderScriptRuntime::JITAllocationStride(AllocationDetails *alloc, StackFrame *frame_ptr) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + Log *log = GetLog(LLDBLog::Language); if (!alloc->address.isValid() || !alloc->data_ptr.isValid()) { LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__); @@ -2220,7 +2221,7 @@ bool RenderScriptRuntime::RefreshAllocation(AllocationDetails *alloc, // represents. We need this string for pretty printing the Element to users. void RenderScriptRuntime::FindStructTypeName(Element &elem, StackFrame *frame_ptr) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + Log *log = GetLog(LLDBLog::Language); if (!elem.type_name.IsEmpty()) // Name already set return; @@ -2304,7 +2305,7 @@ void RenderScriptRuntime::FindStructTypeName(Element &elem, // single instance including padding. Assumes the relevant allocation // information has already been jitted. void RenderScriptRuntime::SetElementSize(Element &elem) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + Log *log = GetLog(LLDBLog::Language); const Element::DataType type = *elem.type.get(); assert(type >= Element::RS_TYPE_NONE && type <= Element::RS_TYPE_FONT && "Invalid allocation type"); @@ -2348,7 +2349,7 @@ void RenderScriptRuntime::SetElementSize(Element &elem) { std::shared_ptr<uint8_t> RenderScriptRuntime::GetAllocationData(AllocationDetails *alloc, StackFrame *frame_ptr) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + Log *log = GetLog(LLDBLog::Language); // JIT all the allocation details if (alloc->ShouldRefresh()) { @@ -2396,7 +2397,7 @@ RenderScriptRuntime::GetAllocationData(AllocationDetails *alloc, bool RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id, const char *path, StackFrame *frame_ptr) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + Log *log = GetLog(LLDBLog::Language); // Find allocation with the given id AllocationDetails *alloc = FindAllocByID(strm, alloc_id); @@ -2441,7 +2442,7 @@ bool RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id, auto data_sp = FileSystem::Instance().CreateDataBuffer(file.GetPath()); // Cast start of buffer to FileHeader and use pointer to read metadata - void *file_buf = data_sp->GetBytes(); + const void *file_buf = data_sp->GetBytes(); if (file_buf == nullptr || data_sp->GetByteSize() < (sizeof(AllocationDetails::FileHeader) + sizeof(AllocationDetails::ElementHeader))) { @@ -2450,7 +2451,7 @@ bool RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id, return false; } const AllocationDetails::FileHeader *file_header = - static_cast<AllocationDetails::FileHeader *>(file_buf); + static_cast<const AllocationDetails::FileHeader *>(file_buf); // Check file starts with ascii characters "RSAD" if (memcmp(file_header->ident, "RSAD", 4)) { @@ -2462,8 +2463,9 @@ bool RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id, // Look at the type of the root element in the header AllocationDetails::ElementHeader root_el_hdr; - memcpy(&root_el_hdr, static_cast<uint8_t *>(file_buf) + - sizeof(AllocationDetails::FileHeader), + memcpy(&root_el_hdr, + static_cast<const uint8_t *>(file_buf) + + sizeof(AllocationDetails::FileHeader), sizeof(AllocationDetails::ElementHeader)); LLDB_LOGF(log, "%s - header type %" PRIu32 ", element size %" PRIu32, @@ -2514,7 +2516,7 @@ bool RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id, } // Advance buffer past header - file_buf = static_cast<uint8_t *>(file_buf) + file_header->hdr_size; + file_buf = static_cast<const uint8_t *>(file_buf) + file_header->hdr_size; // Calculate size of allocation data in file size_t size = data_sp->GetByteSize() - file_header->hdr_size; @@ -2616,7 +2618,7 @@ size_t RenderScriptRuntime::CalculateElementHeaderSize(const Element &elem) { bool RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, const char *path, StackFrame *frame_ptr) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + Log *log = GetLog(LLDBLog::Language); // Find allocation with the given id AllocationDetails *alloc = FindAllocByID(strm, alloc_id); @@ -2735,7 +2737,7 @@ bool RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, } bool RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + Log *log = GetLog(LLDBLog::Language); if (module_sp) { for (const auto &rs_module : m_rsmodules) { @@ -2867,7 +2869,7 @@ bool RSModuleDescriptor::ParseExportReduceCount(llvm::StringRef *lines, // a function is not explicitly named by the user, or is not generated by the // compiler, it is named "." so the dash separated list should always be 8 // items long - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE); + Log *log = GetLog(LLDBLog::Language); // Skip the exportReduceCount line ++lines; for (; n_lines--; ++lines) { @@ -2958,7 +2960,7 @@ bool RSModuleDescriptor::ParseExportVarCount(llvm::StringRef *lines, // be parsed. The string is basic and is parsed on a line by line basis. bool RSModuleDescriptor::ParseRSInfo() { assert(m_module); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + Log *log = GetLog(LLDBLog::Language); const Symbol *info_sym = m_module->FindFirstSymbolWithNameAndType( ConstString(".rs.info"), eSymbolTypeData); if (!info_sym) @@ -3165,7 +3167,7 @@ RenderScriptRuntime::FindAllocByID(Stream &strm, const uint32_t alloc_id) { // file bool RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame *frame_ptr, const uint32_t id) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + Log *log = GetLog(LLDBLog::Language); // Check we can find the desired allocation AllocationDetails *alloc = FindAllocByID(strm, id); @@ -3453,8 +3455,7 @@ void RenderScriptRuntime::BreakOnModuleKernels( // or disable breaking on all kernels. When do_break is true we want to enable // this functionality. When do_break is false we want to disable it. void RenderScriptRuntime::SetBreakAllKernels(bool do_break, TargetSP target) { - Log *log( - GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Language | LLDBLog::Breakpoints); InitSearchFilter(target); @@ -3482,8 +3483,7 @@ void RenderScriptRuntime::SetBreakAllKernels(bool do_break, TargetSP target) { // breakpoint resolver, and returns the Breakpoint shared pointer. BreakpointSP RenderScriptRuntime::CreateKernelBreakpoint(ConstString name) { - Log *log( - GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Language | LLDBLog::Breakpoints); if (!m_filtersp) { LLDB_LOGF(log, "%s - error, no breakpoint search filter set.", @@ -3510,8 +3510,7 @@ RenderScriptRuntime::CreateKernelBreakpoint(ConstString name) { BreakpointSP RenderScriptRuntime::CreateReductionBreakpoint(ConstString name, int kernel_types) { - Log *log( - GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Language | LLDBLog::Breakpoints); if (!m_filtersp) { LLDB_LOGF(log, "%s - error, no breakpoint search filter set.", @@ -3542,7 +3541,7 @@ RenderScriptRuntime::CreateReductionBreakpoint(ConstString name, bool RenderScriptRuntime::GetFrameVarAsUnsigned(const StackFrameSP frame_sp, const char *var_name, uint64_t &val) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + Log *log = GetLog(LLDBLog::Language); Status err; VariableSP var_sp; @@ -3580,7 +3579,7 @@ bool RenderScriptRuntime::GetKernelCoordinate(RSCoordinate &coord, static const char *const y_expr = "p->current.y"; static const char *const z_expr = "p->current.z"; - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + Log *log = GetLog(LLDBLog::Language); if (!thread_ptr) { LLDB_LOGF(log, "%s - Error, No thread pointer", __FUNCTION__); @@ -3646,8 +3645,7 @@ bool RenderScriptRuntime::KernelBreakpointHit(void *baton, StoppointCallbackContext *ctx, user_id_t break_id, user_id_t break_loc_id) { - Log *log( - GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Language | LLDBLog::Breakpoints); assert(baton && "Error: null baton in conditional kernel breakpoint callback"); @@ -3742,8 +3740,7 @@ bool RenderScriptRuntime::PlaceBreakpointOnKernel(TargetSP target, BreakpointSP RenderScriptRuntime::CreateScriptGroupBreakpoint(ConstString name, bool stop_on_all) { - Log *log( - GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Language | LLDBLog::Breakpoints); if (!m_filtersp) { LLDB_LOGF(log, "%s - error, no breakpoint search filter set.", @@ -3839,7 +3836,7 @@ RenderScriptRuntime::LookUpAllocation(addr_t address) { RenderScriptRuntime::AllocationDetails * RenderScriptRuntime::CreateAllocation(addr_t address) { - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE); + Log *log = GetLog(LLDBLog::Language); // Remove any previous allocation which contains the same address auto it = m_allocations.begin(); @@ -3862,7 +3859,7 @@ RenderScriptRuntime::CreateAllocation(addr_t address) { bool RenderScriptRuntime::ResolveKernelName(lldb::addr_t kernel_addr, ConstString &name) { - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS); + Log *log = GetLog(LLDBLog::Symbols); Target &target = GetProcess()->GetTarget(); Address resolved; @@ -4070,7 +4067,10 @@ public: "<reduction_kernel_type,...>]", eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused), - m_options(){}; + m_options() { + CommandArgumentData name_arg{eArgTypeName, eArgRepeatPlain}; + m_arguments.push_back({name_arg}); + }; class CommandOptions : public Options { public: @@ -4219,7 +4219,10 @@ public: "renderscript kernel breakpoint set <kernel_name> [-c x,y,z]", eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused), - m_options() {} + m_options() { + CommandArgumentData name_arg{eArgTypeName, eArgRepeatPlain}; + m_arguments.push_back({name_arg}); + } ~CommandObjectRenderScriptRuntimeKernelBreakpointSet() override = default; @@ -4314,7 +4317,10 @@ public: "but does not remove currently set breakpoints.", "renderscript kernel breakpoint all <enable/disable>", eCommandRequiresProcess | eCommandProcessMustBeLaunched | - eCommandProcessMustBePaused) {} + eCommandProcessMustBePaused) { + CommandArgumentData enable_arg{eArgTypeNone, eArgRepeatPlain}; + m_arguments.push_back({enable_arg}); + } ~CommandObjectRenderScriptRuntimeKernelBreakpointAll() override = default; @@ -4496,7 +4502,10 @@ public: "renderscript allocation dump <ID>", eCommandRequiresProcess | eCommandProcessMustBeLaunched), - m_options() {} + m_options() { + CommandArgumentData id_arg{eArgTypeUnsignedInteger, eArgRepeatPlain}; + m_arguments.push_back({id_arg}); + } ~CommandObjectRenderScriptRuntimeAllocationDump() override = default; @@ -4682,7 +4691,12 @@ public: interpreter, "renderscript allocation load", "Loads renderscript allocation contents from a file.", "renderscript allocation load <ID> <filename>", - eCommandRequiresProcess | eCommandProcessMustBeLaunched) {} + eCommandRequiresProcess | eCommandProcessMustBeLaunched) { + CommandArgumentData id_arg{eArgTypeUnsignedInteger, eArgRepeatPlain}; + CommandArgumentData name_arg{eArgTypeFilename, eArgRepeatPlain}; + m_arguments.push_back({id_arg}); + m_arguments.push_back({name_arg}); + } ~CommandObjectRenderScriptRuntimeAllocationLoad() override = default; @@ -4729,7 +4743,12 @@ public: "Write renderscript allocation contents to a file.", "renderscript allocation save <ID> <filename>", eCommandRequiresProcess | - eCommandProcessMustBeLaunched) {} + eCommandProcessMustBeLaunched) { + CommandArgumentData id_arg{eArgTypeUnsignedInteger, eArgRepeatPlain}; + CommandArgumentData name_arg{eArgTypeFilename, eArgRepeatPlain}; + m_arguments.push_back({id_arg}); + m_arguments.push_back({name_arg}); + } ~CommandObjectRenderScriptRuntimeAllocationSave() override = default; diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp index b6f8b20c90c3..3eb2519dda9e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp @@ -39,7 +39,10 @@ public: interpreter, "renderscript scriptgroup breakpoint set", "Place a breakpoint on all kernels forming a script group.", "renderscript scriptgroup breakpoint set <group_name>", - eCommandRequiresProcess | eCommandProcessMustBeLaunched) {} + eCommandRequiresProcess | eCommandProcessMustBeLaunched) { + CommandArgumentData name_arg{eArgTypeName, eArgRepeatPlus}; + m_arguments.push_back({name_arg}); + } ~CommandObjectRenderScriptScriptGroupBreakpointSet() override = default; diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp index f3b7c9dd3edc..ec8f8d83c4b3 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp @@ -19,14 +19,14 @@ #include "llvm/Pass.h" #include "lldb/Target/Process.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" using namespace lldb_private; -static bool isRSAPICall(llvm::Module &module, llvm::CallInst *call_inst) { +static bool isRSAPICall(llvm::CallInst *call_inst) { // TODO get the list of renderscript modules from lldb and check if // this llvm::Module calls into any of them. - (void)module; const auto func_name = call_inst->getCalledFunction()->getName(); if (func_name.startswith("llvm") || func_name.startswith("lldb")) return false; @@ -37,8 +37,7 @@ static bool isRSAPICall(llvm::Module &module, llvm::CallInst *call_inst) { return true; } -static bool isRSLargeReturnCall(llvm::Module &module, - llvm::CallInst *call_inst) { +static bool isRSLargeReturnCall(llvm::CallInst *call_inst) { // i686 and x86_64 returns for large vectors in the RenderScript API are not // handled as normal register pairs, but as a hidden sret type. This is not // reflected in the debug info or mangled symbol name, and the android ABI @@ -49,7 +48,6 @@ static bool isRSLargeReturnCall(llvm::Module &module, // It is perhaps an unreliable heuristic, and relies on bcc not generating // AVX code, so if the android ABI one day provides for AVX, this function // may go out of fashion. - (void)module; if (!call_inst || !call_inst->getCalledFunction()) return false; @@ -58,23 +56,19 @@ static bool isRSLargeReturnCall(llvm::Module &module, ->getPrimitiveSizeInBits() > 128; } -static bool isRSAllocationPtrTy(const llvm::Type *type) { - if (!type->isPointerTy()) - return false; - auto ptr_type = type->getPointerElementType(); - - return ptr_type->isStructTy() && - ptr_type->getStructName().startswith("struct.rs_allocation"); +static bool isRSAllocationTy(const llvm::Type *type) { + return type->isStructTy() && + type->getStructName().startswith("struct.rs_allocation"); } -static bool isRSAllocationTyCallSite(llvm::Module &module, - llvm::CallInst *call_inst) { - (void)module; +static bool isRSAllocationTyCallSite(llvm::CallInst *call_inst) { if (!call_inst->hasByValArgument()) return false; - for (const auto *param : call_inst->operand_values()) - if (isRSAllocationPtrTy(param->getType())) - return true; + for (unsigned i = 0; i < call_inst->arg_size(); ++i) { + if (llvm::Type *ByValTy = call_inst->getParamByValType(i)) + if (isRSAllocationTy(ByValTy)) + return true; + } return false; } @@ -85,8 +79,7 @@ static llvm::FunctionType *cloneToStructRetFnTy(llvm::CallInst *call_inst) { // create a return type by getting the pointer type of the old return type, // and inserting a new initial argument of pointer type of the original // return type. - Log *log( - GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Language | LLDBLog::Expressions); assert(call_inst && "no CallInst"); llvm::Function *orig = call_inst->getCalledFunction(); @@ -125,7 +118,7 @@ static llvm::FunctionType *cloneToStructRetFnTy(llvm::CallInst *call_inst) { static bool findRSCallSites(llvm::Module &module, std::set<llvm::CallInst *> &rs_callsites, - bool (*predicate)(llvm::Module &, llvm::CallInst *)) { + bool (*predicate)(llvm::CallInst *)) { bool found = false; for (auto &func : module.getFunctionList()) @@ -136,7 +129,7 @@ findRSCallSites(llvm::Module &module, std::set<llvm::CallInst *> &rs_callsites, if (!call_inst || !call_inst->getCalledFunction()) // This is not the call-site you are looking for... continue; - if (isRSAPICall(module, call_inst) && predicate(module, call_inst)) { + if (isRSAPICall(call_inst) && predicate(call_inst)) { rs_callsites.insert(call_inst); found = true; } @@ -187,18 +180,17 @@ static bool fixupX86StructRetCalls(llvm::Module &module) { (new llvm::StoreInst(new_func_cast, new_func_ptr, call_inst)) ->setName("new_func_ptr_load_cast"); // load the new function address ready for a jump - llvm::LoadInst *new_func_addr_load = - new llvm::LoadInst(new_func_ptr->getType()->getPointerElementType(), - new_func_ptr, "load_func_pointer", call_inst); + llvm::LoadInst *new_func_addr_load = new llvm::LoadInst( + new_func_ptr_type, new_func_ptr, "load_func_pointer", call_inst); // and create a callinstruction from it llvm::CallInst *new_call_inst = llvm::CallInst::Create(new_func_type, new_func_addr_load, new_call_args, "new_func_call", call_inst); new_call_inst->setCallingConv(call_inst->getCallingConv()); new_call_inst->setTailCall(call_inst->isTailCall()); - llvm::LoadInst *lldb_save_result_address = new llvm::LoadInst( - return_value_alloc->getType()->getPointerElementType(), - return_value_alloc, "save_return_val", call_inst); + llvm::LoadInst *lldb_save_result_address = + new llvm::LoadInst(func->getReturnType(), return_value_alloc, + "save_return_val", call_inst); // Now remove the old broken call call_inst->replaceAllUsesWith(lldb_save_result_address); diff --git a/contrib/llvm-project/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp b/contrib/llvm-project/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp index 14d9c4024689..aaead88369b2 100644 --- a/contrib/llvm-project/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp @@ -72,7 +72,7 @@ const char *memory_history_asan_command_prefix = R"( void *alloc_trace[256]; size_t alloc_count; int alloc_tid; - + void *free_trace[256]; size_t free_count; int free_tid; @@ -179,9 +179,11 @@ HistoryThreads MemoryHistoryASan::GetHistoryThreads(lldb::addr_t address) { ExpressionResults expr_result = UserExpression::Evaluate( exe_ctx, options, expr.GetString(), "", return_value_sp, eval_error); if (expr_result != eExpressionCompleted) { - process_sp->GetTarget().GetDebugger().GetAsyncOutputStream()->Printf( - "Warning: Cannot evaluate AddressSanitizer expression:\n%s\n", - eval_error.AsCString()); + StreamString ss; + ss << "cannot evaluate AddressSanitizer expression:\n"; + ss << eval_error.AsCString(); + Debugger::ReportWarning(ss.GetString().str(), + process_sp->GetTarget().GetDebugger().GetID()); return result; } diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp index ce701fd823fd..c591a4a7534c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp @@ -57,7 +57,7 @@ void ObjectFileBreakpad::Terminate() { } ObjectFile *ObjectFileBreakpad::CreateInstance( - const ModuleSP &module_sp, DataBufferSP &data_sp, offset_t data_offset, + const ModuleSP &module_sp, DataBufferSP data_sp, offset_t data_offset, const FileSpec *file, offset_t file_offset, offset_t length) { if (!data_sp) { data_sp = MapFileData(*file, length, file_offset); @@ -84,7 +84,7 @@ ObjectFile *ObjectFileBreakpad::CreateInstance( } ObjectFile *ObjectFileBreakpad::CreateMemoryInstance( - const ModuleSP &module_sp, DataBufferSP &data_sp, + const ModuleSP &module_sp, WritableDataBufferSP data_sp, const ProcessSP &process_sp, addr_t header_addr) { return nullptr; } diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h index f04e0b4dd7a7..074d667c1ca5 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h @@ -27,12 +27,12 @@ public: } static ObjectFile * - CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, + CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp, lldb::offset_t data_offset, const FileSpec *file, lldb::offset_t file_offset, lldb::offset_t length); static ObjectFile *CreateMemoryInstance(const lldb::ModuleSP &module_sp, - lldb::DataBufferSP &data_sp, + lldb::WritableDataBufferSP data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr); diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp index f0496beba2ef..abda0cd0e9a3 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp @@ -208,6 +208,9 @@ unsigned ELFHeader::GetRelocationJumpSlotType() const { case EM_S390: slot = R_390_JMP_SLOT; break; + case EM_RISCV: + slot = R_RISCV_JUMP_SLOT; + break; } return slot; 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 96e94ef08a45..28ccfbe3d6e6 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -26,6 +26,7 @@ #include "lldb/Target/Target.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RangeMap.h" #include "lldb/Utility/Status.h" @@ -235,7 +236,7 @@ bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) { const char *cstr = data.GetCStr(offset, llvm::alignTo(n_namesz, 4)); if (cstr == nullptr) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS)); + Log *log = GetLog(LLDBLog::Symbols); LLDB_LOGF(log, "Failed to parse note name lacking nul terminator"); return false; @@ -309,9 +310,19 @@ static uint32_t riscvVariantFromElfFlags(const elf::ELFHeader &header) { } } +static uint32_t ppc64VariantFromElfFlags(const elf::ELFHeader &header) { + uint32_t endian = header.e_ident[EI_DATA]; + if (endian == ELFDATA2LSB) + return ArchSpec::eCore_ppc64le_generic; + else + return ArchSpec::eCore_ppc64_generic; +} + static uint32_t subTypeFromElfHeader(const elf::ELFHeader &header) { if (header.e_machine == llvm::ELF::EM_MIPS) return mipsVariantFromElfFlags(header); + else if (header.e_machine == llvm::ELF::EM_PPC64) + return ppc64VariantFromElfFlags(header); else if (header.e_machine == llvm::ELF::EM_RISCV) return riscvVariantFromElfFlags(header); @@ -335,16 +346,18 @@ void ObjectFileELF::Terminate() { } ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp, - DataBufferSP &data_sp, + DataBufferSP data_sp, lldb::offset_t data_offset, const lldb_private::FileSpec *file, lldb::offset_t file_offset, lldb::offset_t length) { + bool mapped_writable = false; if (!data_sp) { - data_sp = MapFileData(*file, length, file_offset); + data_sp = MapFileDataWritable(*file, length, file_offset); if (!data_sp) return nullptr; data_offset = 0; + mapped_writable = true; } assert(data_sp); @@ -358,10 +371,19 @@ ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp, // Update the data to contain the entire file if it doesn't already if (data_sp->GetByteSize() < length) { - data_sp = MapFileData(*file, length, file_offset); + data_sp = MapFileDataWritable(*file, length, file_offset); if (!data_sp) return nullptr; data_offset = 0; + mapped_writable = true; + magic = data_sp->GetBytes(); + } + + // If we didn't map the data as writable take ownership of the buffer. + if (!mapped_writable) { + data_sp = std::make_shared<DataBufferHeap>(data_sp->GetBytes(), + data_sp->GetByteSize()); + data_offset = 0; magic = data_sp->GetBytes(); } @@ -378,7 +400,7 @@ ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp, } ObjectFile *ObjectFileELF::CreateMemoryInstance( - const lldb::ModuleSP &module_sp, DataBufferSP &data_sp, + const lldb::ModuleSP &module_sp, WritableDataBufferSP data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr) { if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT)) { const uint8_t *magic = data_sp->GetBytes(); @@ -504,7 +526,7 @@ size_t ObjectFileELF::GetModuleSpecifications( const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp, lldb::offset_t data_offset, lldb::offset_t file_offset, lldb::offset_t length, lldb_private::ModuleSpecList &specs) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES)); + Log *log = GetLog(LLDBLog::Modules); const size_t initial_count = specs.GetSize(); @@ -627,7 +649,7 @@ size_t ObjectFileELF::GetModuleSpecifications( // ObjectFile protocol ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp, - DataBufferSP &data_sp, lldb::offset_t data_offset, + DataBufferSP data_sp, lldb::offset_t data_offset, const FileSpec *file, lldb::offset_t file_offset, lldb::offset_t length) : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset) { @@ -636,7 +658,7 @@ ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp, } ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp, - DataBufferSP &header_data_sp, + DataBufferSP header_data_sp, const lldb::ProcessSP &process_sp, addr_t header_addr) : ObjectFile(module_sp, process_sp, header_addr, header_data_sp) {} @@ -998,7 +1020,7 @@ lldb_private::Status ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data, lldb_private::ArchSpec &arch_spec, lldb_private::UUID &uuid) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES)); + Log *log = GetLog(LLDBLog::Modules); Status error; lldb::offset_t offset = 0; @@ -1174,26 +1196,28 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data, // register info arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux); } else if (note.n_name == LLDB_NT_OWNER_CORE) { - // Parse the NT_FILE to look for stuff in paths to shared libraries As - // the contents look like this in a 64 bit ELF core file: count = - // 0x000000000000000a (10) page_size = 0x0000000000001000 (4096) Index - // start end file_ofs path ===== - // 0x0000000000401000 0x0000000000000000 /tmp/a.out [ 1] - // 0x0000000000600000 0x0000000000601000 0x0000000000000000 /tmp/a.out [ - // 2] 0x0000000000601000 0x0000000000602000 0x0000000000000001 /tmp/a.out - // [ 3] 0x00007fa79c9ed000 0x00007fa79cba8000 0x0000000000000000 - // /lib/x86_64-linux-gnu/libc-2.19.so [ 4] 0x00007fa79cba8000 - // 0x00007fa79cda7000 0x00000000000001bb /lib/x86_64-linux- - // gnu/libc-2.19.so [ 5] 0x00007fa79cda7000 0x00007fa79cdab000 - // 0x00000000000001ba /lib/x86_64-linux-gnu/libc-2.19.so [ 6] - // 0x00007fa79cdab000 0x00007fa79cdad000 0x00000000000001be /lib/x86_64 - // -linux-gnu/libc-2.19.so [ 7] 0x00007fa79cdb2000 0x00007fa79cdd5000 - // 0x0000000000000000 /lib/x86_64-linux-gnu/ld-2.19.so [ 8] - // 0x00007fa79cfd4000 0x00007fa79cfd5000 0x0000000000000022 /lib/x86_64 - // -linux-gnu/ld-2.19.so [ 9] 0x00007fa79cfd5000 0x00007fa79cfd6000 - // 0x0000000000000023 /lib/x86_64-linux-gnu/ld-2.19.so In the 32 bit ELFs - // the count, page_size, start, end, file_ofs are uint32_t For reference: - // see readelf source code (in binutils). + // Parse the NT_FILE to look for stuff in paths to shared libraries + // The contents look like this in a 64 bit ELF core file: + // + // count = 0x000000000000000a (10) + // page_size = 0x0000000000001000 (4096) + // Index start end file_ofs path + // ===== ------------------ ------------------ ------------------ ------------------------------------- + // [ 0] 0x0000000000401000 0x0000000000000000 /tmp/a.out + // [ 1] 0x0000000000600000 0x0000000000601000 0x0000000000000000 /tmp/a.out + // [ 2] 0x0000000000601000 0x0000000000602000 0x0000000000000001 /tmp/a.out + // [ 3] 0x00007fa79c9ed000 0x00007fa79cba8000 0x0000000000000000 /lib/x86_64-linux-gnu/libc-2.19.so + // [ 4] 0x00007fa79cba8000 0x00007fa79cda7000 0x00000000000001bb /lib/x86_64-linux-gnu/libc-2.19.so + // [ 5] 0x00007fa79cda7000 0x00007fa79cdab000 0x00000000000001ba /lib/x86_64-linux-gnu/libc-2.19.so + // [ 6] 0x00007fa79cdab000 0x00007fa79cdad000 0x00000000000001be /lib/x86_64-linux-gnu/libc-2.19.so + // [ 7] 0x00007fa79cdb2000 0x00007fa79cdd5000 0x0000000000000000 /lib/x86_64-linux-gnu/ld-2.19.so + // [ 8] 0x00007fa79cfd4000 0x00007fa79cfd5000 0x0000000000000022 /lib/x86_64-linux-gnu/ld-2.19.so + // [ 9] 0x00007fa79cfd5000 0x00007fa79cfd6000 0x0000000000000023 /lib/x86_64-linux-gnu/ld-2.19.so + // + // In the 32 bit ELFs the count, page_size, start, end, file_ofs are + // uint32_t. + // + // For reference: see readelf source code (in binutils). if (note.n_type == NT_FILE) { uint64_t count = data.GetAddress(&offset); const char *cstr; @@ -1361,11 +1385,33 @@ size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers, arch_spec.SetFlags(ArchSpec::eARM_abi_hard_float); } + if (arch_spec.GetMachine() == llvm::Triple::riscv32 || + arch_spec.GetMachine() == llvm::Triple::riscv64) { + uint32_t flags = arch_spec.GetFlags(); + + if (header.e_flags & llvm::ELF::EF_RISCV_RVC) + flags |= ArchSpec::eRISCV_rvc; + if (header.e_flags & llvm::ELF::EF_RISCV_RVE) + flags |= ArchSpec::eRISCV_rve; + + if ((header.e_flags & llvm::ELF::EF_RISCV_FLOAT_ABI_SINGLE) == + llvm::ELF::EF_RISCV_FLOAT_ABI_SINGLE) + flags |= ArchSpec::eRISCV_float_abi_single; + else if ((header.e_flags & llvm::ELF::EF_RISCV_FLOAT_ABI_DOUBLE) == + llvm::ELF::EF_RISCV_FLOAT_ABI_DOUBLE) + flags |= ArchSpec::eRISCV_float_abi_double; + else if ((header.e_flags & llvm::ELF::EF_RISCV_FLOAT_ABI_QUAD) == + llvm::ELF::EF_RISCV_FLOAT_ABI_QUAD) + flags |= ArchSpec::eRISCV_float_abi_quad; + + arch_spec.SetFlags(flags); + } + // If there are no section headers we are done. if (header.e_shnum == 0) return 0; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES)); + Log *log = GetLog(LLDBLog::Modules); section_headers.resize(header.e_shnum); if (section_headers.size() != header.e_shnum) @@ -1678,9 +1724,9 @@ class VMAddressProvider { ObjectFile::Type ObjectType; addr_t NextVMAddress = 0; VMMap::Allocator Alloc; - VMMap Segments = VMMap(Alloc); - VMMap Sections = VMMap(Alloc); - lldb_private::Log *Log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES); + VMMap Segments{Alloc}; + VMMap Sections{Alloc}; + lldb_private::Log *Log = GetLog(LLDBLog::Modules); size_t SegmentCount = 0; std::string SegmentName; @@ -2596,8 +2642,11 @@ unsigned ObjectFileELF::ApplyRelocations( if (symbol) { addr_t value = symbol->GetAddressRef().GetFileAddress(); DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer(); + // ObjectFileELF creates a WritableDataBuffer in CreateInstance. + WritableDataBuffer *data_buffer = + llvm::cast<WritableDataBuffer>(data_buffer_sp.get()); uint64_t *dst = reinterpret_cast<uint64_t *>( - data_buffer_sp->GetBytes() + rel_section->GetFileOffset() + + data_buffer->GetBytes() + rel_section->GetFileOffset() + ELFRelocation::RelocOffset64(rel)); uint64_t val_offset = value + ELFRelocation::RelocAddend64(rel); memcpy(dst, &val_offset, sizeof(uint64_t)); @@ -2616,15 +2665,17 @@ unsigned ObjectFileELF::ApplyRelocations( ((int64_t)value > INT32_MAX && (int64_t)value < INT32_MIN)) || (reloc_type(rel) == R_AARCH64_ABS32 && ((int64_t)value > INT32_MAX && (int64_t)value < INT32_MIN))) { - Log *log = - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES); + Log *log = GetLog(LLDBLog::Modules); LLDB_LOGF(log, "Failed to apply debug info relocations"); break; } uint32_t truncated_addr = (value & 0xFFFFFFFF); DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer(); + // ObjectFileELF creates a WritableDataBuffer in CreateInstance. + WritableDataBuffer *data_buffer = + llvm::cast<WritableDataBuffer>(data_buffer_sp.get()); uint32_t *dst = reinterpret_cast<uint32_t *>( - data_buffer_sp->GetBytes() + rel_section->GetFileOffset() + + data_buffer->GetBytes() + rel_section->GetFileOffset() + ELFRelocation::RelocOffset32(rel)); memcpy(dst, &truncated_addr, sizeof(uint32_t)); } @@ -3388,3 +3439,10 @@ ObjectFileELF::GetLoadableData(Target &target) { } return loadables; } + +lldb::WritableDataBufferSP +ObjectFileELF::MapFileDataWritable(const FileSpec &file, uint64_t Size, + uint64_t Offset) { + return FileSystem::Instance().CreateWritableDataBuffer(file.GetPath(), Size, + Offset); +} 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 554f623ec8af..5deb2c7d163c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h @@ -68,12 +68,12 @@ public: } static lldb_private::ObjectFile * - CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, + CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp, lldb::offset_t data_offset, const lldb_private::FileSpec *file, lldb::offset_t file_offset, lldb::offset_t length); static lldb_private::ObjectFile *CreateMemoryInstance( - const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, + const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr); static size_t GetModuleSpecifications(const lldb_private::FileSpec &file, @@ -159,13 +159,17 @@ protected: std::vector<LoadableData> GetLoadableData(lldb_private::Target &target) override; + static lldb::WritableDataBufferSP + MapFileDataWritable(const lldb_private::FileSpec &file, uint64_t Size, + uint64_t Offset); + private: - ObjectFileELF(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, + ObjectFileELF(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp, lldb::offset_t data_offset, const lldb_private::FileSpec *file, lldb::offset_t offset, lldb::offset_t length); ObjectFileELF(const lldb::ModuleSP &module_sp, - lldb::DataBufferSP &header_data_sp, + lldb::DataBufferSP header_data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr); typedef std::vector<elf::ELFProgramHeader> ProgramHeaderColl; 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 ca9337454889..2ea83e4b6883 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp @@ -54,7 +54,7 @@ void ObjectFileJIT::Terminate() { } ObjectFile *ObjectFileJIT::CreateInstance(const lldb::ModuleSP &module_sp, - DataBufferSP &data_sp, + DataBufferSP data_sp, lldb::offset_t data_offset, const FileSpec *file, lldb::offset_t file_offset, @@ -65,7 +65,7 @@ ObjectFile *ObjectFileJIT::CreateInstance(const lldb::ModuleSP &module_sp, } ObjectFile *ObjectFileJIT::CreateMemoryInstance(const lldb::ModuleSP &module_sp, - DataBufferSP &data_sp, + WritableDataBufferSP data_sp, const ProcessSP &process_sp, lldb::addr_t header_addr) { // JIT'ed object file is backed by the ObjectFileJITDelegate, never read from diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h index be31139df549..91fdd205eb20 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h @@ -33,12 +33,12 @@ public: } static lldb_private::ObjectFile * - CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, + CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp, lldb::offset_t data_offset, const lldb_private::FileSpec *file, lldb::offset_t file_offset, lldb::offset_t length); static lldb_private::ObjectFile *CreateMemoryInstance( - const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, + const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr); static size_t GetModuleSpecifications(const lldb_private::FileSpec &file, diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp index 715ccd311dee..17b37afe557d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp @@ -33,14 +33,14 @@ void ObjectFileMinidump::Terminate() { } ObjectFile *ObjectFileMinidump::CreateInstance( - const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, + const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp, lldb::offset_t data_offset, const lldb_private::FileSpec *file, lldb::offset_t offset, lldb::offset_t length) { return nullptr; } ObjectFile *ObjectFileMinidump::CreateMemoryInstance( - const lldb::ModuleSP &module_sp, DataBufferSP &data_sp, + const lldb::ModuleSP &module_sp, WritableDataBufferSP data_sp, const ProcessSP &process_sp, lldb::addr_t header_addr) { return nullptr; } diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.h b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.h index 3e4d55dc6c8c..b5c40445fe74 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.h +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.h @@ -38,12 +38,12 @@ public: llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } static lldb_private::ObjectFile * - CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, + CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp, lldb::offset_t data_offset, const lldb_private::FileSpec *file, lldb::offset_t offset, lldb::offset_t length); static lldb_private::ObjectFile *CreateMemoryInstance( - const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, + const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr); static size_t GetModuleSpecifications(const lldb_private::FileSpec &file, 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 b63cd8e70899..1c10efed9564 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp @@ -87,7 +87,7 @@ bool ObjectFilePDB::initPDBFile() { } ObjectFile * -ObjectFilePDB::CreateInstance(const ModuleSP &module_sp, DataBufferSP &data_sp, +ObjectFilePDB::CreateInstance(const ModuleSP &module_sp, DataBufferSP data_sp, offset_t data_offset, const FileSpec *file, offset_t file_offset, offset_t length) { auto objfile_up = std::make_unique<ObjectFilePDB>( @@ -98,7 +98,7 @@ ObjectFilePDB::CreateInstance(const ModuleSP &module_sp, DataBufferSP &data_sp, } ObjectFile *ObjectFilePDB::CreateMemoryInstance(const ModuleSP &module_sp, - DataBufferSP &data_sp, + WritableDataBufferSP data_sp, const ProcessSP &process_sp, addr_t header_addr) { return nullptr; diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h index a1a3eeb656dd..c06e72650e01 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h @@ -31,12 +31,12 @@ public: loadPDBFile(std::string PdbPath, llvm::BumpPtrAllocator &Allocator); static ObjectFile * - CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, + CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp, lldb::offset_t data_offset, const FileSpec *file, lldb::offset_t file_offset, lldb::offset_t length); static ObjectFile *CreateMemoryInstance(const lldb::ModuleSP &module_sp, - lldb::DataBufferSP &data_sp, + lldb::WritableDataBufferSP data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr); 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 7445f8311c50..905e9637493b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp @@ -15,6 +15,7 @@ #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" @@ -42,7 +43,7 @@ static bool ValidateModuleHeader(const DataBufferSP &data_sp) { llvm::file_magic::wasm_object) return false; - uint8_t *Ptr = data_sp->GetBytes() + sizeof(llvm::wasm::WasmMagic); + const uint8_t *Ptr = data_sp->GetBytes() + sizeof(llvm::wasm::WasmMagic); uint32_t version = llvm::support::endian::read32le(Ptr); return version == llvm::wasm::WasmVersion; @@ -87,10 +88,10 @@ void ObjectFileWasm::Terminate() { } ObjectFile * -ObjectFileWasm::CreateInstance(const ModuleSP &module_sp, DataBufferSP &data_sp, +ObjectFileWasm::CreateInstance(const ModuleSP &module_sp, DataBufferSP data_sp, offset_t data_offset, const FileSpec *file, offset_t file_offset, offset_t length) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); + Log *log = GetLog(LLDBLog::Object); if (!data_sp) { data_sp = MapFileData(*file, length, file_offset); @@ -140,7 +141,7 @@ ObjectFileWasm::CreateInstance(const ModuleSP &module_sp, DataBufferSP &data_sp, } ObjectFile *ObjectFileWasm::CreateMemoryInstance(const ModuleSP &module_sp, - DataBufferSP &data_sp, + WritableDataBufferSP data_sp, const ProcessSP &process_sp, addr_t header_addr) { if (!ValidateModuleHeader(data_sp)) @@ -191,7 +192,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_TAG) { + } else if (section_id <= llvm::wasm::WASM_SEC_LAST_KNOWN) { m_sect_infos.push_back(section_info{*offset_ptr + c.tell(), static_cast<uint32_t>(payload_len), section_id, ConstString()}); @@ -226,7 +227,7 @@ size_t ObjectFileWasm::GetModuleSpecifications( return 1; } -ObjectFileWasm::ObjectFileWasm(const ModuleSP &module_sp, DataBufferSP &data_sp, +ObjectFileWasm::ObjectFileWasm(const ModuleSP &module_sp, DataBufferSP data_sp, offset_t data_offset, const FileSpec *file, offset_t offset, offset_t length) : ObjectFile(module_sp, file, offset, length, data_sp, data_offset), @@ -235,7 +236,7 @@ ObjectFileWasm::ObjectFileWasm(const ModuleSP &module_sp, DataBufferSP &data_sp, } ObjectFileWasm::ObjectFileWasm(const lldb::ModuleSP &module_sp, - lldb::DataBufferSP &header_data_sp, + lldb::WritableDataBufferSP header_data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr) : ObjectFile(module_sp, process_sp, header_addr, header_data_sp), diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h index d7b5bc22caad..5676030f955e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h @@ -30,12 +30,12 @@ public: } static ObjectFile * - CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, + CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp, lldb::offset_t data_offset, const FileSpec *file, lldb::offset_t file_offset, lldb::offset_t length); static ObjectFile *CreateMemoryInstance(const lldb::ModuleSP &module_sp, - lldb::DataBufferSP &data_sp, + lldb::WritableDataBufferSP data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr); @@ -111,11 +111,11 @@ public: llvm::Optional<FileSpec> GetExternalDebugInfoFileSpec(); private: - ObjectFileWasm(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, + ObjectFileWasm(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp, lldb::offset_t data_offset, const FileSpec *file, lldb::offset_t offset, lldb::offset_t length); ObjectFileWasm(const lldb::ModuleSP &module_sp, - lldb::DataBufferSP &header_data_sp, + lldb::WritableDataBufferSP header_data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr); /// Wasm section decoding routines. 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 7d14f02e68f7..c22003f24f76 100644 --- a/contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp @@ -29,6 +29,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadList.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/StructuredData.h" @@ -115,7 +116,7 @@ DynamicRegisterInfo *OperatingSystemPython::GetDynamicRegisterInfo() { if (m_register_info_up == nullptr) { if (!m_interpreter || !m_python_object_sp) return nullptr; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS)); + Log *log = GetLog(LLDBLog::OS); LLDB_LOGF(log, "OperatingSystemPython::GetDynamicRegisterInfo() fetching " @@ -141,7 +142,7 @@ bool OperatingSystemPython::UpdateThreadList(ThreadList &old_thread_list, if (!m_interpreter || !m_python_object_sp) return false; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS)); + Log *log = GetLog(LLDBLog::OS); // First thing we have to do is to try to get the API lock, and the // interpreter lock. We're going to change the thread content of the process, @@ -301,7 +302,7 @@ OperatingSystemPython::CreateRegisterContextForThread(Thread *thread, (void)api_lock.try_lock(); // See above. auto interpreter_lock = m_interpreter->AcquireInterpreterLock(); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); if (reg_data_addr != LLDB_INVALID_ADDRESS) { // The registers data is in contiguous memory, just create the register @@ -363,7 +364,7 @@ OperatingSystemPython::CreateThreadStopReason(lldb_private::Thread *thread) { lldb::ThreadSP OperatingSystemPython::CreateThread(lldb::tid_t tid, addr_t context) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); LLDB_LOGF(log, "OperatingSystemPython::CreateThread (tid = 0x%" PRIx64 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 2bf0a44e4a3e..17c86a435aa8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp @@ -22,6 +22,7 @@ #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/State.h" #include "lldb/Utility/Status.h" @@ -45,7 +46,7 @@ static uint32_t g_initialize_count = 0; PlatformSP PlatformFreeBSD::CreateInstance(bool force, const ArchSpec *arch) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + Log *log = GetLog(LLDBLog::Platform); LLDB_LOG(log, "force = {0}, arch=({1}, {2})", force, arch ? arch->GetArchitectureName() : "<null>", arch ? arch->GetTriple().getTriple() : "<null>"); @@ -128,9 +129,10 @@ PlatformFreeBSD::PlatformFreeBSD(bool is_host) } } -std::vector<ArchSpec> PlatformFreeBSD::GetSupportedArchitectures() { +std::vector<ArchSpec> +PlatformFreeBSD::GetSupportedArchitectures(const ArchSpec &process_host_arch) { if (m_remote_platform_sp) - return m_remote_platform_sp->GetSupportedArchitectures(); + return m_remote_platform_sp->GetSupportedArchitectures(process_host_arch); return m_supported_architectures; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h b/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h index 7f9dfd87a59a..4aeedb62931d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h +++ b/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h @@ -43,7 +43,8 @@ public: void GetStatus(Stream &strm) override; - std::vector<ArchSpec> GetSupportedArchitectures() override; + std::vector<ArchSpec> + GetSupportedArchitectures(const ArchSpec &process_host_arch) override; bool CanDebugProcess() override; 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 ddba64bc5d11..d79fe664cb1c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp @@ -20,6 +20,7 @@ #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/State.h" #include "lldb/Utility/Status.h" @@ -40,7 +41,7 @@ static uint32_t g_initialize_count = 0; PlatformSP PlatformNetBSD::CreateInstance(bool force, const ArchSpec *arch) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + Log *log = GetLog(LLDBLog::Platform); LLDB_LOG(log, "force = {0}, arch=({1}, {2})", force, arch ? arch->GetArchitectureName() : "<null>", arch ? arch->GetTriple().getTriple() : "<null>"); @@ -114,9 +115,10 @@ PlatformNetBSD::PlatformNetBSD(bool is_host) } } -std::vector<ArchSpec> PlatformNetBSD::GetSupportedArchitectures() { +std::vector<ArchSpec> +PlatformNetBSD::GetSupportedArchitectures(const ArchSpec &process_host_arch) { if (m_remote_platform_sp) - return m_remote_platform_sp->GetSupportedArchitectures(); + return m_remote_platform_sp->GetSupportedArchitectures(process_host_arch); return m_supported_architectures; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h b/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h index 433cf6653126..2613311790a3 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h +++ b/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h @@ -43,7 +43,8 @@ public: void GetStatus(Stream &strm) override; - std::vector<ArchSpec> GetSupportedArchitectures() override; + std::vector<ArchSpec> + GetSupportedArchitectures(const ArchSpec &process_host_arch) override; uint32_t GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) override; 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 84d9ff799f47..3946092276fd 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp @@ -20,6 +20,7 @@ #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/State.h" #include "lldb/Utility/Status.h" @@ -40,7 +41,7 @@ static uint32_t g_initialize_count = 0; PlatformSP PlatformOpenBSD::CreateInstance(bool force, const ArchSpec *arch) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + Log *log = GetLog(LLDBLog::Platform); LLDB_LOG(log, "force = {0}, arch=({1}, {2})", force, arch ? arch->GetArchitectureName() : "<null>", arch ? arch->GetTriple().getTriple() : "<null>"); @@ -117,9 +118,10 @@ PlatformOpenBSD::PlatformOpenBSD(bool is_host) } } -std::vector<ArchSpec> PlatformOpenBSD::GetSupportedArchitectures() { +std::vector<ArchSpec> +PlatformOpenBSD::GetSupportedArchitectures(const ArchSpec &process_host_arch) { if (m_remote_platform_sp) - return m_remote_platform_sp->GetSupportedArchitectures(); + return m_remote_platform_sp->GetSupportedArchitectures(process_host_arch); return m_supported_architectures; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h b/contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h index fd03988590ca..fcdc03576711 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h +++ b/contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h @@ -42,7 +42,8 @@ public: void GetStatus(Stream &strm) override; - std::vector<ArchSpec> GetSupportedArchitectures() override; + std::vector<ArchSpec> + GetSupportedArchitectures(const ArchSpec &process_host_arch) override; bool CanDebugProcess() override; 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 1d989b268b74..fb0d39ea6f86 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp @@ -8,6 +8,7 @@ #include "PlatformPOSIX.h" +#include "Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h" #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" @@ -28,6 +29,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" #include "llvm/ADT/ScopeExit.h" @@ -89,7 +91,7 @@ lldb_private::Status PlatformPOSIX::PutFile(const lldb_private::FileSpec &source, const lldb_private::FileSpec &destination, uint32_t uid, uint32_t gid) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); + Log *log = GetLog(LLDBLog::Platform); if (IsHost()) { if (source == destination) @@ -154,7 +156,7 @@ lldb_private::Status PlatformPOSIX::GetFile( const lldb_private::FileSpec &source, // remote file path const lldb_private::FileSpec &destination) // local file path { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); + Log *log = GetLog(LLDBLog::Platform); // Check the args, first. std::string src_path(source.GetPath()); @@ -228,7 +230,7 @@ lldb_private::Status PlatformPOSIX::GetFile( } if (error.Success()) { - lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024, 0)); + lldb::WritableDataBufferSP buffer_sp(new DataBufferHeap(1024, 0)); uint64_t offset = 0; error.Clear(); while (error.Success()) { @@ -306,7 +308,8 @@ Status PlatformPOSIX::ConnectRemote(Args &args) { } else { if (!m_remote_platform_sp) m_remote_platform_sp = - Platform::Create(ConstString("remote-gdb-server"), error); + platform_gdb_server::PlatformRemoteGDBServer::CreateInstance( + /*force=*/true, nullptr); if (m_remote_platform_sp && error.Success()) error = m_remote_platform_sp->ConnectRemote(args); @@ -360,7 +363,7 @@ lldb::ProcessSP PlatformPOSIX::Attach(ProcessAttachInfo &attach_info, Debugger &debugger, Target *target, Status &error) { lldb::ProcessSP process_sp; - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); + Log *log = GetLog(LLDBLog::Platform); if (IsHost()) { if (target == nullptr) { @@ -413,7 +416,7 @@ lldb::ProcessSP PlatformPOSIX::Attach(ProcessAttachInfo &attach_info, lldb::ProcessSP PlatformPOSIX::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, Target &target, Status &error) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + Log *log = GetLog(LLDBLog::Platform); LLDB_LOG(log, "target {0}", &target); ProcessSP process_sp; @@ -442,9 +445,8 @@ lldb::ProcessSP PlatformPOSIX::DebugProcess(ProcessLaunchInfo &launch_info, // Now create the gdb-remote process. LLDB_LOG(log, "having target create process with gdb-remote plugin"); - process_sp = - target.CreateProcess(launch_info.GetListener(), "gdb-remote", nullptr, - true); + process_sp = target.CreateProcess(launch_info.GetListener(), "gdb-remote", + nullptr, true); if (!process_sp) { error.SetErrorString("CreateProcess() failed for gdb-remote process"); @@ -453,15 +455,8 @@ lldb::ProcessSP PlatformPOSIX::DebugProcess(ProcessLaunchInfo &launch_info, } LLDB_LOG(log, "successfully created process"); - // Adjust launch for a hijacker. - ListenerSP listener_sp; - if (!launch_info.GetHijackListener()) { - LLDB_LOG(log, "setting up hijacker"); - listener_sp = - Listener::MakeListener("lldb.PlatformLinux.DebugProcess.hijack"); - launch_info.SetHijackListener(listener_sp); - process_sp->HijackProcessEvents(listener_sp); - } + + process_sp->HijackProcessEvents(launch_info.GetHijackListener()); // Log file actions. if (log) { @@ -479,14 +474,6 @@ lldb::ProcessSP PlatformPOSIX::DebugProcess(ProcessLaunchInfo &launch_info, // Do the launch. error = process_sp->Launch(launch_info); if (error.Success()) { - // Handle the hijacking of process events. - if (listener_sp) { - const StateType state = process_sp->WaitForProcessToStop( - llvm::None, nullptr, false, listener_sp); - - LLDB_LOG(log, "pid {0} state {0}", process_sp->GetID(), state); - } - // Hook up process PTY if we have one (which we should for local debugging // with llgs). int pty_fd = launch_info.GetPTY().ReleasePrimaryFileDescriptor(); @@ -575,8 +562,8 @@ PlatformPOSIX::MakeLoadImageUtilityFunction(ExecutionContext &exe_ctx, const char *error_str; }; - extern void *memcpy(void *, const void *, size_t size); - extern size_t strlen(const char *); + extern "C" void *memcpy(void *, const void *, size_t size); + extern "C" size_t strlen(const char *); void * __lldb_dlopen_wrapper (const char *name, @@ -623,12 +610,12 @@ PlatformPOSIX::MakeLoadImageUtilityFunction(ExecutionContext &exe_ctx, DiagnosticManager diagnostics; auto utility_fn_or_error = process->GetTarget().CreateUtilityFunction( - std::move(expr), dlopen_wrapper_name, eLanguageTypeObjC, exe_ctx); + std::move(expr), dlopen_wrapper_name, eLanguageTypeC_plus_plus, exe_ctx); if (!utility_fn_or_error) { std::string error_str = llvm::toString(utility_fn_or_error.takeError()); - error.SetErrorStringWithFormat("dlopen error: could not create utility" - "function: %s", - error_str.c_str()); + error.SetErrorStringWithFormat( + "dlopen error: could not create utility function: %s", + error_str.c_str()); return nullptr; } std::unique_ptr<UtilityFunction> dlopen_utility_func_up = @@ -663,8 +650,9 @@ PlatformPOSIX::MakeLoadImageUtilityFunction(ExecutionContext &exe_ctx, do_dlopen_function = dlopen_utility_func_up->MakeFunctionCaller( clang_void_pointer_type, arguments, exe_ctx.GetThreadSP(), utility_error); if (utility_error.Fail()) { - error.SetErrorStringWithFormat("dlopen error: could not make function" - "caller: %s", utility_error.AsCString()); + error.SetErrorStringWithFormat( + "dlopen error: could not make function caller: %s", + utility_error.AsCString()); return nullptr; } @@ -730,8 +718,9 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process, permissions, utility_error); if (path_addr == LLDB_INVALID_ADDRESS) { - error.SetErrorStringWithFormat("dlopen error: could not allocate memory" - "for path: %s", utility_error.AsCString()); + error.SetErrorStringWithFormat( + "dlopen error: could not allocate memory for path: %s", + utility_error.AsCString()); return LLDB_INVALID_IMAGE_TOKEN; } @@ -743,8 +732,9 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process, process->WriteMemory(path_addr, path.c_str(), path_len, utility_error); if (utility_error.Fail()) { - error.SetErrorStringWithFormat("dlopen error: could not write path string:" - " %s", utility_error.AsCString()); + error.SetErrorStringWithFormat( + "dlopen error: could not write path string: %s", + utility_error.AsCString()); return LLDB_INVALID_IMAGE_TOKEN; } @@ -755,8 +745,9 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process, permissions, utility_error); if (utility_error.Fail()) { - error.SetErrorStringWithFormat("dlopen error: could not allocate memory" - "for path: %s", utility_error.AsCString()); + error.SetErrorStringWithFormat( + "dlopen error: could not allocate memory for path: %s", + utility_error.AsCString()); return LLDB_INVALID_IMAGE_TOKEN; } @@ -804,9 +795,9 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process, permissions, utility_error); if (path_array_addr == LLDB_INVALID_ADDRESS) { - error.SetErrorStringWithFormat("dlopen error: could not allocate memory" - "for path array: %s", - utility_error.AsCString()); + error.SetErrorStringWithFormat( + "dlopen error: could not allocate memory for path array: %s", + utility_error.AsCString()); return LLDB_INVALID_IMAGE_TOKEN; } @@ -820,8 +811,9 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process, path_array.size(), utility_error); if (utility_error.Fail()) { - error.SetErrorStringWithFormat("dlopen error: could not write path array:" - " %s", utility_error.AsCString()); + error.SetErrorStringWithFormat( + "dlopen error: could not write path array: %s", + utility_error.AsCString()); return LLDB_INVALID_IMAGE_TOKEN; } // Now make spaces in the target for the buffer. We need to add one for @@ -832,9 +824,9 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process, permissions, utility_error); if (buffer_addr == LLDB_INVALID_ADDRESS) { - error.SetErrorStringWithFormat("dlopen error: could not allocate memory" - "for buffer: %s", - utility_error.AsCString()); + error.SetErrorStringWithFormat( + "dlopen error: could not allocate memory for buffer: %s", + utility_error.AsCString()); return LLDB_INVALID_IMAGE_TOKEN; } @@ -857,9 +849,9 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process, func_args_addr, arguments, diagnostics)) { - error.SetErrorStringWithFormat("dlopen error: could not write function " - "arguments: %s", - diagnostics.GetString().c_str()); + error.SetErrorStringWithFormat( + "dlopen error: could not write function arguments: %s", + diagnostics.GetString().c_str()); return LLDB_INVALID_IMAGE_TOKEN; } @@ -899,9 +891,9 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process, ExpressionResults results = do_dlopen_function->ExecuteFunction( exe_ctx, &func_args_addr, options, diagnostics, return_value); if (results != eExpressionCompleted) { - error.SetErrorStringWithFormat("dlopen error: failed executing " - "dlopen wrapper function: %s", - diagnostics.GetString().c_str()); + error.SetErrorStringWithFormat( + "dlopen error: failed executing dlopen wrapper function: %s", + diagnostics.GetString().c_str()); return LLDB_INVALID_IMAGE_TOKEN; } @@ -909,8 +901,9 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process, lldb::addr_t token = process->ReadPointerFromMemory(return_addr, utility_error); if (utility_error.Fail()) { - error.SetErrorStringWithFormat("dlopen error: could not read the return " - "struct: %s", utility_error.AsCString()); + error.SetErrorStringWithFormat( + "dlopen error: could not read the return struct: %s", + utility_error.AsCString()); return LLDB_INVALID_IMAGE_TOKEN; } @@ -933,8 +926,9 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process, lldb::addr_t error_addr = process->ReadPointerFromMemory(return_addr + addr_size, utility_error); if (utility_error.Fail()) { - error.SetErrorStringWithFormat("dlopen error: could not read error string: " - "%s", utility_error.AsCString()); + error.SetErrorStringWithFormat( + "dlopen error: could not read error string: %s", + utility_error.AsCString()); return LLDB_INVALID_IMAGE_TOKEN; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp b/contrib/llvm-project/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp index dd7546d8fa15..7ee92ef76c9c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp @@ -14,6 +14,7 @@ #include "lldb/Interpreter/OptionValueProperties.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Listener.h" #include "lldb/Utility/Log.h" @@ -105,7 +106,8 @@ PlatformSP PlatformQemuUser::CreateInstance(bool force, const ArchSpec *arch) { return nullptr; } -std::vector<ArchSpec> PlatformQemuUser::GetSupportedArchitectures() { +std::vector<ArchSpec> +PlatformQemuUser::GetSupportedArchitectures(const ArchSpec &process_host_arch) { llvm::Triple triple = HostInfo::GetArchitecture().GetTriple(); triple.setEnvironment(llvm::Triple::UnknownEnvironment); triple.setArchName(GetGlobalProperties().GetArchitecture()); @@ -160,7 +162,7 @@ static Environment ComputeLaunchEnvironment(Environment target, lldb::ProcessSP PlatformQemuUser::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, Target &target, Status &error) { - Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); + Log *log = GetLog(LLDBLog::Platform); FileSpec qemu = GetGlobalProperties().GetEmulatorPath(); if (!qemu) @@ -200,8 +202,7 @@ lldb::ProcessSP PlatformQemuUser::DebugProcess(ProcessLaunchInfo &launch_info, launch_info.SetLaunchInSeparateProcessGroup(true); launch_info.GetFlags().Clear(eLaunchFlagDebug); - launch_info.SetMonitorProcessCallback(ProcessLaunchInfo::NoOpMonitorCallback, - false); + launch_info.SetMonitorProcessCallback(ProcessLaunchInfo::NoOpMonitorCallback); // This is automatically done for host platform in // Target::FinalizeFileActions, but we're not a host platform. @@ -216,11 +217,12 @@ lldb::ProcessSP PlatformQemuUser::DebugProcess(ProcessLaunchInfo &launch_info, launch_info.GetListener(), process_gdb_remote::ProcessGDBRemote::GetPluginNameStatic(), nullptr, true); + if (!process_sp) { + error.SetErrorString("Failed to create GDB process"); + return nullptr; + } - ListenerSP listener_sp = - Listener::MakeListener("lldb.platform_qemu_user.debugprocess"); - launch_info.SetHijackListener(listener_sp); - Process::ProcessEventHijacker hijacker(*process_sp, listener_sp); + process_sp->HijackProcessEvents(launch_info.GetHijackListener()); error = process_sp->ConnectRemote(("unix-connect://" + socket_path).str()); if (error.Fail()) @@ -231,7 +233,6 @@ lldb::ProcessSP PlatformQemuUser::DebugProcess(ProcessLaunchInfo &launch_info, process_sp->SetSTDIOFileDescriptor( launch_info.GetPTY().ReleasePrimaryFileDescriptor()); - process_sp->WaitForProcessToStop(llvm::None, nullptr, false, listener_sp); return process_sp; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h b/contrib/llvm-project/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h index c5439e126db1..0dd0e2f6f2b9 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h +++ b/contrib/llvm-project/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h @@ -29,7 +29,8 @@ public: return HostInfo::GetUserIDResolver(); } - std::vector<ArchSpec> GetSupportedArchitectures() override; + std::vector<ArchSpec> + GetSupportedArchitectures(const ArchSpec &process_host_arch) override; lldb::ProcessSP DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, Target &target, @@ -59,7 +60,7 @@ private: static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch); static void DebuggerInitialize(Debugger &debugger); - PlatformQemuUser() : Platform(/*is_host=*/false) {} + PlatformQemuUser() : Platform(/*is_host=*/true) {} }; } // namespace lldb_private 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 0929a060d0b8..243866188629 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 @@ -23,6 +23,7 @@ #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/ProcessInfo.h" #include "lldb/Utility/Status.h" @@ -92,7 +93,7 @@ llvm::StringRef PlatformRemoteGDBServer::GetDescription() { bool PlatformRemoteGDBServer::GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch, ModuleSpec &module_spec) { - Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); + Log *log = GetLog(LLDBLog::Platform); const auto module_path = module_file_spec.GetPath(false); @@ -171,7 +172,7 @@ ArchSpec PlatformRemoteGDBServer::GetRemoteSystemArchitecture() { FileSpec PlatformRemoteGDBServer::GetRemoteWorkingDirectory() { if (IsConnected()) { - Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); + Log *log = GetLog(LLDBLog::Platform); FileSpec working_dir; if (m_gdb_client_up->GetWorkingDir(working_dir) && log) LLDB_LOGF(log, @@ -188,7 +189,7 @@ bool PlatformRemoteGDBServer::SetRemoteWorkingDirectory( if (IsConnected()) { // Clear the working directory it case it doesn't get set correctly. This // will for use to re-read it - Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); + Log *log = GetLog(LLDBLog::Platform); LLDB_LOGF(log, "PlatformRemoteGDBServer::SetRemoteWorkingDirectory('%s')", working_dir.GetCString()); return m_gdb_client_up->SetWorkingDir(working_dir) == 0; @@ -280,10 +281,10 @@ Status PlatformRemoteGDBServer::DisconnectRemote() { const char *PlatformRemoteGDBServer::GetHostname() { if (m_gdb_client_up) - m_gdb_client_up->GetHostname(m_name); - if (m_name.empty()) + m_gdb_client_up->GetHostname(m_hostname); + if (m_hostname.empty()) return nullptr; - return m_name.c_str(); + return m_hostname.c_str(); } llvm::Optional<std::string> @@ -318,7 +319,7 @@ bool PlatformRemoteGDBServer::GetProcessInfo( } Status PlatformRemoteGDBServer::LaunchProcess(ProcessLaunchInfo &launch_info) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + Log *log = GetLog(LLDBLog::Platform); Status error; LLDB_LOGF(log, "PlatformRemoteGDBServer::%s() called", __FUNCTION__); @@ -427,6 +428,8 @@ PlatformRemoteGDBServer::DebugProcess(ProcessLaunchInfo &launch_info, "gdb-remote", nullptr, true); if (process_sp) { + process_sp->HijackProcessEvents(launch_info.GetHijackListener()); + error = process_sp->ConnectRemote(connect_url.c_str()); // Retry the connect remote one time... if (error.Fail()) @@ -539,7 +542,7 @@ Status PlatformRemoteGDBServer::MakeDirectory(const FileSpec &file_spec, if (!IsConnected()) return Status("Not connected."); Status error = m_gdb_client_up->MakeDirectory(file_spec, mode); - Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); + Log *log = GetLog(LLDBLog::Platform); LLDB_LOGF(log, "PlatformRemoteGDBServer::MakeDirectory(path='%s', mode=%o) " "error = %u (%s)", @@ -553,7 +556,7 @@ Status PlatformRemoteGDBServer::GetFilePermissions(const FileSpec &file_spec, return Status("Not connected."); Status error = m_gdb_client_up->GetFilePermissions(file_spec, file_permissions); - Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); + Log *log = GetLog(LLDBLog::Platform); LLDB_LOGF(log, "PlatformRemoteGDBServer::GetFilePermissions(path='%s', " "file_permissions=%o) error = %u (%s)", @@ -568,7 +571,7 @@ Status PlatformRemoteGDBServer::SetFilePermissions(const FileSpec &file_spec, return Status("Not connected."); Status error = m_gdb_client_up->SetFilePermissions(file_spec, file_permissions); - Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); + Log *log = GetLog(LLDBLog::Platform); LLDB_LOGF(log, "PlatformRemoteGDBServer::SetFilePermissions(path='%s', " "file_permissions=%o) error = %u (%s)", @@ -637,7 +640,7 @@ Status PlatformRemoteGDBServer::CreateSymlink( if (!IsConnected()) return Status("Not connected."); Status error = m_gdb_client_up->CreateSymlink(src, dst); - Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); + Log *log = GetLog(LLDBLog::Platform); LLDB_LOGF(log, "PlatformRemoteGDBServer::CreateSymlink(src='%s', dst='%s') " "error = %u (%s)", @@ -650,7 +653,7 @@ Status PlatformRemoteGDBServer::Unlink(const FileSpec &file_spec) { if (!IsConnected()) return Status("Not connected."); Status error = m_gdb_client_up->Unlink(file_spec); - Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); + Log *log = GetLog(LLDBLog::Platform); LLDB_LOGF(log, "PlatformRemoteGDBServer::Unlink(path='%s') error = %u (%s)", file_spec.GetCString(), error.GetError(), error.AsCString()); return error; diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h b/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h index 263516f520d5..3caf531edaa8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h +++ b/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h @@ -65,7 +65,8 @@ public: // target, else use existing one Status &error) override; - std::vector<ArchSpec> GetSupportedArchitectures() override { + std::vector<ArchSpec> + GetSupportedArchitectures(const ArchSpec &process_host_arch) override { return m_supported_architectures; } 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 21c9ead0eca4..5d73ec3457e3 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp @@ -497,6 +497,10 @@ Status NativeProcessFreeBSD::Resume(const ResumeActionList &resume_actions) { Status NativeProcessFreeBSD::Halt() { Status error; + // Do not try to stop a process that's already stopped, this may cause + // the SIGSTOP to get queued and stop the process again once resumed. + if (StateIsStoppedState(m_state, false)) + return error; if (kill(GetID(), SIGSTOP) != 0) error.SetErrorToErrno(); return error; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.cpp index c4ee3773eaeb..2c5017664387 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.cpp @@ -140,7 +140,7 @@ Status NativeRegisterContextFreeBSD_arm::WriteRegister( } Status NativeRegisterContextFreeBSD_arm::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { Status error; error = ReadRegisterSet(RegisterInfoPOSIX_arm::GPRegSet); @@ -177,7 +177,7 @@ Status NativeRegisterContextFreeBSD_arm::WriteAllRegisterValues( return error; } - uint8_t *src = data_sp->GetBytes(); + const uint8_t *src = data_sp->GetBytes(); if (src == nullptr) { error.SetErrorStringWithFormat("NativeRegisterContextFreeBSD_arm::%s " "DataBuffer::GetBytes() returned a null " diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.h index 4be75b958fc1..89ffa617294a 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.h @@ -44,7 +44,7 @@ public: Status WriteRegister(const RegisterInfo *reg_info, const RegisterValue ®_value) override; - Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + Status ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; 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 143d94069bc6..9db5970af653 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 @@ -149,7 +149,7 @@ Status NativeRegisterContextFreeBSD_arm64::WriteRegister( } Status NativeRegisterContextFreeBSD_arm64::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { Status error; error = ReadRegisterSet(RegisterInfoPOSIX_arm64::GPRegSet); @@ -186,7 +186,7 @@ Status NativeRegisterContextFreeBSD_arm64::WriteAllRegisterValues( return error; } - uint8_t *src = data_sp->GetBytes(); + const uint8_t *src = data_sp->GetBytes(); if (src == nullptr) { error.SetErrorStringWithFormat("NativeRegisterContextFreeBSD_arm64::%s " "DataBuffer::GetBytes() returned a null " diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.h index a230f8fed48a..799209e26e86 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.h @@ -51,7 +51,7 @@ public: Status WriteRegister(const RegisterInfo *reg_info, const RegisterValue ®_value) override; - Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + Status ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp index d93b7fd33815..83664b586960 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp @@ -176,7 +176,7 @@ Status NativeRegisterContextFreeBSD_mips64::WriteRegister( } Status NativeRegisterContextFreeBSD_mips64::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { Status error; error = ReadRegisterSet(GPRegSet); @@ -213,7 +213,7 @@ Status NativeRegisterContextFreeBSD_mips64::WriteAllRegisterValues( return error; } - uint8_t *src = data_sp->GetBytes(); + const uint8_t *src = data_sp->GetBytes(); if (src == nullptr) { error.SetErrorStringWithFormat("NativeRegisterContextFreeBSD_mips64::%s " "DataBuffer::GetBytes() returned a null " diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.h index 8e300ed829c9..7a2c0b34eeee 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.h @@ -44,7 +44,7 @@ public: Status WriteRegister(const RegisterInfo *reg_info, const RegisterValue ®_value) override; - Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + Status ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.cpp index 5b5d44a308b1..ee125e5e6881 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.cpp @@ -227,7 +227,7 @@ Status NativeRegisterContextFreeBSD_powerpc::WriteRegister( } Status NativeRegisterContextFreeBSD_powerpc::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { Status error; error = ReadRegisterSet(GPRegSet); @@ -264,7 +264,7 @@ Status NativeRegisterContextFreeBSD_powerpc::WriteAllRegisterValues( return error; } - uint8_t *src = data_sp->GetBytes(); + const uint8_t *src = data_sp->GetBytes(); if (src == nullptr) { error.SetErrorStringWithFormat("NativeRegisterContextFreeBSD_powerpc::%s " "DataBuffer::GetBytes() returned a null " diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.h index 884c25988ce1..c77394366517 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.h @@ -44,7 +44,7 @@ public: Status WriteRegister(const RegisterInfo *reg_info, const RegisterValue ®_value) override; - Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + Status ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; 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 9328d606ad26..b69cfa7d5d83 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 @@ -537,7 +537,7 @@ Status NativeRegisterContextFreeBSD_x86_64::WriteRegister( } Status NativeRegisterContextFreeBSD_x86_64::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { Status error; data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0)); @@ -571,7 +571,7 @@ Status NativeRegisterContextFreeBSD_x86_64::WriteAllRegisterValues( return error; } - uint8_t *src = data_sp->GetBytes(); + const uint8_t *src = data_sp->GetBytes(); if (src == nullptr) { error.SetErrorStringWithFormat("NativeRegisterContextFreeBSD_x86_64::%s " "DataBuffer::GetBytes() returned a null " diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.h index efd0f91f77b9..366a89b6eec8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.h @@ -48,7 +48,7 @@ public: Status WriteRegister(const RegisterInfo *reg_info, const RegisterValue ®_value) override; - Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + Status ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; 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 a75668f3b5c7..8e6399bcf9c7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp @@ -81,7 +81,7 @@ void NativeThreadFreeBSD::SetStoppedBySignal(uint32_t signo, SetStopped(); m_stop_info.reason = StopReason::eStopReasonSignal; - m_stop_info.details.signal.signo = signo; + m_stop_info.signo = signo; m_stop_description.clear(); if (info) { @@ -100,19 +100,19 @@ void NativeThreadFreeBSD::SetStoppedBySignal(uint32_t signo, void NativeThreadFreeBSD::SetStoppedByBreakpoint() { SetStopped(); m_stop_info.reason = StopReason::eStopReasonBreakpoint; - m_stop_info.details.signal.signo = SIGTRAP; + m_stop_info.signo = SIGTRAP; } void NativeThreadFreeBSD::SetStoppedByTrace() { SetStopped(); m_stop_info.reason = StopReason::eStopReasonTrace; - m_stop_info.details.signal.signo = SIGTRAP; + m_stop_info.signo = SIGTRAP; } void NativeThreadFreeBSD::SetStoppedByExec() { SetStopped(); m_stop_info.reason = StopReason::eStopReasonExec; - m_stop_info.details.signal.signo = SIGTRAP; + m_stop_info.signo = SIGTRAP; } void NativeThreadFreeBSD::SetStoppedByWatchpoint(uint32_t wp_index) { @@ -127,7 +127,7 @@ void NativeThreadFreeBSD::SetStoppedByWatchpoint(uint32_t wp_index) { SetStopped(); m_stop_description = ostr.str(); m_stop_info.reason = StopReason::eStopReasonWatchpoint; - m_stop_info.details.signal.signo = SIGTRAP; + m_stop_info.signo = SIGTRAP; } void NativeThreadFreeBSD::SetStoppedByFork(lldb::pid_t child_pid, @@ -135,6 +135,7 @@ void NativeThreadFreeBSD::SetStoppedByFork(lldb::pid_t child_pid, SetStopped(); m_stop_info.reason = StopReason::eStopReasonFork; + m_stop_info.signo = SIGTRAP; m_stop_info.details.fork.child_pid = child_pid; m_stop_info.details.fork.child_tid = child_tid; } @@ -144,6 +145,7 @@ void NativeThreadFreeBSD::SetStoppedByVFork(lldb::pid_t child_pid, SetStopped(); m_stop_info.reason = StopReason::eStopReasonVFork; + m_stop_info.signo = SIGTRAP; m_stop_info.details.fork.child_pid = child_pid; m_stop_info.details.fork.child_tid = child_tid; } @@ -152,13 +154,14 @@ void NativeThreadFreeBSD::SetStoppedByVForkDone() { SetStopped(); m_stop_info.reason = StopReason::eStopReasonVForkDone; + m_stop_info.signo = SIGTRAP; } void NativeThreadFreeBSD::SetStoppedWithNoReason() { SetStopped(); m_stop_info.reason = StopReason::eStopReasonNone; - m_stop_info.details.signal.signo = 0; + m_stop_info.signo = 0; } void NativeThreadFreeBSD::SetStopped() { 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 3d164eadbea7..5a910b5a6ec9 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 @@ -527,7 +527,7 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegister( } Status NativeRegisterContextNetBSD_x86_64::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { Status error; data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0)); @@ -561,7 +561,7 @@ Status NativeRegisterContextNetBSD_x86_64::WriteAllRegisterValues( return error; } - uint8_t *src = data_sp->GetBytes(); + const uint8_t *src = data_sp->GetBytes(); if (src == nullptr) { error.SetErrorStringWithFormat("NativeRegisterContextNetBSD_x86_64::%s " "DataBuffer::GetBytes() returned a null " diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h index 31005952dd75..795cbeefd467 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h @@ -46,7 +46,7 @@ public: Status WriteRegister(const RegisterInfo *reg_info, const RegisterValue ®_value) override; - Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + Status ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; 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 3e8cf9fd9f23..995fe3fa78e8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp @@ -81,7 +81,7 @@ void NativeThreadNetBSD::SetStoppedBySignal(uint32_t signo, SetStopped(); m_stop_info.reason = StopReason::eStopReasonSignal; - m_stop_info.details.signal.signo = signo; + m_stop_info.signo = signo; m_stop_description.clear(); if (info) { @@ -100,19 +100,19 @@ void NativeThreadNetBSD::SetStoppedBySignal(uint32_t signo, void NativeThreadNetBSD::SetStoppedByBreakpoint() { SetStopped(); m_stop_info.reason = StopReason::eStopReasonBreakpoint; - m_stop_info.details.signal.signo = SIGTRAP; + m_stop_info.signo = SIGTRAP; } void NativeThreadNetBSD::SetStoppedByTrace() { SetStopped(); m_stop_info.reason = StopReason::eStopReasonTrace; - m_stop_info.details.signal.signo = SIGTRAP; + m_stop_info.signo = SIGTRAP; } void NativeThreadNetBSD::SetStoppedByExec() { SetStopped(); m_stop_info.reason = StopReason::eStopReasonExec; - m_stop_info.details.signal.signo = SIGTRAP; + m_stop_info.signo = SIGTRAP; } void NativeThreadNetBSD::SetStoppedByWatchpoint(uint32_t wp_index) { @@ -127,7 +127,7 @@ void NativeThreadNetBSD::SetStoppedByWatchpoint(uint32_t wp_index) { SetStopped(); m_stop_description = ostr.str(); m_stop_info.reason = StopReason::eStopReasonWatchpoint; - m_stop_info.details.signal.signo = SIGTRAP; + m_stop_info.signo = SIGTRAP; } void NativeThreadNetBSD::SetStoppedByFork(lldb::pid_t child_pid, @@ -135,6 +135,7 @@ void NativeThreadNetBSD::SetStoppedByFork(lldb::pid_t child_pid, SetStopped(); m_stop_info.reason = StopReason::eStopReasonFork; + m_stop_info.signo = SIGTRAP; m_stop_info.details.fork.child_pid = child_pid; m_stop_info.details.fork.child_tid = child_tid; } @@ -144,6 +145,7 @@ void NativeThreadNetBSD::SetStoppedByVFork(lldb::pid_t child_pid, SetStopped(); m_stop_info.reason = StopReason::eStopReasonVFork; + m_stop_info.signo = SIGTRAP; m_stop_info.details.fork.child_pid = child_pid; m_stop_info.details.fork.child_tid = child_tid; } @@ -152,13 +154,14 @@ void NativeThreadNetBSD::SetStoppedByVForkDone() { SetStopped(); m_stop_info.reason = StopReason::eStopReasonVForkDone; + m_stop_info.signo = SIGTRAP; } void NativeThreadNetBSD::SetStoppedWithNoReason() { SetStopped(); m_stop_info.reason = StopReason::eStopReasonNone; - m_stop_info.details.signal.signo = 0; + m_stop_info.signo = 0; } void NativeThreadNetBSD::SetStopped() { diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/NativeProcessELF.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/NativeProcessELF.cpp index 117d12101a0b..cbaa1fc7a2b1 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/NativeProcessELF.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/NativeProcessELF.cpp @@ -28,7 +28,7 @@ NativeProcessELF::GetAuxValue(enum AuxVector::EntryType type) { } lldb::addr_t NativeProcessELF::GetSharedLibraryInfoAddress() { - if (!m_shared_library_info_addr.hasValue()) { + if (!m_shared_library_info_addr) { if (GetAddressByteSize() == 8) m_shared_library_info_addr = GetELFImageInfoAddress<llvm::ELF::Elf64_Ehdr, llvm::ELF::Elf64_Phdr, @@ -39,7 +39,7 @@ lldb::addr_t NativeProcessELF::GetSharedLibraryInfoAddress() { llvm::ELF::Elf32_Dyn>(); } - return m_shared_library_info_addr.getValue(); + return *m_shared_library_info_addr; } template <typename ELF_EHDR, typename ELF_PHDR, typename ELF_DYN> @@ -180,4 +180,9 @@ NativeProcessELF::GetLoadedSVR4Libraries() { return library_list; } +void NativeProcessELF::NotifyDidExec() { + NativeProcessProtocol::NotifyDidExec(); + m_shared_library_info_addr.reset(); +} + } // namespace lldb_private 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 c01409940daa..8e92899defec 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h @@ -45,6 +45,8 @@ protected: llvm::Expected<SVR4LibraryInfo> ReadSVR4LibraryInfo(lldb::addr_t link_map_addr); + void NotifyDidExec() override; + std::unique_ptr<AuxVector> m_aux_vector; llvm::Optional<lldb::addr_t> m_shared_library_info_addr; }; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h b/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h index 7b8b6cdbf255..88cfdfd204c0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h @@ -10,8 +10,8 @@ #ifndef liblldb_ProcessPOSIXLog_h_ #define liblldb_ProcessPOSIXLog_h_ - #include "lldb/Utility/Log.h" +#include "llvm/ADT/BitmaskEnum.h" namespace lldb_private { @@ -23,8 +23,10 @@ enum class POSIXLog : Log::MaskType { Registers = Log::ChannelFlag<4>, Thread = Log::ChannelFlag<5>, Watchpoints = Log::ChannelFlag<6>, - LLVM_MARK_AS_BITMASK_ENUM(Watchpoints) + Trace = Log::ChannelFlag<7>, + LLVM_MARK_AS_BITMASK_ENUM(Trace) }; +LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); class ProcessPOSIXLog { public: diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/HistoryThread.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/HistoryThread.cpp index d73b132539f1..bc06757c806a 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/HistoryThread.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/HistoryThread.cpp @@ -15,6 +15,7 @@ #include "lldb/Target/Process.h" #include "lldb/Target/StackFrameList.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include <memory> @@ -33,14 +34,14 @@ HistoryThread::HistoryThread(lldb_private::Process &process, lldb::tid_t tid, m_queue_id(LLDB_INVALID_QUEUE_ID) { m_unwinder_up = std::make_unique<HistoryUnwind>(*this, pcs, pcs_are_call_addresses); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); + Log *log = GetLog(LLDBLog::Object); LLDB_LOGF(log, "%p HistoryThread::HistoryThread", static_cast<void *>(this)); } // Destructor HistoryThread::~HistoryThread() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); + Log *log = GetLog(LLDBLog::Object); LLDB_LOGF(log, "%p HistoryThread::~HistoryThread (tid=0x%" PRIx64 ")", static_cast<void *>(this), GetID()); DestroyThread(); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp index 947b970edf6c..2a15f9813749 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp @@ -94,7 +94,15 @@ ParseMemoryRegionInfoFromProcMapsLine(llvm::StringRef maps_line, return ProcMapError("unexpected /proc/{pid}/%s exec permission char", maps_kind); - line_extractor.GetChar(); // Read the private bit + // Handle sharing status (private/shared). + const char sharing_char = line_extractor.GetChar(); + if (sharing_char == 's') + region.SetShared(MemoryRegionInfo::OptionalBool::eYes); + else if (sharing_char == 'p') + region.SetShared(MemoryRegionInfo::OptionalBool::eNo); + else + region.SetShared(MemoryRegionInfo::OptionalBool::eDontKnow); + line_extractor.SkipSpaces(); // Skip the separator line_extractor.GetHexMaxU64(false, 0); // Read the offset line_extractor.GetHexMaxU64(false, 0); // Read the major device number 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 feee857cfe5f..4bec3de58668 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 @@ -8,6 +8,7 @@ #include "NativeRegisterContextDBReg_arm64.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegisterValue.h" @@ -29,7 +30,7 @@ static constexpr inline uint64_t GetSizeBits(int size) { } uint32_t NativeRegisterContextDBReg_arm64::NumSupportedHardwareBreakpoints() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); llvm::Error error = ReadHardwareDebugInfo(); if (error) { LLDB_LOG_ERROR(log, std::move(error), @@ -43,7 +44,7 @@ uint32_t NativeRegisterContextDBReg_arm64::NumSupportedHardwareBreakpoints() { uint32_t NativeRegisterContextDBReg_arm64::SetHardwareBreakpoint(lldb::addr_t addr, size_t size) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); LLDB_LOG(log, "addr: {0:x}, size: {1:x}", addr, size); // Read hardware breakpoint and watchpoint information. @@ -104,7 +105,7 @@ NativeRegisterContextDBReg_arm64::SetHardwareBreakpoint(lldb::addr_t addr, bool NativeRegisterContextDBReg_arm64::ClearHardwareBreakpoint( uint32_t hw_idx) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); LLDB_LOG(log, "hw_idx: {0}", hw_idx); // Read hardware breakpoint and watchpoint information. @@ -144,7 +145,7 @@ bool NativeRegisterContextDBReg_arm64::ClearHardwareBreakpoint( Status NativeRegisterContextDBReg_arm64::GetHardwareBreakHitIndex( uint32_t &bp_index, lldb::addr_t trap_addr) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); LLDB_LOGF(log, "NativeRegisterContextDBReg_arm64::%s()", __FUNCTION__); @@ -164,7 +165,7 @@ Status NativeRegisterContextDBReg_arm64::GetHardwareBreakHitIndex( } Status NativeRegisterContextDBReg_arm64::ClearAllHardwareBreakpoints() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); LLDB_LOGF(log, "NativeRegisterContextDBReg_arm64::%s()", __FUNCTION__); @@ -206,7 +207,7 @@ bool NativeRegisterContextDBReg_arm64::BreakpointIsEnabled(uint32_t bp_index) { } uint32_t NativeRegisterContextDBReg_arm64::NumSupportedHardwareWatchpoints() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); llvm::Error error = ReadHardwareDebugInfo(); if (error) { LLDB_LOG_ERROR(log, std::move(error), @@ -219,7 +220,7 @@ uint32_t NativeRegisterContextDBReg_arm64::NumSupportedHardwareWatchpoints() { uint32_t NativeRegisterContextDBReg_arm64::SetHardwareWatchpoint( lldb::addr_t addr, size_t size, uint32_t watch_flags) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); LLDB_LOG(log, "addr: {0:x}, size: {1:x} watch_flags: {2:x}", addr, size, watch_flags); @@ -312,7 +313,7 @@ uint32_t NativeRegisterContextDBReg_arm64::SetHardwareWatchpoint( bool NativeRegisterContextDBReg_arm64::ClearHardwareWatchpoint( uint32_t wp_index) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); LLDB_LOG(log, "wp_index: {0}", wp_index); // Read hardware breakpoint and watchpoint information. @@ -384,7 +385,7 @@ Status NativeRegisterContextDBReg_arm64::ClearAllHardwareWatchpoints() { uint32_t NativeRegisterContextDBReg_arm64::GetWatchpointSize(uint32_t wp_index) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); LLDB_LOG(log, "wp_index: {0}", wp_index); switch ((m_hwp_regs[wp_index].control >> 5) & 0xff) { @@ -402,7 +403,7 @@ NativeRegisterContextDBReg_arm64::GetWatchpointSize(uint32_t wp_index) { } bool NativeRegisterContextDBReg_arm64::WatchpointIsEnabled(uint32_t wp_index) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); LLDB_LOG(log, "wp_index: {0}", wp_index); if ((m_hwp_regs[wp_index].control & g_enable_bit) != 0) @@ -413,7 +414,7 @@ bool NativeRegisterContextDBReg_arm64::WatchpointIsEnabled(uint32_t wp_index) { Status NativeRegisterContextDBReg_arm64::GetWatchpointHitIndex( uint32_t &wp_index, lldb::addr_t trap_addr) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); LLDB_LOG(log, "wp_index: {0}, trap_addr: {1:x}", wp_index, trap_addr); // Read hardware breakpoint and watchpoint information. @@ -444,7 +445,7 @@ Status NativeRegisterContextDBReg_arm64::GetWatchpointHitIndex( lldb::addr_t NativeRegisterContextDBReg_arm64::GetWatchpointAddress(uint32_t wp_index) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); LLDB_LOG(log, "wp_index: {0}", wp_index); if (wp_index >= m_max_hwp_supported) @@ -457,7 +458,7 @@ NativeRegisterContextDBReg_arm64::GetWatchpointAddress(uint32_t wp_index) { lldb::addr_t NativeRegisterContextDBReg_arm64::GetWatchpointHitAddress(uint32_t wp_index) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); LLDB_LOG(log, "wp_index: {0}", wp_index); if (wp_index >= m_max_hwp_supported) diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.cpp index 56c1757ee89d..222e4a2690e4 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.cpp @@ -7,8 +7,7 @@ //===----------------------------------------------------------------------===// #include "NativeRegisterContextDBReg_x86.h" - -#include "lldb/Utility/Log.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/RegisterValue.h" #include "Plugins/Process/Utility/lldb-x86-register-enums.h" @@ -242,7 +241,7 @@ Status NativeRegisterContextDBReg_x86::ClearAllHardwareWatchpoints() { uint32_t NativeRegisterContextDBReg_x86::SetHardwareWatchpoint( lldb::addr_t addr, size_t size, uint32_t watch_flags) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints(); for (uint32_t wp_index = 0; wp_index < num_hw_watchpoints; ++wp_index) { bool is_vacant; 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 e1d3b6ecd7d0..33bab249d960 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 @@ -1236,7 +1236,7 @@ bool RegisterContextDarwin_arm::WriteRegister(const RegisterInfo *reg_info, } bool RegisterContextDarwin_arm::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { data_sp = std::make_shared<DataBufferHeap>(REG_CONTEXT_SIZE, 0); if (data_sp && ReadGPR(false) == KERN_SUCCESS && ReadFPU(false) == KERN_SUCCESS && ReadEXC(false) == KERN_SUCCESS) { diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h index 1bd60f756487..7ff1bded81f4 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h @@ -66,7 +66,7 @@ public: bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue ®_value) override; - bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; 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 50f710e26815..11b300bc44fb 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 @@ -643,7 +643,7 @@ bool RegisterContextDarwin_arm64::WriteRegister(const RegisterInfo *reg_info, } bool RegisterContextDarwin_arm64::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { data_sp = std::make_shared<DataBufferHeap>(REG_CONTEXT_SIZE, 0); if (ReadGPR(false) == KERN_SUCCESS && ReadFPU(false) == KERN_SUCCESS && ReadEXC(false) == KERN_SUCCESS) { diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h index 010e566be32c..a0d7821ae9e8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h @@ -48,7 +48,7 @@ public: bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue ®_value) override; - bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; 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 5f56e6f1636a..9158f8acc2e7 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 @@ -793,7 +793,7 @@ bool RegisterContextDarwin_i386::WriteRegister(const RegisterInfo *reg_info, } bool RegisterContextDarwin_i386::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { data_sp = std::make_shared<DataBufferHeap>(REG_CONTEXT_SIZE, 0); if (ReadGPR(false) == 0 && ReadFPU(false) == 0 && ReadEXC(false) == 0) { uint8_t *dst = data_sp->GetBytes(); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h index 9c759c31caed..be933f3be266 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h @@ -35,7 +35,7 @@ public: bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value) override; - bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; 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 567df8fc980c..ad25ebbbb804 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 @@ -852,7 +852,7 @@ bool RegisterContextDarwin_x86_64::WriteRegister(const RegisterInfo *reg_info, } bool RegisterContextDarwin_x86_64::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { data_sp = std::make_shared<DataBufferHeap>(REG_CONTEXT_SIZE, 0); if (ReadGPR(false) == 0 && ReadFPU(false) == 0 && ReadEXC(false) == 0) { uint8_t *dst = data_sp->GetBytes(); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h index d9ba8d0b2319..a132f92d4d49 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h @@ -35,7 +35,7 @@ public: bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value) override; - bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp index 4c2e291c62d6..f41aa2ca599e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp @@ -102,7 +102,8 @@ bool RegisterContextDummy::WriteRegister( return false; } -bool RegisterContextDummy::ReadAllRegisterValues(lldb::DataBufferSP &data_sp) { +bool RegisterContextDummy::ReadAllRegisterValues( + lldb::WritableDataBufferSP &data_sp) { return false; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDummy.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDummy.h index de98767693fe..631ad30b16a8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDummy.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDummy.h @@ -43,7 +43,7 @@ public: bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value) override; - bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp index 577958738900..f06af93cfa83 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp @@ -104,7 +104,7 @@ bool RegisterContextHistory::WriteRegister( } bool RegisterContextHistory::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { return false; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextHistory.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextHistory.h index 407640d2bdb9..a1eadac5d1b7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextHistory.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextHistory.h @@ -43,7 +43,7 @@ public: bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value) override; - bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h index 1ceca65c97c3..fedd0062c99c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h @@ -16,7 +16,7 @@ public: RegisterContextMach_arm(lldb_private::Thread &thread, uint32_t concrete_frame_idx); - virtual ~RegisterContextMach_arm(); + ~RegisterContextMach_arm() override; protected: int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h index da5411eb2de2..8bdac083863d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h @@ -16,7 +16,7 @@ public: RegisterContextMach_i386(lldb_private::Thread &thread, uint32_t concrete_frame_idx); - virtual ~RegisterContextMach_i386(); + ~RegisterContextMach_i386() override; protected: int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h index c131c8282bd2..99841a8e9a8d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h @@ -17,7 +17,7 @@ public: RegisterContextMach_x86_64(lldb_private::Thread &thread, uint32_t concrete_frame_idx); - virtual ~RegisterContextMach_x86_64(); + ~RegisterContextMach_x86_64() override; protected: int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override; 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 49a4c8669022..ead8c4b4a80d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp @@ -32,9 +32,9 @@ RegisterContextMemory::RegisterContextMemory(Thread &thread, m_reg_valid.resize(num_regs); // Make a heap based buffer that is big enough to store all registers - DataBufferSP reg_data_sp( - new DataBufferHeap(reg_infos.GetRegisterDataByteSize(), 0)); - m_reg_data.SetData(reg_data_sp); + m_data = + std::make_shared<DataBufferHeap>(reg_infos.GetRegisterDataByteSize(), 0); + m_reg_data.SetData(m_data); } // Destructor @@ -76,7 +76,7 @@ bool RegisterContextMemory::ReadRegister(const RegisterInfo *reg_info, RegisterValue ®_value) { const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB]; if (!m_reg_valid[reg_num]) { - if (!ReadAllRegisterValues(m_reg_data.GetSharedDataBuffer())) + if (!ReadAllRegisterValues(m_data)) return false; } const bool partial_data_ok = false; @@ -99,7 +99,8 @@ bool RegisterContextMemory::WriteRegister(const RegisterInfo *reg_info, return false; } -bool RegisterContextMemory::ReadAllRegisterValues(DataBufferSP &data_sp) { +bool RegisterContextMemory::ReadAllRegisterValues( + WritableDataBufferSP &data_sp) { if (m_reg_data_addr != LLDB_INVALID_ADDRESS) { ProcessSP process_sp(CalculateProcess()); if (process_sp) { diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h index c3b9ec72ca22..2aad99ec9b21 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h @@ -50,7 +50,7 @@ public: bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue ®_value) override; - bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; @@ -61,6 +61,7 @@ protected: lldb_private::DynamicRegisterInfo &m_reg_infos; std::vector<bool> m_reg_valid; + lldb::WritableDataBufferSP m_data; lldb_private::DataExtractor m_reg_data; lldb::addr_t m_reg_data_addr; // If this is valid, then we have a register // context that is stored in memmory 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 4866cbd235e8..b5f2b0d2212d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp @@ -107,7 +107,7 @@ bool RegisterContextThreadMemory::WriteRegister( } bool RegisterContextThreadMemory::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { UpdateRegisterContext(); if (m_reg_ctx_sp) return m_reg_ctx_sp->ReadAllRegisterValues(data_sp); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.h index 40688a502a66..0a7314528f0a 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.h @@ -51,7 +51,7 @@ public: // is a somewhat disruptive operation, // so these API's should only be used when this behavior is needed. - bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; 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 d6c4a8687ec5..579ac6e36d0b 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 @@ -72,6 +72,12 @@ #include "RegisterInfos_arm64_sve.h" #undef DECLARE_REGISTER_INFOS_ARM64_STRUCT +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)}; + // Number of register sets provided by this context. enum { k_num_gpr_registers = gpr_w28 - gpr_x0 + 1, 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 ccfbd6afbefb..d647fcaa600a 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 @@ -784,10 +784,5 @@ static lldb_private::RegisterInfo g_register_infos_arm64_le[] = { {DEFINE_DBG(wcr, 15)} }; // 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/elf-core/ProcessElfCore.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp index 043544f05665..58b4fe3add1b 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 @@ -15,11 +15,13 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" +#include "lldb/Target/ABI.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/Target.h" #include "lldb/Target/UnixSignals.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/State.h" @@ -280,6 +282,9 @@ bool ProcessElfCore::IsAlive() { return true; } // Process Memory size_t ProcessElfCore::ReadMemory(lldb::addr_t addr, void *buf, size_t size, Status &error) { + if (lldb::ABISP abi_sp = GetABI()) + addr = abi_sp->FixAnyAddress(addr); + // Don't allow the caching that lldb_private::Process::ReadMemory does since // in core files we have it all cached our our core file anyway. return DoReadMemory(addr, buf, size, error); @@ -402,7 +407,7 @@ static void ParseFreeBSDPrStatus(ThreadData &thread_data, lldb::offset_t offset = 0; int pr_version = data.GetU32(&offset); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); if (log) { if (pr_version > 1) LLDB_LOGF(log, "FreeBSD PRSTATUS unexpected version %d", pr_version); @@ -430,7 +435,7 @@ static void ParseFreeBSDPrPsInfo(ProcessElfCore &process, lldb::offset_t offset = 0; int pr_version = data.GetU32(&offset); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); if (log) { if (pr_version > 1) LLDB_LOGF(log, "FreeBSD PRPSINFO unexpected version %d", pr_version); 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 f0aee04b5f62..3a62081827c6 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 @@ -55,7 +55,7 @@ bool RegisterContextCorePOSIX_arm::ReadRegister(const RegisterInfo *reg_info, } bool RegisterContextCorePOSIX_arm::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { return false; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h index de343f9001e0..8d773a046bca 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h @@ -30,7 +30,7 @@ public: bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value) override; - bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; 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 e56aa88b57d9..bb88ce9e9e50 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 @@ -230,7 +230,7 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info, } bool RegisterContextCorePOSIX_arm64::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { 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 3988e3539b89..f8548562adba 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 @@ -31,7 +31,7 @@ public: bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value) override; - bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; 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 5b1eb8b5437d..56e68742ead7 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 @@ -72,7 +72,7 @@ bool RegisterContextCorePOSIX_mips64::ReadRegister(const RegisterInfo *reg_info, } bool RegisterContextCorePOSIX_mips64::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { return false; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h index b42a76c082f0..529b00215e35 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h @@ -30,7 +30,7 @@ public: bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value) override; - bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; 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 8380731692a3..4e7be91c3895 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 @@ -92,7 +92,7 @@ bool RegisterContextCorePOSIX_powerpc::ReadRegister( } bool RegisterContextCorePOSIX_powerpc::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { return false; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h index cf50b6e0bf70..5364c5589238 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h @@ -29,7 +29,7 @@ public: bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value) override; - bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; 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 f1cd6897616d..69707eeb3f1e 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 @@ -77,7 +77,7 @@ bool RegisterContextCorePOSIX_s390x::ReadRegister(const RegisterInfo *reg_info, } bool RegisterContextCorePOSIX_s390x::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { return false; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h index 4560f062e06f..edb7cbc9462f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h @@ -29,7 +29,7 @@ public: bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value) override; - bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp index 6eaad9f381d6..6bc8edb9226f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp @@ -80,7 +80,7 @@ bool RegisterContextCorePOSIX_x86_64::ReadRegister(const RegisterInfo *reg_info, } bool RegisterContextCorePOSIX_x86_64::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { return false; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h index 9adfbf7e6852..46416a2381db 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h @@ -26,7 +26,7 @@ public: bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value) override; - bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; 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 5086cfaa6536..357140d269f1 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 @@ -11,6 +11,7 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Unwind.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h" @@ -68,7 +69,7 @@ RegisterContextSP ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { RegisterContextSP reg_ctx_sp; uint32_t concrete_frame_idx = 0; - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); if (frame) concrete_frame_idx = frame->GetConcreteFrameIndex(); 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 8364ffeef46f..e3a3cfc4f23e 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 @@ -347,7 +347,7 @@ GDBRemoteClientBase::Lock::Lock(GDBRemoteClientBase &comm, } void GDBRemoteClientBase::Lock::SyncWithContinueThread() { - Log *log = GetLog(GDBRLog::Process); + Log *log = GetLog(GDBRLog::Process|GDBRLog::Packets); std::unique_lock<std::mutex> lock(m_comm.m_mutex); 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 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 38d9e400978d..e5461c1899ec 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 @@ -125,6 +125,29 @@ GDBRemoteCommunication::SendPacketNoLock(llvm::StringRef payload) { } GDBRemoteCommunication::PacketResult +GDBRemoteCommunication::SendNotificationPacketNoLock( + llvm::StringRef notify_type, std::deque<std::string> &queue, + llvm::StringRef payload) { + PacketResult ret = PacketResult::Success; + + // If there are no notification in the queue, send the notification + // packet. + if (queue.empty()) { + StreamString packet(0, 4, eByteOrderBig); + packet.PutChar('%'); + packet.Write(notify_type.data(), notify_type.size()); + packet.PutChar(':'); + packet.Write(payload.data(), payload.size()); + packet.PutChar('#'); + packet.PutHex8(CalculcateChecksum(payload)); + ret = SendRawPacketNoLock(packet.GetString(), true); + } + + queue.push_back(payload.str()); + return ret; +} + +GDBRemoteCommunication::PacketResult GDBRemoteCommunication::SendRawPacketNoLock(llvm::StringRef packet, bool skip_ack) { if (IsConnected()) { @@ -843,7 +866,7 @@ Status GDBRemoteCommunication::StartListenThread(const char *hostname, m_listen_url = listen_url; SetConnection(std::make_unique<ConnectionFileDescriptor>()); llvm::Expected<HostThread> listen_thread = ThreadLauncher::LaunchThread( - listen_url, GDBRemoteCommunication::ListenThread, this); + listen_url, [this] { return GDBRemoteCommunication::ListenThread(); }); if (!listen_thread) return Status(listen_thread.takeError()); m_listen_thread = *listen_thread; @@ -857,23 +880,22 @@ bool GDBRemoteCommunication::JoinListenThread() { return true; } -lldb::thread_result_t -GDBRemoteCommunication::ListenThread(lldb::thread_arg_t arg) { - GDBRemoteCommunication *comm = (GDBRemoteCommunication *)arg; +lldb::thread_result_t GDBRemoteCommunication::ListenThread() { Status error; ConnectionFileDescriptor *connection = - (ConnectionFileDescriptor *)comm->GetConnection(); + (ConnectionFileDescriptor *)GetConnection(); if (connection) { // Do the listen on another thread so we can continue on... if (connection->Connect( - comm->m_listen_url.c_str(), [comm](llvm::StringRef port_str) { + m_listen_url.c_str(), + [this](llvm::StringRef port_str) { uint16_t port = 0; llvm::to_integer(port_str, port, 10); - comm->m_port_promise.set_value(port); + m_port_promise.set_value(port); }, &error) != eConnectionStatusSuccess) - comm->SetConnection(nullptr); + SetConnection(nullptr); } return {}; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h index afc7e740d4c9..35e86c202b5b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h @@ -183,6 +183,9 @@ protected: CompressionType m_compression_type; PacketResult SendPacketNoLock(llvm::StringRef payload); + PacketResult SendNotificationPacketNoLock(llvm::StringRef notify_type, + std::deque<std::string>& queue, + llvm::StringRef payload); PacketResult SendRawPacketNoLock(llvm::StringRef payload, bool skip_ack = false); @@ -218,7 +221,7 @@ protected: bool JoinListenThread(); - static lldb::thread_result_t ListenThread(lldb::thread_arg_t arg); + lldb::thread_result_t ListenThread(); private: // Promise used to grab the port number from listening thread 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 91b9151328a8..700e6ebdf84c 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 @@ -24,6 +24,7 @@ #include "lldb/Utility/Args.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/State.h" #include "lldb/Utility/StreamString.h" @@ -642,7 +643,7 @@ DataBufferSP GDBRemoteCommunicationClient::ReadMemoryTags(lldb::addr_t addr, } size_t expected_bytes = response.GetBytesLeft() / 2; - DataBufferSP buffer_sp(new DataBufferHeap(expected_bytes, 0)); + WritableDataBufferSP 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. @@ -2227,8 +2228,10 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) { m_process_arch.SetArchitecture(eArchTypeCOFF, cpu, sub); break; case llvm::Triple::GOFF: + case llvm::Triple::SPIRV: case llvm::Triple::Wasm: case llvm::Triple::XCOFF: + case llvm::Triple::DXContainer: LLDB_LOGF(log, "error: not supported target architecture"); return false; case llvm::Triple::UnknownObjectFormat: @@ -2245,9 +2248,6 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) { m_process_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name)); m_process_arch.GetTriple().setOSName(llvm::StringRef(os_name)); m_process_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment)); - m_host_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name)); - m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name)); - m_host_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment)); } return true; } @@ -2697,8 +2697,8 @@ GDBRemoteCommunicationClient::SendSetCurrentThreadPacket(uint64_t tid, packet.Printf("%" PRIx64, tid); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(packet.GetString(), response) - == PacketResult::Success) { + if (SendPacketAndWaitForResponse(packet.GetString(), response) == + PacketResult::Success) { if (response.IsOKResponse()) return {{pid, tid}}; @@ -2722,7 +2722,7 @@ bool GDBRemoteCommunicationClient::SetCurrentThread(uint64_t tid, return true; llvm::Optional<PidTid> ret = SendSetCurrentThreadPacket(tid, pid, 'g'); - if (ret.hasValue()) { + if (ret) { if (ret->pid != LLDB_INVALID_PROCESS_ID) m_curr_pid = ret->pid; m_curr_tid = ret->tid; @@ -2737,7 +2737,7 @@ bool GDBRemoteCommunicationClient::SetCurrentThreadForRun(uint64_t tid, return true; llvm::Optional<PidTid> ret = SendSetCurrentThreadPacket(tid, pid, 'c'); - if (ret.hasValue()) { + if (ret) { if (ret->pid != LLDB_INVALID_PROCESS_ID) m_curr_pid_run = ret->pid; m_curr_tid_run = ret->tid; @@ -2778,7 +2778,7 @@ bool GDBRemoteCommunicationClient::GetThreadStopInfo( uint8_t GDBRemoteCommunicationClient::SendGDBStoppointTypePacket( GDBStoppointType type, bool insert, addr_t addr, uint32_t length, std::chrono::seconds timeout) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64, __FUNCTION__, insert ? "add" : "remove", addr); @@ -2865,7 +2865,7 @@ GDBRemoteCommunicationClient::GetCurrentProcessAndThreadIDs( if (!pid_tid) break; - ids.push_back(pid_tid.getValue()); + ids.push_back(*pid_tid); ch = response.GetChar(); // Skip the command separator } while (ch == ','); // Make sure we got a comma separator } @@ -3443,7 +3443,7 @@ DataBufferSP GDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid, !response.IsNormalResponse()) return nullptr; - DataBufferSP buffer_sp( + WritableDataBufferSP buffer_sp( new DataBufferHeap(response.GetStringRef().size() / 2, 0)); response.GetHexBytes(buffer_sp->GetData(), '\xcc'); return buffer_sp; @@ -3458,7 +3458,7 @@ DataBufferSP GDBRemoteCommunicationClient::ReadAllRegisters(lldb::tid_t tid) { !response.IsNormalResponse()) return nullptr; - DataBufferSP buffer_sp( + WritableDataBufferSP buffer_sp( new DataBufferHeap(response.GetStringRef().size() / 2, 0)); response.GetHexBytes(buffer_sp->GetData(), '\xcc'); return buffer_sp; @@ -3701,9 +3701,6 @@ GDBRemoteCommunicationClient::SendTraceGetBinaryData( GDBRemoteCommunication::PacketResult::Success) { 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()); 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 f371649842e8..2a58f2028386 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 @@ -30,6 +30,7 @@ #include "lldb/Target/Platform.h" #include "lldb/Utility/Endian.h" #include "lldb/Utility/GDBRemote.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/StructuredData.h" @@ -426,7 +427,7 @@ GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerCommon::Handle_qUserName( StringExtractorGDBRemote &packet) { #if LLDB_ENABLE_POSIX - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "GDBRemoteCommunicationServerCommon::%s begin", __FUNCTION__); // Packet format: "qUserName:%i" where %i is the uid @@ -1020,7 +1021,7 @@ GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) { // encoded argument value list, but we will stay true to the documented // version of the 'A' packet here... - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); int actual_arg_index = 0; packet.SetFilePos(1); // Skip the 'A' 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 029972348ef0..f696cb5c61c6 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 @@ -15,7 +15,6 @@ #include "lldb/lldb-private-forward.h" #include "GDBRemoteCommunicationServer.h" -#include "GDBRemoteCommunicationServerCommon.h" class StringExtractorGDBRemote; 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 123a8198a89b..63174ef55219 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 @@ -35,6 +35,7 @@ #include "lldb/Utility/Endian.h" #include "lldb/Utility/GDBRemote.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/State.h" @@ -106,6 +107,8 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() { &GDBRemoteCommunicationServerLLGS::Handle_P); RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qC, &GDBRemoteCommunicationServerLLGS::Handle_qC); + RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_T, + &GDBRemoteCommunicationServerLLGS::Handle_T); RegisterMemberFunctionHandler( StringExtractorGDBRemote::eServerPacketType_qfThreadInfo, &GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo); @@ -232,8 +235,22 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() { }); RegisterMemberFunctionHandler( + StringExtractorGDBRemote::eServerPacketType_vKill, + &GDBRemoteCommunicationServerLLGS::Handle_vKill); + + RegisterMemberFunctionHandler( StringExtractorGDBRemote::eServerPacketType_qLLDBSaveCore, &GDBRemoteCommunicationServerLLGS::Handle_qSaveCore); + + RegisterMemberFunctionHandler( + StringExtractorGDBRemote::eServerPacketType_QNonStop, + &GDBRemoteCommunicationServerLLGS::Handle_QNonStop); + RegisterMemberFunctionHandler( + StringExtractorGDBRemote::eServerPacketType_vStopped, + &GDBRemoteCommunicationServerLLGS::Handle_vStopped); + RegisterMemberFunctionHandler( + StringExtractorGDBRemote::eServerPacketType_vCtrlC, + &GDBRemoteCommunicationServerLLGS::Handle_vCtrlC); } void GDBRemoteCommunicationServerLLGS::SetLaunchInfo(const ProcessLaunchInfo &info) { @@ -241,7 +258,7 @@ void GDBRemoteCommunicationServerLLGS::SetLaunchInfo(const ProcessLaunchInfo &in } Status GDBRemoteCommunicationServerLLGS::LaunchProcess() { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); if (!m_process_launch_info.GetArguments().GetArgumentCount()) return Status("%s: no process command line specified to launch", @@ -323,7 +340,7 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() { } Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64, __FUNCTION__, pid); @@ -370,7 +387,7 @@ Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) { Status GDBRemoteCommunicationServerLLGS::AttachWaitProcess( llvm::StringRef process_name, bool include_existing) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); std::chrono::milliseconds polling_interval = std::chrono::milliseconds(1); @@ -440,7 +457,7 @@ Status GDBRemoteCommunicationServerLLGS::AttachWaitProcess( void GDBRemoteCommunicationServerLLGS::InitializeDelegate( NativeProcessProtocol *process) { assert(process && "process cannot be NULL"); - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); if (log) { LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called with " @@ -454,7 +471,7 @@ GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::SendWResponse( NativeProcessProtocol *process) { assert(process && "process cannot be NULL"); - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); // send W notification auto wait_status = process->GetExitStatus(); @@ -471,8 +488,17 @@ GDBRemoteCommunicationServerLLGS::SendWResponse( LLDB_LOG(log, "pid = {0}, returning exit type {1}", process->GetID(), *wait_status); + // If the process was killed through vKill, return "OK". + if (m_vkilled_processes.find(process->GetID()) != m_vkilled_processes.end()) + return SendOKResponse(); + StreamGDBRemote response; response.Format("{0:g}", *wait_status); + if (bool(m_extensions_supported & NativeProcessProtocol::Extension::multiprocess)) + response.Format(";process:{0:x-}", process->GetID()); + if (m_non_stop) + return SendNotificationPacketNoLock("Stop", m_stop_notification_queue, + response.GetString()); return SendPacketNoLock(response.GetString()); } @@ -608,7 +634,7 @@ static void WriteRegisterValueInHexFixedWidth( static llvm::Optional<json::Object> GetRegistersAsJSON(NativeThreadProtocol &thread) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); NativeRegisterContext& reg_ctx = thread.GetRegisterContext(); @@ -693,26 +719,21 @@ static const char *GetStopReasonString(StopReason stop_reason) { static llvm::Expected<json::Array> GetJSONThreadsInfo(NativeProcessProtocol &process, bool abridged) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread); json::Array threads_array; // Ensure we can get info on the given thread. - uint32_t thread_idx = 0; - for (NativeThreadProtocol *thread; - (thread = process.GetThreadAtIndex(thread_idx)) != nullptr; - ++thread_idx) { - - lldb::tid_t tid = thread->GetID(); - + for (NativeThreadProtocol &thread : process.Threads()) { + lldb::tid_t tid = thread.GetID(); // Grab the reason this thread stopped. struct ThreadStopInfo tid_stop_info; std::string description; - if (!thread->GetStopReason(tid_stop_info, description)) + if (!thread.GetStopReason(tid_stop_info, description)) return llvm::make_error<llvm::StringError>( "failed to get stop reason", llvm::inconvertibleErrorCode()); - const int signum = tid_stop_info.details.signal.signo; + const int signum = tid_stop_info.signo; if (log) { LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 @@ -725,7 +746,7 @@ GetJSONThreadsInfo(NativeProcessProtocol &process, bool abridged) { json::Object thread_obj; if (!abridged) { - if (llvm::Optional<json::Object> registers = GetRegistersAsJSON(*thread)) + if (llvm::Optional<json::Object> registers = GetRegistersAsJSON(thread)) thread_obj.try_emplace("registers", std::move(*registers)); } @@ -734,7 +755,7 @@ GetJSONThreadsInfo(NativeProcessProtocol &process, bool abridged) { if (signum != 0) thread_obj.try_emplace("signal", signum); - const std::string thread_name = thread->GetName(); + const std::string thread_name = thread.GetName(); if (!thread_name.empty()) thread_obj.try_emplace("name", thread_name); @@ -763,29 +784,22 @@ GetJSONThreadsInfo(NativeProcessProtocol &process, bool abridged) { return threads_array; } -GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( - lldb::tid_t tid) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); +StreamString +GDBRemoteCommunicationServerLLGS::PrepareStopReplyPacketForThread( + NativeThreadProtocol &thread) { + Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread); - // Ensure we have a debugged process. - if (!m_current_process || - (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) - return SendErrorResponse(50); + NativeProcessProtocol &process = thread.GetProcess(); - LLDB_LOG(log, "preparing packet for pid {0} tid {1}", - m_current_process->GetID(), tid); - - // Ensure we can get info on the given thread. - NativeThreadProtocol *thread = m_current_process->GetThreadByID(tid); - if (!thread) - return SendErrorResponse(51); + LLDB_LOG(log, "preparing packet for pid {0} tid {1}", process.GetID(), + thread.GetID()); // Grab the reason this thread stopped. + StreamString response; struct ThreadStopInfo tid_stop_info; std::string description; - if (!thread->GetStopReason(tid_stop_info, description)) - return SendErrorResponse(52); + if (!thread.GetStopReason(tid_stop_info, description)) + return response; // FIXME implement register handling for exec'd inferiors. // if (tid_stop_info.reason == eStopReasonExec) { @@ -793,24 +807,25 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( // InitializeRegisters(force); // } - StreamString response; // Output the T packet with the thread response.PutChar('T'); - int signum = tid_stop_info.details.signal.signo; + int signum = tid_stop_info.signo; LLDB_LOG( log, "pid {0}, tid {1}, got signal signo = {2}, reason = {3}, exc_type = {4}", - m_current_process->GetID(), tid, signum, int(tid_stop_info.reason), + process.GetID(), thread.GetID(), signum, int(tid_stop_info.reason), tid_stop_info.details.exception.type); // Print the signal number. response.PutHex8(signum & 0xff); - // Include the tid. - response.Printf("thread:%" PRIx64 ";", tid); + // Include the (pid and) tid. + response.PutCString("thread:"); + AppendThreadIDToResponse(response, process.GetID(), thread.GetID()); + response.PutChar(';'); // Include the thread name if there is one. - const std::string thread_name = thread->GetName(); + const std::string thread_name = thread.GetName(); if (!thread_name.empty()) { size_t thread_name_len = thread_name.length(); @@ -836,14 +851,12 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( if (m_list_threads_in_stop_reply) { response.PutCString("threads:"); - uint32_t thread_index = 0; - NativeThreadProtocol *listed_thread; - for (listed_thread = m_current_process->GetThreadAtIndex(thread_index); - listed_thread; ++thread_index, - listed_thread = m_current_process->GetThreadAtIndex(thread_index)) { - if (thread_index > 0) + uint32_t thread_num = 0; + for (NativeThreadProtocol &listed_thread : process.Threads()) { + if (thread_num > 0) response.PutChar(','); - response.Printf("%" PRIx64, listed_thread->GetID()); + response.Printf("%" PRIx64, listed_thread.GetID()); + ++thread_num; } response.PutChar(';'); @@ -852,7 +865,7 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( // is hex ascii JSON that contains the thread IDs thread stop info only for // threads that have stop reasons. Only send this if we have more than one // thread otherwise this packet has all the info it needs. - if (thread_index > 1) { + if (thread_num > 1) { const bool threads_with_valid_stop_info_only = true; llvm::Expected<json::Array> threads_info = GetJSONThreadsInfo( *m_current_process, threads_with_valid_stop_info_only); @@ -865,16 +878,14 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( } else { LLDB_LOG_ERROR(log, threads_info.takeError(), "failed to prepare a jstopinfo field for pid {1}: {0}", - m_current_process->GetID()); + process.GetID()); } } - uint32_t i = 0; response.PutCString("thread-pcs"); char delimiter = ':'; - for (NativeThreadProtocol *thread; - (thread = m_current_process->GetThreadAtIndex(i)) != nullptr; ++i) { - NativeRegisterContext& reg_ctx = thread->GetRegisterContext(); + for (NativeThreadProtocol &thread : process.Threads()) { + NativeRegisterContext ®_ctx = thread.GetRegisterContext(); uint32_t reg_to_read = reg_ctx.ConvertRegisterKindToRegisterNumber( eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); @@ -905,7 +916,7 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( // // Grab the register context. - NativeRegisterContext& reg_ctx = thread->GetRegisterContext(); + NativeRegisterContext ®_ctx = thread.GetRegisterContext(); const auto expedited_regs = reg_ctx.GetExpeditedRegisters(ExpeditedRegs::Full); @@ -922,8 +933,9 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( ®_value, lldb::eByteOrderBig); response.PutChar(';'); } else { - LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s failed to read " - "register '%s' index %" PRIu32 ": %s", + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s failed to read " + "register '%s' index %" PRIu32 ": %s", __FUNCTION__, reg_info_p->name ? reg_info_p->name : "<unnamed-register>", reg_num, error.AsCString()); @@ -972,17 +984,53 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( tid_stop_info.details.fork.child_tid); } + return response; +} + +GDBRemoteCommunication::PacketResult +GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( + NativeProcessProtocol &process, lldb::tid_t tid, bool force_synchronous) { + // Ensure we can get info on the given thread. + NativeThreadProtocol *thread = process.GetThreadByID(tid); + if (!thread) + return SendErrorResponse(51); + + StreamString response = PrepareStopReplyPacketForThread(*thread); + if (response.Empty()) + return SendErrorResponse(42); + + if (m_non_stop && !force_synchronous) { + PacketResult ret = SendNotificationPacketNoLock( + "Stop", m_stop_notification_queue, response.GetString()); + // Queue notification events for the remaining threads. + EnqueueStopReplyPackets(tid); + return ret; + } + return SendPacketNoLock(response.GetString()); } +void GDBRemoteCommunicationServerLLGS::EnqueueStopReplyPackets( + lldb::tid_t thread_to_skip) { + if (!m_non_stop) + return; + + for (NativeThreadProtocol &listed_thread : m_current_process->Threads()) { + if (listed_thread.GetID() != thread_to_skip) + m_stop_notification_queue.push_back( + PrepareStopReplyPacketForThread(listed_thread).GetString().str()); + } +} + void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Exited( NativeProcessProtocol *process) { assert(process && "process cannot be NULL"); - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); - PacketResult result = SendStopReasonForState(StateType::eStateExited); + PacketResult result = SendStopReasonForState( + *process, StateType::eStateExited, /*force_synchronous=*/false); if (result != PacketResult::Success) { LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s failed to send stop " @@ -990,20 +1038,37 @@ void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Exited( __FUNCTION__, process->GetID()); } - // Close the pipe to the inferior terminal i/o if we launched it and set one - // up. - MaybeCloseInferiorTerminalConnection(); - - // We are ready to exit the debug monitor. - m_exit_now = true; - m_mainloop.RequestTermination(); + if (m_current_process == process) + m_current_process = nullptr; + if (m_continue_process == process) + m_continue_process = nullptr; + + lldb::pid_t pid = process->GetID(); + m_mainloop.AddPendingCallback([this, pid](MainLoopBase &loop) { + m_debugged_processes.erase(pid); + auto vkill_it = m_vkilled_processes.find(pid); + if (vkill_it != m_vkilled_processes.end()) + m_vkilled_processes.erase(vkill_it); + // Terminate the main loop only if vKill has not been used. + // When running in non-stop mode, wait for the vStopped to clear + // the notification queue. + else if (m_debugged_processes.empty() && !m_non_stop) { + // Close the pipe to the inferior terminal i/o if we launched it and set + // one up. + MaybeCloseInferiorTerminalConnection(); + + // We are ready to exit the debug monitor. + m_exit_now = true; + loop.RequestTermination(); + } + }); } void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped( NativeProcessProtocol *process) { assert(process && "process cannot be NULL"); - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); // Send the stop reason unless this is the stop after the launch or attach. @@ -1014,7 +1079,8 @@ void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped( break; default: // In all other cases, send the stop reason. - PacketResult result = SendStopReasonForState(StateType::eStateStopped); + PacketResult result = SendStopReasonForState( + *process, StateType::eStateStopped, /*force_synchronous=*/false); if (result != PacketResult::Success) { LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s failed to send stop " @@ -1028,7 +1094,7 @@ void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped( void GDBRemoteCommunicationServerLLGS::ProcessStateChanged( NativeProcessProtocol *process, lldb::StateType state) { assert(process && "process cannot be NULL"); - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); if (log) { LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called with " @@ -1038,7 +1104,6 @@ void GDBRemoteCommunicationServerLLGS::ProcessStateChanged( switch (state) { case StateType::eStateRunning: - StartSTDIOForwarding(); break; case StateType::eStateStopped: @@ -1163,7 +1228,7 @@ void GDBRemoteCommunicationServerLLGS::StartSTDIOForwarding() { return; Status error; - lldbassert(!m_stdio_handle_up); + assert(!m_stdio_handle_up); m_stdio_handle_up = m_mainloop.RegisterReadObject( m_stdio_communication.GetConnection()->GetReadObject(), [this](MainLoopBase &) { SendProcessOutput(); }, error); @@ -1171,11 +1236,8 @@ void GDBRemoteCommunicationServerLLGS::StartSTDIOForwarding() { if (!m_stdio_handle_up) { // Not much we can do about the failure. Log it and continue without // forwarding. - if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)) - LLDB_LOGF(log, - "GDBRemoteCommunicationServerLLGS::%s Failed to set up stdio " - "forwarding: %s", - __FUNCTION__, error.AsCString()); + if (Log *log = GetLog(LLDBLog::Process)) + LLDB_LOG(log, "Failed to set up stdio forwarding: {0}", error); } } @@ -1198,7 +1260,7 @@ void GDBRemoteCommunicationServerLLGS::SendProcessOutput() { case eConnectionStatusEndOfFile: case eConnectionStatusError: case eConnectionStatusNoConnection: - if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)) + if (Log *log = GetLog(LLDBLog::Process)) LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s Stopping stdio " "forwarding as communication returned status %d (error: " @@ -1349,29 +1411,61 @@ GDBRemoteCommunicationServerLLGS::Handle_qC(StringExtractorGDBRemote &packet) { return SendErrorResponse(69); StreamString response; - response.Printf("QC%" PRIx64, thread->GetID()); + response.PutCString("QC"); + AppendThreadIDToResponse(response, m_current_process->GetID(), + thread->GetID()); return SendPacketNoLock(response.GetString()); } GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_k(StringExtractorGDBRemote &packet) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); StopSTDIOForwarding(); - if (!m_current_process) { + if (m_debugged_processes.empty()) { LLDB_LOG(log, "No debugged process found."); return PacketResult::Success; } - Status error = m_current_process->Kill(); + for (auto it = m_debugged_processes.begin(); it != m_debugged_processes.end(); + ++it) { + LLDB_LOG(log, "Killing process {0}", it->first); + Status error = it->second->Kill(); + if (error.Fail()) + LLDB_LOG(log, "Failed to kill debugged process {0}: {1}", it->first, + error); + } + + // The response to kill packet is undefined per the spec. LLDB + // follows the same rules as for continue packets, i.e. no response + // in all-stop mode, and "OK" in non-stop mode; in both cases this + // is followed by the actual stop reason. + return SendContinueSuccessResponse(); +} + +GDBRemoteCommunication::PacketResult +GDBRemoteCommunicationServerLLGS::Handle_vKill( + StringExtractorGDBRemote &packet) { + StopSTDIOForwarding(); + + packet.SetFilePos(6); // vKill; + uint32_t pid = packet.GetU32(LLDB_INVALID_PROCESS_ID, 16); + if (pid == LLDB_INVALID_PROCESS_ID) + return SendIllFormedResponse(packet, + "vKill failed to parse the process id"); + + auto it = m_debugged_processes.find(pid); + if (it == m_debugged_processes.end()) + return SendErrorResponse(42); + + Status error = it->second->Kill(); if (error.Fail()) - LLDB_LOG(log, "Failed to kill debugged process {0}: {1}", - m_current_process->GetID(), error); + return SendErrorResponse(error.ToError()); - // No OK response for kill packet. - // return SendOKResponse (); + // OK response is sent when the process dies. + m_vkilled_processes.insert(pid); return PacketResult::Success; } @@ -1425,7 +1519,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QListThreadsInStopReply( GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_C(StringExtractorGDBRemote &packet) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread); LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); // Ensure we have a native process. @@ -1500,13 +1594,14 @@ GDBRemoteCommunicationServerLLGS::Handle_C(StringExtractorGDBRemote &packet) { return SendErrorResponse(0x38); } - // Don't send an "OK" packet; response is the stopped/exited message. - return PacketResult::Success; + // Don't send an "OK" packet, except in non-stop mode; + // otherwise, the response is the stopped/exited message. + return SendContinueSuccessResponse(); } GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_c(StringExtractorGDBRemote &packet) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread); LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); packet.SetFilePos(packet.GetFilePos() + ::strlen("c")); @@ -1540,15 +1635,15 @@ GDBRemoteCommunicationServerLLGS::Handle_c(StringExtractorGDBRemote &packet) { } LLDB_LOG(log, "continued process {0}", m_continue_process->GetID()); - // No response required from continue. - return PacketResult::Success; + + return SendContinueSuccessResponse(); } GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_vCont_actions( StringExtractorGDBRemote &packet) { StreamString response; - response.Printf("vCont;c;C;s;S"); + response.Printf("vCont;c;C;s;S;t"); return SendPacketNoLock(response.GetString()); } @@ -1556,7 +1651,7 @@ GDBRemoteCommunicationServerLLGS::Handle_vCont_actions( GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_vCont( StringExtractorGDBRemote &packet) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s handling vCont packet", __FUNCTION__); @@ -1570,24 +1665,16 @@ GDBRemoteCommunicationServerLLGS::Handle_vCont( return SendIllFormedResponse(packet, "Missing action from vCont package"); } - // Check if this is all continue (no options or ";c"). - if (::strcmp(packet.Peek(), ";c") == 0) { - // Move past the ';', then do a simple 'c'. - packet.SetFilePos(packet.GetFilePos() + 1); - return Handle_c(packet); - } else if (::strcmp(packet.Peek(), ";s") == 0) { + if (::strcmp(packet.Peek(), ";s") == 0) { // Move past the ';', then do a simple 's'. packet.SetFilePos(packet.GetFilePos() + 1); return Handle_s(packet); + } else if (m_non_stop && ::strcmp(packet.Peek(), ";t") == 0) { + // TODO: add full support for "t" action + return SendOKResponse(); } - // Ensure we have a native process. - if (!m_continue_process) { - LLDB_LOG(log, "no debugged process"); - return SendErrorResponse(0x36); - } - - ResumeActionList thread_actions; + std::unordered_map<lldb::pid_t, ResumeActionList> thread_actions; while (packet.GetBytesLeft() && *packet.Peek() == ';') { // Skip the semi-colon. @@ -1625,43 +1712,78 @@ GDBRemoteCommunicationServerLLGS::Handle_vCont( thread_action.state = eStateStepping; break; + case 't': + // Stop + thread_action.state = eStateSuspended; + break; + default: return SendIllFormedResponse(packet, "Unsupported vCont action"); break; } + lldb::pid_t pid = StringExtractorGDBRemote::AllProcesses; + lldb::tid_t tid = StringExtractorGDBRemote::AllThreads; + // Parse out optional :{thread-id} value. if (packet.GetBytesLeft() && (*packet.Peek() == ':')) { // Consume the separator. packet.GetChar(); - llvm::Expected<lldb::tid_t> tid_ret = - ReadTid(packet, /*allow_all=*/true, m_continue_process->GetID()); - if (!tid_ret) - return SendErrorResponse(tid_ret.takeError()); + auto pid_tid = packet.GetPidTid(StringExtractorGDBRemote::AllProcesses); + if (!pid_tid) + return SendIllFormedResponse(packet, "Malformed thread-id"); + + pid = pid_tid->first; + tid = pid_tid->second; + } - thread_action.tid = tid_ret.get(); - if (thread_action.tid == StringExtractorGDBRemote::AllThreads) - thread_action.tid = LLDB_INVALID_THREAD_ID; + if (pid == StringExtractorGDBRemote::AllProcesses) { + if (m_debugged_processes.size() > 1) + return SendIllFormedResponse( + packet, "Resuming multiple processes not supported yet"); + if (!m_continue_process) { + LLDB_LOG(log, "no debugged process"); + return SendErrorResponse(0x36); + } + pid = m_continue_process->GetID(); } - thread_actions.Append(thread_action); + if (tid == StringExtractorGDBRemote::AllThreads) + tid = LLDB_INVALID_THREAD_ID; + + thread_action.tid = tid; + + thread_actions[pid].Append(thread_action); } - Status error = m_continue_process->Resume(thread_actions); - if (error.Fail()) { - LLDB_LOG(log, "vCont failed for process {0}: {1}", - m_continue_process->GetID(), error); - return SendErrorResponse(GDBRemoteServerError::eErrorResume); + assert(thread_actions.size() >= 1); + if (thread_actions.size() > 1) + return SendIllFormedResponse( + packet, "Resuming multiple processes not supported yet"); + + for (std::pair<lldb::pid_t, ResumeActionList> x : thread_actions) { + auto process_it = m_debugged_processes.find(x.first); + if (process_it == m_debugged_processes.end()) { + LLDB_LOG(log, "vCont failed for process {0}: process not debugged", + x.first); + return SendErrorResponse(GDBRemoteServerError::eErrorResume); + } + + Status error = process_it->second->Resume(x.second); + if (error.Fail()) { + LLDB_LOG(log, "vCont failed for process {0}: {1}", x.first, error); + return SendErrorResponse(GDBRemoteServerError::eErrorResume); + } + + LLDB_LOG(log, "continued process {0}", x.first); } - LLDB_LOG(log, "continued process {0}", m_continue_process->GetID()); - // No response required from vCont. - return PacketResult::Success; + return SendContinueSuccessResponse(); } void GDBRemoteCommunicationServerLLGS::SetCurrentThreadID(lldb::tid_t tid) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); LLDB_LOG(log, "setting current thread id to {0}", tid); m_current_tid = tid; @@ -1670,7 +1792,7 @@ void GDBRemoteCommunicationServerLLGS::SetCurrentThreadID(lldb::tid_t tid) { } void GDBRemoteCommunicationServerLLGS::SetContinueThreadID(lldb::tid_t tid) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); LLDB_LOG(log, "setting continue thread id to {0}", tid); m_continue_tid = tid; @@ -1681,17 +1803,47 @@ GDBRemoteCommunicationServerLLGS::Handle_stop_reason( StringExtractorGDBRemote &packet) { // Handle the $? gdbremote command. + if (m_non_stop) { + // Clear the notification queue first, except for pending exit + // notifications. + llvm::erase_if(m_stop_notification_queue, [](const std::string &x) { + return x.front() != 'W' && x.front() != 'X'; + }); + + if (m_current_process) { + // Queue stop reply packets for all active threads. Start with + // the current thread (for clients that don't actually support multiple + // stop reasons). + NativeThreadProtocol *thread = m_current_process->GetCurrentThread(); + if (thread) + m_stop_notification_queue.push_back( + PrepareStopReplyPacketForThread(*thread).GetString().str()); + EnqueueStopReplyPackets(thread ? thread->GetID() + : LLDB_INVALID_THREAD_ID); + } + + // If the notification queue is empty (i.e. everything is running), send OK. + if (m_stop_notification_queue.empty()) + return SendOKResponse(); + + // Send the first item from the new notification queue synchronously. + return SendPacketNoLock(m_stop_notification_queue.front()); + } + // If no process, indicate error if (!m_current_process) return SendErrorResponse(02); - return SendStopReasonForState(m_current_process->GetState()); + return SendStopReasonForState(*m_current_process, + m_current_process->GetState(), + /*force_synchronous=*/true); } GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::SendStopReasonForState( - lldb::StateType process_state) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + NativeProcessProtocol &process, lldb::StateType process_state, + bool force_synchronous) { + Log *log = GetLog(LLDBLog::Process); switch (process_state) { case eStateAttaching: @@ -1706,22 +1858,21 @@ GDBRemoteCommunicationServerLLGS::SendStopReasonForState( case eStateSuspended: case eStateStopped: case eStateCrashed: { - assert(m_current_process != nullptr); - lldb::tid_t tid = m_current_process->GetCurrentThreadID(); + lldb::tid_t tid = process.GetCurrentThreadID(); // Make sure we set the current thread so g and p packets return the data // the gdb will expect. SetCurrentThreadID(tid); - return SendStopReplyPacketForThread(tid); + return SendStopReplyPacketForThread(process, tid, force_synchronous); } case eStateInvalid: case eStateUnloaded: case eStateExited: - return SendWResponse(m_current_process); + return SendWResponse(&process); default: LLDB_LOG(log, "pid {0}, current state reporting not handled: {1}", - m_current_process->GetID(), process_state); + process.GetID(), process_state); break; } @@ -1819,38 +1970,38 @@ GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo( return SendPacketNoLock(response.GetString()); } +void GDBRemoteCommunicationServerLLGS::AddProcessThreads( + StreamGDBRemote &response, NativeProcessProtocol &process, bool &had_any) { + Log *log = GetLog(LLDBLog::Thread); + + lldb::pid_t pid = process.GetID(); + if (pid == LLDB_INVALID_PROCESS_ID) + return; + + LLDB_LOG(log, "iterating over threads of process {0}", process.GetID()); + for (NativeThreadProtocol &thread : process.Threads()) { + LLDB_LOG(log, "iterated thread tid={0}", thread.GetID()); + response.PutChar(had_any ? ',' : 'm'); + AppendThreadIDToResponse(response, pid, thread.GetID()); + had_any = true; + } +} + GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo( StringExtractorGDBRemote &packet) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); - - // Fail if we don't have a current process. - if (!m_current_process || - (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { - LLDB_LOG(log, "no process ({0}), returning OK", - m_current_process ? "invalid process id" - : "null m_current_process"); - return SendOKResponse(); - } + assert(m_debugged_processes.size() == 1 || + bool(m_extensions_supported & + NativeProcessProtocol::Extension::multiprocess)); + bool had_any = false; StreamGDBRemote response; - response.PutChar('m'); - LLDB_LOG(log, "starting thread iteration"); - NativeThreadProtocol *thread; - uint32_t thread_index; - for (thread_index = 0, - thread = m_current_process->GetThreadAtIndex(thread_index); - thread; ++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) - response.PutChar(','); - response.Printf("%" PRIx64, thread->GetID()); - } + for (auto &pid_ptr : m_debugged_processes) + AddProcessThreads(response, *pid_ptr.second, had_any); - LLDB_LOG(log, "finished thread iteration"); + if (!had_any) + return SendOKResponse(); return SendPacketNoLock(response.GetString()); } @@ -1864,7 +2015,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qsThreadInfo( GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_g(StringExtractorGDBRemote &packet) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); // Move past packet name. packet.SetFilePos(strlen("g")); @@ -1919,7 +2070,7 @@ GDBRemoteCommunicationServerLLGS::Handle_g(StringExtractorGDBRemote &packet) { GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); // Parse out the register number from the request. packet.SetFilePos(strlen("p")); @@ -1995,7 +2146,7 @@ GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) { GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); // Ensure there is more content. if (packet.GetBytesLeft() < 1) @@ -2075,7 +2226,7 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) { GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); // Parse out which variant of $H is requested. packet.SetFilePos(strlen("H")); @@ -2166,7 +2317,7 @@ GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) { GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_I(StringExtractorGDBRemote &packet) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); // Fail if we don't have a current process. if (!m_current_process || @@ -2202,7 +2353,7 @@ GDBRemoteCommunicationServerLLGS::Handle_I(StringExtractorGDBRemote &packet) { GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_interrupt( StringExtractorGDBRemote &packet) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread); // Fail if we don't have a current process. if (!m_current_process || @@ -2228,7 +2379,7 @@ GDBRemoteCommunicationServerLLGS::Handle_interrupt( GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_memory_read( StringExtractorGDBRemote &packet) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); if (!m_current_process || (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { @@ -2308,7 +2459,7 @@ GDBRemoteCommunicationServerLLGS::Handle_memory_read( GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle__M(StringExtractorGDBRemote &packet) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); if (!m_current_process || (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { @@ -2357,7 +2508,7 @@ GDBRemoteCommunicationServerLLGS::Handle__M(StringExtractorGDBRemote &packet) { GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle__m(StringExtractorGDBRemote &packet) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); if (!m_current_process || (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { @@ -2385,7 +2536,7 @@ GDBRemoteCommunicationServerLLGS::Handle__m(StringExtractorGDBRemote &packet) { GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_M(StringExtractorGDBRemote &packet) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); if (!m_current_process || (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { @@ -2465,7 +2616,7 @@ GDBRemoteCommunicationServerLLGS::Handle_M(StringExtractorGDBRemote &packet) { GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported( StringExtractorGDBRemote &packet) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); // Currently only the NativeProcessProtocol knows if it can handle a // qMemoryRegionInfoSupported request, but we're not guaranteed to be @@ -2498,7 +2649,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported( GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo( StringExtractorGDBRemote &packet) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); // Ensure we have a process. if (!m_current_process || @@ -2580,7 +2731,7 @@ GDBRemoteCommunicationServerLLGS::Handle_Z(StringExtractorGDBRemote &packet) { // Ensure we have a process. if (!m_current_process || (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOG(log, "failed, no process available"); return SendErrorResponse(0x15); } @@ -2652,7 +2803,7 @@ GDBRemoteCommunicationServerLLGS::Handle_Z(StringExtractorGDBRemote &packet) { m_current_process->SetBreakpoint(addr, size, want_hardware); if (error.Success()) return SendOKResponse(); - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); LLDB_LOG(log, "pid {0} failed to set breakpoint: {1}", m_current_process->GetID(), error); return SendErrorResponse(0x09); @@ -2662,7 +2813,7 @@ GDBRemoteCommunicationServerLLGS::Handle_Z(StringExtractorGDBRemote &packet) { addr, size, watch_flags, want_hardware); if (error.Success()) return SendOKResponse(); - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); LLDB_LOG(log, "pid {0} failed to set watchpoint: {1}", m_current_process->GetID(), error); return SendErrorResponse(0x09); @@ -2674,7 +2825,7 @@ GDBRemoteCommunicationServerLLGS::Handle_z(StringExtractorGDBRemote &packet) { // Ensure we have a process. if (!m_current_process || (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOG(log, "failed, no process available"); return SendErrorResponse(0x15); } @@ -2740,7 +2891,7 @@ GDBRemoteCommunicationServerLLGS::Handle_z(StringExtractorGDBRemote &packet) { m_current_process->RemoveBreakpoint(addr, want_hardware); if (error.Success()) return SendOKResponse(); - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); LLDB_LOG(log, "pid {0} failed to remove breakpoint: {1}", m_current_process->GetID(), error); return SendErrorResponse(0x09); @@ -2749,7 +2900,7 @@ GDBRemoteCommunicationServerLLGS::Handle_z(StringExtractorGDBRemote &packet) { const Status error = m_current_process->RemoveWatchpoint(addr); if (error.Success()) return SendOKResponse(); - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); LLDB_LOG(log, "pid {0} failed to remove watchpoint: {1}", m_current_process->GetID(), error); return SendErrorResponse(0x09); @@ -2758,7 +2909,7 @@ GDBRemoteCommunicationServerLLGS::Handle_z(StringExtractorGDBRemote &packet) { GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread); // Ensure we have a process. if (!m_continue_process || @@ -2803,8 +2954,9 @@ GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) { return SendErrorResponse(0x49); } - // No response here - the stop or exit will come from the resulting action. - return PacketResult::Success; + // No response here, unless in non-stop mode. + // Otherwise, the stop or exit will come from the resulting action. + return SendContinueSuccessResponse(); } llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> @@ -2815,7 +2967,7 @@ GDBRemoteCommunicationServerLLGS::BuildTargetXml() { return llvm::createStringError(llvm::inconvertibleErrorCode(), "No thread available"); - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread); // Get the register context for the first thread. NativeRegisterContext ®_context = thread->GetRegisterContext(); @@ -3032,7 +3184,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qXfer( GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState( StringExtractorGDBRemote &packet) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); // Move past packet name. packet.SetFilePos(strlen("QSaveRegisterState")); @@ -3052,7 +3204,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState( NativeRegisterContext& reg_context = thread->GetRegisterContext(); // Save registers to a buffer. - DataBufferSP register_data_sp; + WritableDataBufferSP register_data_sp; Status error = reg_context.ReadAllRegisterValues(register_data_sp); if (error.Fail()) { LLDB_LOG(log, "pid {0} failed to save all register values: {1}", @@ -3080,7 +3232,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState( GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState( StringExtractorGDBRemote &packet) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); // Parse out save id. packet.SetFilePos(strlen("QRestoreRegisterState:")); @@ -3141,7 +3293,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState( GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_vAttach( StringExtractorGDBRemote &packet) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); // Consume the ';' after vAttach. packet.SetFilePos(strlen("vAttach")); @@ -3171,13 +3323,16 @@ GDBRemoteCommunicationServerLLGS::Handle_vAttach( } // Notify we attached by sending a stop packet. - return SendStopReasonForState(m_current_process->GetState()); + assert(m_current_process); + return SendStopReasonForState(*m_current_process, + m_current_process->GetState(), + /*force_synchronous=*/false); } GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_vAttachWait( StringExtractorGDBRemote &packet) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); // Consume the ';' after the identifier. packet.SetFilePos(strlen("vAttachWait")); @@ -3201,7 +3356,10 @@ GDBRemoteCommunicationServerLLGS::Handle_vAttachWait( } // Notify we attached by sending a stop packet. - return SendStopReasonForState(m_current_process->GetState()); + assert(m_current_process); + return SendStopReasonForState(*m_current_process, + m_current_process->GetState(), + /*force_synchronous=*/false); } GDBRemoteCommunication::PacketResult @@ -3213,7 +3371,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qVAttachOrWaitSupported( GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_vAttachOrWait( StringExtractorGDBRemote &packet) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); // Consume the ';' after the identifier. packet.SetFilePos(strlen("vAttachOrWait")); @@ -3237,13 +3395,16 @@ GDBRemoteCommunicationServerLLGS::Handle_vAttachOrWait( } // Notify we attached by sending a stop packet. - return SendStopReasonForState(m_current_process->GetState()); + assert(m_current_process); + return SendStopReasonForState(*m_current_process, + m_current_process->GetState(), + /*force_synchronous=*/false); } GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_vRun( StringExtractorGDBRemote &packet) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); llvm::StringRef s = packet.GetStringRef(); if (!s.consume_front("vRun;")) @@ -3265,8 +3426,12 @@ GDBRemoteCommunicationServerLLGS::Handle_vRun( m_process_launch_info.GetExecutableFile().SetFile( m_process_launch_info.GetArguments()[0].ref(), FileSpec::Style::native); m_process_launch_error = LaunchProcess(); - if (m_process_launch_error.Success()) - return SendStopReasonForState(m_current_process->GetState()); + if (m_process_launch_error.Success()) { + assert(m_current_process); + return SendStopReasonForState(*m_current_process, + m_current_process->GetState(), + /*force_synchronous=*/true); + } LLDB_LOG(log, "failed to launch exe: {0}", m_process_launch_error); } return SendErrorResponse(8); @@ -3274,6 +3439,7 @@ GDBRemoteCommunicationServerLLGS::Handle_vRun( GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_D(StringExtractorGDBRemote &packet) { + Log *log = GetLog(LLDBLog::Process); StopSTDIOForwarding(); lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; @@ -3297,6 +3463,9 @@ GDBRemoteCommunicationServerLLGS::Handle_D(StringExtractorGDBRemote &packet) { for (auto it = m_debugged_processes.begin(); it != m_debugged_processes.end();) { if (pid == LLDB_INVALID_PROCESS_ID || pid == it->first) { + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s detaching %" PRId64, + __FUNCTION__, it->first); if (llvm::Error e = it->second->Detach().ToError()) detach_error = llvm::joinErrors(std::move(detach_error), std::move(e)); else { @@ -3322,7 +3491,11 @@ GDBRemoteCommunicationServerLLGS::Handle_D(StringExtractorGDBRemote &packet) { GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo( StringExtractorGDBRemote &packet) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); + + if (!m_current_process || + (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) + return SendErrorResponse(50); packet.SetFilePos(strlen("qThreadStopInfo")); const lldb::tid_t tid = packet.GetHexMaxU64(false, LLDB_INVALID_THREAD_ID); @@ -3333,13 +3506,14 @@ GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo( __FUNCTION__, packet.GetStringRef().data()); return SendErrorResponse(0x15); } - return SendStopReplyPacketForThread(tid); + return SendStopReplyPacketForThread(*m_current_process, tid, + /*force_synchronous=*/true); } GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo( StringExtractorGDBRemote &) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread); // Ensure we have a debugged process. if (!m_current_process || @@ -3455,7 +3629,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QPassSignals( GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_qMemTags( StringExtractorGDBRemote &packet) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); // Ensure we have a process. if (!m_current_process || @@ -3536,7 +3710,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qMemTags( GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_QMemTags( StringExtractorGDBRemote &packet) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); // Ensure we have a process. if (!m_current_process || @@ -3656,8 +3830,91 @@ GDBRemoteCommunicationServerLLGS::Handle_qSaveCore( return SendPacketNoLock(response.GetString()); } +GDBRemoteCommunication::PacketResult +GDBRemoteCommunicationServerLLGS::Handle_QNonStop( + StringExtractorGDBRemote &packet) { + StringRef packet_str{packet.GetStringRef()}; + assert(packet_str.startswith("QNonStop:")); + packet_str.consume_front("QNonStop:"); + if (packet_str == "0") { + m_non_stop = false; + // TODO: stop all threads + } else if (packet_str == "1") { + m_non_stop = true; + } else + return SendErrorResponse(Status("Invalid QNonStop packet")); + return SendOKResponse(); +} + +GDBRemoteCommunication::PacketResult +GDBRemoteCommunicationServerLLGS::Handle_vStopped( + StringExtractorGDBRemote &packet) { + // Per the protocol, the first message put into the queue is sent + // immediately. However, it remains the queue until the client ACKs + // it via vStopped -- then we pop it and send the next message. + // The process repeats until the last message in the queue is ACK-ed, + // in which case the vStopped packet sends an OK response. + + if (m_stop_notification_queue.empty()) + return SendErrorResponse(Status("No pending notification to ack")); + m_stop_notification_queue.pop_front(); + if (!m_stop_notification_queue.empty()) + return SendPacketNoLock(m_stop_notification_queue.front()); + // If this was the last notification and all the processes exited, + // terminate the server. + if (m_debugged_processes.empty()) { + m_exit_now = true; + m_mainloop.RequestTermination(); + } + return SendOKResponse(); +} + +GDBRemoteCommunication::PacketResult +GDBRemoteCommunicationServerLLGS::Handle_vCtrlC( + StringExtractorGDBRemote &packet) { + if (!m_non_stop) + return SendErrorResponse(Status("vCtrl is only valid in non-stop mode")); + + PacketResult interrupt_res = Handle_interrupt(packet); + // If interrupting the process failed, pass the result through. + if (interrupt_res != PacketResult::Success) + return interrupt_res; + // Otherwise, vCtrlC should issue an OK response (normal interrupts do not). + return SendOKResponse(); +} + +GDBRemoteCommunication::PacketResult +GDBRemoteCommunicationServerLLGS::Handle_T(StringExtractorGDBRemote &packet) { + packet.SetFilePos(strlen("T")); + auto pid_tid = packet.GetPidTid(m_current_process ? m_current_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; + + // Technically, this would also be caught by the PID check but let's be more + // explicit about the error. + 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(1); + + // Check the thread ID + if (!new_process_it->second->GetThreadByID(tid)) + return SendErrorResponse(2); + + return SendOKResponse(); +} + void GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection() { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); // Tell the stdio connection to shut down. if (m_stdio_communication.IsConnected()) { @@ -3701,7 +3958,7 @@ NativeThreadProtocol *GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix( return m_current_process->GetThreadByID(current_tid); } - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); // Parse out the ';'. if (packet.GetBytesLeft() < 1 || packet.GetChar() != ';') { @@ -3752,7 +4009,7 @@ uint32_t GDBRemoteCommunicationServerLLGS::GetNextSavedRegistersID() { } void GDBRemoteCommunicationServerLLGS::ClearProcessSpecificData() { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOG(log, "clearing {0} xfer buffers", m_xfer_buffer_map.size()); m_xfer_buffer_map.clear(); @@ -3799,38 +4056,6 @@ 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 = @@ -3839,6 +4064,7 @@ std::vector<std::string> GDBRemoteCommunicationServerLLGS::HandleFeatures( "QThreadSuffixSupported+", "QListThreadsInStopReply+", "qXfer:features:read+", + "QNonStop+", }); // report server-only features @@ -3893,6 +4119,21 @@ void GDBRemoteCommunicationServerLLGS::SetEnabledExtensions( process.SetEnabledExtensions(flags); } +GDBRemoteCommunication::PacketResult +GDBRemoteCommunicationServerLLGS::SendContinueSuccessResponse() { + // TODO: how to handle forwarding in non-stop mode? + StartSTDIOForwarding(); + return m_non_stop ? SendOKResponse() : PacketResult::Success; +} + +void GDBRemoteCommunicationServerLLGS::AppendThreadIDToResponse( + Stream &response, lldb::pid_t pid, lldb::tid_t tid) { + if (bool(m_extensions_supported & + NativeProcessProtocol::Extension::multiprocess)) + response.Format("p{0:x-}.", pid); + response.Format("{0:x-}", tid); +} + std::string lldb_private::process_gdb_remote::LLGSArgToURL(llvm::StringRef url_arg, bool reverse_connect) { 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 17ee4130dc34..5187a953f957 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 @@ -11,6 +11,7 @@ #include <mutex> #include <unordered_map> +#include <unordered_set> #include "lldb/Core/Communication.h" #include "lldb/Host/MainLoop.h" @@ -95,6 +96,7 @@ protected: std::recursive_mutex m_debugged_process_mutex; std::unordered_map<lldb::pid_t, std::unique_ptr<NativeProcessProtocol>> m_debugged_processes; + std::unordered_set<lldb::pid_t> m_vkilled_processes; Communication m_stdio_communication; MainLoop::ReadHandleUP m_stdio_handle_up; @@ -106,6 +108,8 @@ protected: uint32_t m_next_saved_registers_id = 1; bool m_thread_suffix_supported = false; bool m_list_threads_in_stop_reply = false; + bool m_non_stop = false; + std::deque<std::string> m_stop_notification_queue; NativeProcessProtocol::Extension m_extensions_supported = {}; @@ -113,12 +117,22 @@ protected: PacketResult SendWResponse(NativeProcessProtocol *process); - PacketResult SendStopReplyPacketForThread(lldb::tid_t tid); + StreamString PrepareStopReplyPacketForThread(NativeThreadProtocol &thread); - PacketResult SendStopReasonForState(lldb::StateType process_state); + PacketResult SendStopReplyPacketForThread(NativeProcessProtocol &process, + lldb::tid_t tid, + bool force_synchronous); + + PacketResult SendStopReasonForState(NativeProcessProtocol &process, + lldb::StateType process_state, + bool force_synchronous); + + void EnqueueStopReplyPackets(lldb::tid_t thread_to_skip); PacketResult Handle_k(StringExtractorGDBRemote &packet); + PacketResult Handle_vKill(StringExtractorGDBRemote &packet); + PacketResult Handle_qProcessInfo(StringExtractorGDBRemote &packet); PacketResult Handle_qC(StringExtractorGDBRemote &packet); @@ -145,6 +159,9 @@ protected: PacketResult Handle_qRegisterInfo(StringExtractorGDBRemote &packet); + void AddProcessThreads(StreamGDBRemote &response, + NativeProcessProtocol &process, bool &had_any); + PacketResult Handle_qfThreadInfo(StringExtractorGDBRemote &packet); PacketResult Handle_qsThreadInfo(StringExtractorGDBRemote &packet); @@ -217,12 +234,20 @@ protected: PacketResult Handle_qSaveCore(StringExtractorGDBRemote &packet); + PacketResult Handle_QNonStop(StringExtractorGDBRemote &packet); + + PacketResult Handle_vStopped(StringExtractorGDBRemote &packet); + + PacketResult Handle_vCtrlC(StringExtractorGDBRemote &packet); + PacketResult Handle_g(StringExtractorGDBRemote &packet); PacketResult Handle_qMemTags(StringExtractorGDBRemote &packet); PacketResult Handle_QMemTags(StringExtractorGDBRemote &packet); + PacketResult Handle_T(StringExtractorGDBRemote &packet); + void SetCurrentThreadID(lldb::tid_t tid); lldb::tid_t GetCurrentThreadID() const; @@ -241,9 +266,16 @@ protected: static std::string XMLEncodeAttributeValue(llvm::StringRef value); - virtual std::vector<std::string> HandleFeatures( + std::vector<std::string> HandleFeatures( const llvm::ArrayRef<llvm::StringRef> client_features) override; + // Provide a response for successful continue action, i.e. send "OK" + // in non-stop mode, no response otherwise. + PacketResult SendContinueSuccessResponse(); + + void AppendThreadIDToResponse(Stream &response, lldb::pid_t pid, + lldb::tid_t tid); + private: llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> BuildTargetXml(); @@ -269,15 +301,6 @@ 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); 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 a63b98edec55..6f137d09fee4 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 @@ -30,6 +30,7 @@ #include "lldb/Target/Platform.h" #include "lldb/Target/UnixSignals.h" #include "lldb/Utility/GDBRemote.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/StructuredData.h" @@ -178,7 +179,7 @@ Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer( if (hostname.empty()) hostname = "127.0.0.1"; - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); + Log *log = GetLog(LLDBLog::Platform); LLDB_LOGF(log, "Launching debugserver with: %s:%u...", hostname.c_str(), *port); @@ -187,8 +188,7 @@ Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer( debugserver_launch_info.SetLaunchInSeparateProcessGroup(false); debugserver_launch_info.SetMonitorProcessCallback( std::bind(&GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped, - this, std::placeholders::_1), - false); + this, std::placeholders::_1)); std::ostringstream url; // debugserver does not accept the URL scheme prefix. @@ -228,7 +228,7 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer( // Spawn a local debugserver as a platform so we can then attach or launch a // process... - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); + Log *log = GetLog(LLDBLog::Platform); LLDB_LOGF(log, "GDBRemoteCommunicationServerPlatform::%s() called", __FUNCTION__); @@ -244,7 +244,7 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer( else if (name.equals("port")) { // Make the Optional valid so we can use its value port = 0; - value.getAsInteger(0, port.getValue()); + value.getAsInteger(0, *port); } } @@ -516,12 +516,11 @@ GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo( return SendPacketNoLock(response.GetString()); } -bool GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped( +void GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped( lldb::pid_t pid) { std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex); m_port_map.FreePortForProcess(pid); m_spawned_pids.erase(pid); - return true; } Status GDBRemoteCommunicationServerPlatform::LaunchProcess() { @@ -532,11 +531,9 @@ Status GDBRemoteCommunicationServerPlatform::LaunchProcess() { // specify the process monitor if not already set. This should generally be // what happens since we need to reap started processes. if (!m_process_launch_info.GetMonitorProcessCallback()) - m_process_launch_info.SetMonitorProcessCallback( - std::bind( - &GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped, - this, std::placeholders::_1), - false); + m_process_launch_info.SetMonitorProcessCallback(std::bind( + &GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped, this, + std::placeholders::_1)); Status error = Host::LaunchProcess(m_process_launch_info); if (!error.Success()) { diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h index 6b964da4a279..8dbd5ba942f8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h @@ -131,7 +131,7 @@ protected: private: bool KillSpawnedProcess(lldb::pid_t pid); - bool DebugserverProcessReaped(lldb::pid_t pid); + void DebugserverProcessReaped(lldb::pid_t pid); static const FileSpec &GetDomainSocketDir(); 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 1b66e8c16281..7ad4f4968eac 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 @@ -517,7 +517,7 @@ bool GDBRemoteRegisterContext::WriteAllRegisterValues( } bool GDBRemoteRegisterContext::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { ExecutionContext exe_ctx(CalculateThread()); Process *process = exe_ctx.GetProcessPtr(); @@ -536,9 +536,13 @@ bool GDBRemoteRegisterContext::ReadAllRegisterValues( if (gdb_comm.SyncThreadState(m_thread.GetProtocolID())) InvalidateAllRegisters(); - if (use_g_packet && - (data_sp = gdb_comm.ReadAllRegisters(m_thread.GetProtocolID()))) - return true; + if (use_g_packet) { + if (DataBufferSP data_buffer = + gdb_comm.ReadAllRegisters(m_thread.GetProtocolID())) { + data_sp = std::make_shared<DataBufferHeap>(*data_buffer); + return true; + } + } // We're going to read each register // individually and store them as binary data in a buffer. 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 83c809c5aab6..d185cb5aede1 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 @@ -65,7 +65,7 @@ public: bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value) override; - bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; 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 1524c0613b0c..fe6a3f9ed6c1 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 @@ -59,6 +59,7 @@ #include "lldb/Target/ThreadPlanCallFunction.h" #include "lldb/Utility/Args.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Reproducer.h" #include "lldb/Utility/State.h" #include "lldb/Utility/StreamString.h" @@ -73,9 +74,6 @@ #include "GDBRemoteRegisterContext.h" #include "GDBRemoteRegisterFallback.h" -#ifdef LLDB_ENABLE_ALL -#include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h" -#endif // LLDB_ENABLE_ALL #include "Plugins/Process/Utility/GDBRemoteSignals.h" #include "Plugins/Process/Utility/InferiorCallPOSIX.h" #include "Plugins/Process/Utility/StopInfoMachException.h" @@ -210,6 +208,10 @@ std::chrono::seconds ProcessGDBRemote::GetPacketTimeout() { return std::chrono::seconds(GetGlobalPluginProperties().GetPacketTimeout()); } +ArchSpec ProcessGDBRemote::GetSystemArchitecture() { + return m_gdb_comm.GetHostArchitecture(); +} + bool ProcessGDBRemote::CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) { if (plugin_specified_by_name) @@ -254,7 +256,7 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp, m_continue_C_tids(), m_continue_s_tids(), m_continue_S_tids(), m_max_memory_size(0), m_remote_stub_max_memory_size(0), m_addr_to_mmap_size(), m_thread_create_bp_sp(), - m_waiting_for_attach(false), m_destroy_tried_resuming(false), + m_waiting_for_attach(false), m_command_sp(), m_breakpoint_pc_offset(0), m_initial_tid(LLDB_INVALID_THREAD_ID), m_allow_flash_writes(false), m_erased_flash_ranges(), m_vfork_in_progress(false) { @@ -408,13 +410,13 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) { } if (target_definition_fspec) { // See if we can get register definitions from a python file - if (ParsePythonTargetDefinition(target_definition_fspec)) { + if (ParsePythonTargetDefinition(target_definition_fspec)) return; - } else { - StreamSP stream_sp = GetTarget().GetDebugger().GetAsyncOutputStream(); - stream_sp->Printf("ERROR: target description file %s failed to parse.\n", - target_definition_fspec.GetPath().c_str()); - } + + Debugger::ReportError("target description file " + + target_definition_fspec.GetPath() + + " failed to parse", + GetTarget().GetDebugger().GetID()); } const ArchSpec &target_arch = GetTarget().GetArchitecture(); @@ -589,8 +591,10 @@ Status ProcessGDBRemote::DoConnectRemote(llvm::StringRef remote_url) { if (!module_sp) { // Force a an external lookup, if that tool is available. - if (!module_spec.GetSymbolFileSpec()) - Symbols::DownloadObjectAndSymbolFile(module_spec, true); + if (!module_spec.GetSymbolFileSpec()) { + Status error; + Symbols::DownloadObjectAndSymbolFile(module_spec, error, true); + } if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) { module_sp = std::make_shared<Module>(module_spec); @@ -608,7 +612,7 @@ Status ProcessGDBRemote::DoConnectRemote(llvm::StringRef remote_url) { ReadModuleFromMemory(FileSpec(namebuf), standalone_value); } - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); if (module_sp.get()) { target.GetImages().AppendIfNeeded(module_sp, false); @@ -950,12 +954,23 @@ Status ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) { m_gdb_comm.GetVAttachOrWaitSupported(); m_gdb_comm.EnableErrorStringInPacket(); - size_t num_cmds = GetExtraStartupCommands().GetArgumentCount(); - for (size_t idx = 0; idx < num_cmds; idx++) { - StringExtractorGDBRemote response; - m_gdb_comm.SendPacketAndWaitForResponse( - GetExtraStartupCommands().GetArgumentAtIndex(idx), response); + // First dispatch any commands from the platform: + auto handle_cmds = [&] (const Args &args) -> void { + for (const Args::ArgEntry &entry : args) { + StringExtractorGDBRemote response; + m_gdb_comm.SendPacketAndWaitForResponse( + entry.c_str(), response); + } + }; + + PlatformSP platform_sp = GetTarget().GetPlatform(); + if (platform_sp) { + handle_cmds(platform_sp->GetExtraStartupCommands()); } + + // Then dispatch any process commands: + handle_cmds(GetExtraStartupCommands()); + return error; } @@ -1669,7 +1684,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo( for (const auto &pair : expedited_register_map) { StringExtractor reg_value_extractor(pair.second); - DataBufferSP buffer_sp(new DataBufferHeap( + WritableDataBufferSP buffer_sp(new DataBufferHeap( reg_value_extractor.GetStringRef().size() / 2, 0)); reg_value_extractor.GetHexBytes(buffer_sp->GetData(), '\xcc'); uint32_t lldb_regnum = @@ -2048,7 +2063,8 @@ ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) { bytes.SetFilePos(0); const size_t byte_size = bytes.GetStringRef().size() / 2; - DataBufferSP data_buffer_sp(new DataBufferHeap(byte_size, 0)); + WritableDataBufferSP data_buffer_sp( + new DataBufferHeap(byte_size, 0)); const size_t bytes_copied = bytes.GetHexBytes(data_buffer_sp->GetData(), 0); if (bytes_copied == byte_size) @@ -2210,7 +2226,8 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) { if (!addr_str.getAsInteger(0, mem_cache_addr)) { StringExtractor bytes(bytes_str); const size_t byte_size = bytes.GetBytesLeft() / 2; - DataBufferSP data_buffer_sp(new DataBufferHeap(byte_size, 0)); + WritableDataBufferSP data_buffer_sp( + new DataBufferHeap(byte_size, 0)); const size_t bytes_copied = bytes.GetHexBytes(data_buffer_sp->GetData(), 0); if (bytes_copied == byte_size) @@ -2381,112 +2398,6 @@ Status ProcessGDBRemote::DoDestroy() { Log *log = GetLog(GDBRLog::Process); LLDB_LOGF(log, "ProcessGDBRemote::DoDestroy()"); -#ifdef LLDB_ENABLE_ALL // XXX Currently no iOS target support on FreeBSD - // There is a bug in older iOS debugservers where they don't shut down the - // process they are debugging properly. If the process is sitting at a - // breakpoint or an exception, this can cause problems with restarting. So - // we check to see if any of our threads are stopped at a breakpoint, and if - // so we remove all the breakpoints, resume the process, and THEN destroy it - // again. - // - // Note, we don't have a good way to test the version of debugserver, but I - // happen to know that the set of all the iOS debugservers which don't - // support GetThreadSuffixSupported() and that of the debugservers with this - // bug are equal. There really should be a better way to test this! - // - // We also use m_destroy_tried_resuming to make sure we only do this once, if - // we resume and then halt and get called here to destroy again and we're - // still at a breakpoint or exception, then we should just do the straight- - // forward kill. - // - // And of course, if we weren't able to stop the process by the time we get - // here, it isn't necessary (or helpful) to do any of this. - - if (!m_gdb_comm.GetThreadSuffixSupported() && - m_public_state.GetValue() != eStateRunning) { - PlatformSP platform_sp = GetTarget().GetPlatform(); - - if (platform_sp && platform_sp->GetName() && - platform_sp->GetName().GetStringRef() == - PlatformRemoteiOS::GetPluginNameStatic()) { - if (m_destroy_tried_resuming) { - if (log) - log->PutCString("ProcessGDBRemote::DoDestroy() - Tried resuming to " - "destroy once already, not doing it again."); - } else { - // At present, the plans are discarded and the breakpoints disabled - // Process::Destroy, but we really need it to happen here and it - // doesn't matter if we do it twice. - m_thread_list.DiscardThreadPlans(); - DisableAllBreakpointSites(); - - bool stop_looks_like_crash = false; - ThreadList &threads = GetThreadList(); - - { - std::lock_guard<std::recursive_mutex> guard(threads.GetMutex()); - - size_t num_threads = threads.GetSize(); - for (size_t i = 0; i < num_threads; i++) { - ThreadSP thread_sp = threads.GetThreadAtIndex(i); - StopInfoSP stop_info_sp = thread_sp->GetPrivateStopInfo(); - StopReason reason = eStopReasonInvalid; - if (stop_info_sp) - reason = stop_info_sp->GetStopReason(); - if (reason == eStopReasonBreakpoint || - reason == eStopReasonException) { - LLDB_LOGF(log, - "ProcessGDBRemote::DoDestroy() - thread: 0x%4.4" PRIx64 - " stopped with reason: %s.", - thread_sp->GetProtocolID(), - stop_info_sp->GetDescription()); - stop_looks_like_crash = true; - break; - } - } - } - - if (stop_looks_like_crash) { - if (log) - log->PutCString("ProcessGDBRemote::DoDestroy() - Stopped at a " - "breakpoint, continue and then kill."); - m_destroy_tried_resuming = true; - - // If we are going to run again before killing, it would be good to - // suspend all the threads before resuming so they won't get into - // more trouble. Sadly, for the threads stopped with the breakpoint - // or exception, the exception doesn't get cleared if it is - // suspended, so we do have to run the risk of letting those threads - // proceed a bit. - - { - std::lock_guard<std::recursive_mutex> guard(threads.GetMutex()); - - size_t num_threads = threads.GetSize(); - for (size_t i = 0; i < num_threads; i++) { - ThreadSP thread_sp = threads.GetThreadAtIndex(i); - StopInfoSP stop_info_sp = thread_sp->GetPrivateStopInfo(); - StopReason reason = eStopReasonInvalid; - if (stop_info_sp) - reason = stop_info_sp->GetStopReason(); - if (reason != eStopReasonBreakpoint && - reason != eStopReasonException) { - LLDB_LOGF(log, - "ProcessGDBRemote::DoDestroy() - Suspending " - "thread: 0x%4.4" PRIx64 " before running.", - thread_sp->GetProtocolID()); - thread_sp->SetResumeState(eStateSuspended); - } - } - } - Resume(); - return Destroy(false); - } - } - } - } -#endif // LLDB_ENABLE_ALL - // Interrupt if our inferior is running... int exit_status = SIGABRT; std::string exit_string; @@ -2923,8 +2834,7 @@ size_t ProcessGDBRemote::DoWriteMemory(addr_t addr, const void *buf, lldb::addr_t ProcessGDBRemote::DoAllocateMemory(size_t size, uint32_t permissions, Status &error) { - Log *log( - GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Process | LLDBLog::Expressions); addr_t allocated_addr = LLDB_INVALID_ADDRESS; if (m_gdb_comm.SupportsAllocDeallocMemory() != eLazyBoolNo) { @@ -3370,7 +3280,7 @@ Status ProcessGDBRemote::LaunchAndConnectToDebugserver( const std::weak_ptr<ProcessGDBRemote> this_wp = std::static_pointer_cast<ProcessGDBRemote>(shared_from_this()); debugserver_launch_info.SetMonitorProcessCallback( - std::bind(MonitorDebugserverProcess, this_wp, _1, _2, _3, _4), false); + std::bind(MonitorDebugserverProcess, this_wp, _1, _2, _3)); debugserver_launch_info.SetUserID(process_info.GetUserID()); #if defined(__APPLE__) @@ -3449,16 +3359,14 @@ Status ProcessGDBRemote::LaunchAndConnectToDebugserver( return error; } -bool ProcessGDBRemote::MonitorDebugserverProcess( +void ProcessGDBRemote::MonitorDebugserverProcess( std::weak_ptr<ProcessGDBRemote> process_wp, lldb::pid_t debugserver_pid, - bool exited, // True if the process did exit int signo, // Zero for no signal int exit_status // Exit value of process if signal is zero ) { // "debugserver_pid" argument passed in is the process ID for debugserver // that we are tracking... Log *log = GetLog(GDBRLog::Process); - const bool handled = true; LLDB_LOGF(log, "ProcessGDBRemote::%s(process_wp, pid=%" PRIu64 @@ -3469,7 +3377,7 @@ bool ProcessGDBRemote::MonitorDebugserverProcess( LLDB_LOGF(log, "ProcessGDBRemote::%s(process = %p)", __FUNCTION__, static_cast<void *>(process_sp.get())); if (!process_sp || process_sp->m_debugserver_pid != debugserver_pid) - return handled; + return; // Sleep for a half a second to make sure our inferior process has time to // set its exit status before we set it incorrectly when both the debugserver @@ -3503,7 +3411,6 @@ bool ProcessGDBRemote::MonitorDebugserverProcess( // Debugserver has exited we need to let our ProcessGDBRemote know that it no // longer has a debugserver instance process_sp->m_debugserver_pid = LLDB_INVALID_PROCESS_ID; - return handled; } void ProcessGDBRemote::KillDebugserverProcess() { @@ -3545,11 +3452,12 @@ bool ProcessGDBRemote::StartAsyncThread() { // Create a thread that watches our internal state and controls which // events make it to clients (into the DCProcess event queue). - llvm::Expected<HostThread> async_thread = ThreadLauncher::LaunchThread( - "<lldb.process.gdb-remote.async>", ProcessGDBRemote::AsyncThread, this); + llvm::Expected<HostThread> async_thread = + ThreadLauncher::LaunchThread("<lldb.process.gdb-remote.async>", [this] { + return ProcessGDBRemote::AsyncThread(); + }); if (!async_thread) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST), - async_thread.takeError(), + LLDB_LOG_ERROR(GetLog(LLDBLog::Host), async_thread.takeError(), "failed to launch host thread: {}"); return false; } @@ -3585,14 +3493,10 @@ void ProcessGDBRemote::StopAsyncThread() { __FUNCTION__); } -thread_result_t ProcessGDBRemote::AsyncThread(void *arg) { - ProcessGDBRemote *process = (ProcessGDBRemote *)arg; - +thread_result_t ProcessGDBRemote::AsyncThread() { Log *log = GetLog(GDBRLog::Process); - LLDB_LOGF(log, - "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 - ") thread starting...", - __FUNCTION__, arg, process->GetID()); + LLDB_LOGF(log, "ProcessGDBRemote::%s(pid = %" PRIu64 ") thread starting...", + __FUNCTION__, GetID()); EventSP event_sp; @@ -3608,19 +3512,19 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) { // fetch loop. bool done = false; - while (!done && process->GetPrivateState() != eStateExited) { + while (!done && GetPrivateState() != eStateExited) { LLDB_LOGF(log, - "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 + "ProcessGDBRemote::%s(pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp)...", - __FUNCTION__, arg, process->GetID()); + __FUNCTION__, GetID()); - if (process->m_async_listener_sp->GetEvent(event_sp, llvm::None)) { + if (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)) { + if (event_sp->BroadcasterIs(&m_async_broadcaster)) { LLDB_LOGF(log, - "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 + "ProcessGDBRemote::%s(pid = %" PRIu64 ") Got an event of type: %d...", - __FUNCTION__, arg, process->GetID(), event_type); + __FUNCTION__, GetID(), event_type); switch (event_type) { case eBroadcastBitAsyncContinue: { @@ -3632,39 +3536,39 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) { (const char *)continue_packet->GetBytes(); const size_t continue_cstr_len = continue_packet->GetByteSize(); LLDB_LOGF(log, - "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 + "ProcessGDBRemote::%s(pid = %" PRIu64 ") got eBroadcastBitAsyncContinue: %s", - __FUNCTION__, arg, process->GetID(), continue_cstr); + __FUNCTION__, GetID(), continue_cstr); if (::strstr(continue_cstr, "vAttach") == nullptr) - process->SetPrivateState(eStateRunning); + SetPrivateState(eStateRunning); StringExtractorGDBRemote response; StateType stop_state = - process->GetGDBRemote().SendContinuePacketAndWaitForResponse( - *process, *process->GetUnixSignals(), + GetGDBRemote().SendContinuePacketAndWaitForResponse( + *this, *GetUnixSignals(), llvm::StringRef(continue_cstr, continue_cstr_len), - process->GetInterruptTimeout(), response); + GetInterruptTimeout(), response); // We need to immediately clear the thread ID list so we are sure // to get a valid list of threads. The thread ID list might be // contained within the "response", or the stop reply packet that // caused the stop. So clear it now before we give the stop reply // packet to the process using the - // process->SetLastStopPacket()... - process->ClearThreadIDList(); + // SetLastStopPacket()... + ClearThreadIDList(); switch (stop_state) { case eStateStopped: case eStateCrashed: case eStateSuspended: - process->SetLastStopPacket(response); - process->SetPrivateState(stop_state); + SetLastStopPacket(response); + SetPrivateState(stop_state); break; case eStateExited: { - process->SetLastStopPacket(response); - process->ClearThreadIDList(); + SetLastStopPacket(response); + ClearThreadIDList(); response.SetFilePos(1); int exit_status = response.GetHexU8(); @@ -3679,7 +3583,7 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) { extractor.GetHexByteString(desc_string); } } - process->SetExitStatus(exit_status, desc_string.c_str()); + SetExitStatus(exit_status, desc_string.c_str()); done = true; break; } @@ -3690,20 +3594,20 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) { // helpful error message about why the attach failed. if (::strstr(continue_cstr, "vAttach") != nullptr && response.GetError() == 0x87) { - process->SetExitStatus(-1, "cannot attach to process due to " - "System Integrity Protection"); + SetExitStatus(-1, "cannot attach to process due to " + "System Integrity Protection"); } else if (::strstr(continue_cstr, "vAttach") != nullptr && response.GetStatus().Fail()) { - process->SetExitStatus(-1, response.GetStatus().AsCString()); + SetExitStatus(-1, response.GetStatus().AsCString()); } else { - process->SetExitStatus(-1, "lost connection"); + SetExitStatus(-1, "lost connection"); } done = true; break; } default: - process->SetPrivateState(stop_state); + SetPrivateState(stop_state); break; } // switch(stop_state) } // if (continue_packet) @@ -3712,49 +3616,47 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) { case eBroadcastBitAsyncThreadShouldExit: LLDB_LOGF(log, - "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 + "ProcessGDBRemote::%s(pid = %" PRIu64 ") got eBroadcastBitAsyncThreadShouldExit...", - __FUNCTION__, arg, process->GetID()); + __FUNCTION__, GetID()); done = true; break; default: LLDB_LOGF(log, - "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 + "ProcessGDBRemote::%s(pid = %" PRIu64 ") got unknown event 0x%8.8x", - __FUNCTION__, arg, process->GetID(), event_type); + __FUNCTION__, GetID(), event_type); done = true; break; } - } else if (event_sp->BroadcasterIs(&process->m_gdb_comm)) { + } else if (event_sp->BroadcasterIs(&m_gdb_comm)) { switch (event_type) { case Communication::eBroadcastBitReadThreadDidExit: - process->SetExitStatus(-1, "lost connection"); + SetExitStatus(-1, "lost connection"); done = true; break; default: LLDB_LOGF(log, - "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 + "ProcessGDBRemote::%s(pid = %" PRIu64 ") got unknown event 0x%8.8x", - __FUNCTION__, arg, process->GetID(), event_type); + __FUNCTION__, GetID(), event_type); done = true; break; } } } else { LLDB_LOGF(log, - "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 + "ProcessGDBRemote::%s(pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp) => false", - __FUNCTION__, arg, process->GetID()); + __FUNCTION__, GetID()); done = true; } } - LLDB_LOGF(log, - "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 - ") thread exiting...", - __FUNCTION__, arg, process->GetID()); + LLDB_LOGF(log, "ProcessGDBRemote::%s(pid = %" PRIu64 ") thread exiting...", + __FUNCTION__, GetID()); return {}; } @@ -3785,7 +3687,7 @@ bool ProcessGDBRemote::NewThreadNotifyBreakpointHit( // I don't think I have to do anything here, just make sure I notice the new // thread when it starts to // run so I can stop it if that's what I want to do. - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); LLDB_LOGF(log, "Hit New Thread Notification breakpoint."); return false; } @@ -3828,7 +3730,7 @@ Status ProcessGDBRemote::UpdateAutomaticSignalFiltering() { } bool ProcessGDBRemote::StartNoticingNewThreads() { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (m_thread_create_bp_sp) { if (log && log->GetVerbose()) LLDB_LOGF(log, "Enabled noticing new thread breakpoint."); @@ -3854,7 +3756,7 @@ bool ProcessGDBRemote::StartNoticingNewThreads() { } bool ProcessGDBRemote::StopNoticingNewThreads() { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (log && log->GetVerbose()) LLDB_LOGF(log, "Disabling new thread notification breakpoint."); @@ -4120,7 +4022,7 @@ void ProcessGDBRemote::SetUserSpecifiedMaxMemoryTransferSize( bool ProcessGDBRemote::GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch, ModuleSpec &module_spec) { - Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); + Log *log = GetLog(LLDBLog::Platform); const ModuleCacheKey key(module_file_spec.GetPath(), arch.GetTriple().getTriple()); @@ -4499,7 +4401,7 @@ llvm::Expected<LoadedModuleInfoList> ProcessGDBRemote::GetLoadedModuleList() { return llvm::createStringError(llvm::inconvertibleErrorCode(), "XML parsing not available"); - Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "ProcessGDBRemote::%s", __FUNCTION__); LoadedModuleInfoList list; @@ -5106,19 +5008,12 @@ public: ~CommandObjectProcessGDBRemotePacketHistory() override = default; bool DoExecute(Args &command, CommandReturnObject &result) override { - const size_t argc = command.GetArgumentCount(); - if (argc == 0) { - ProcessGDBRemote *process = - (ProcessGDBRemote *)m_interpreter.GetExecutionContext() - .GetProcessPtr(); - if (process) { - process->GetGDBRemote().DumpHistory(result.GetOutputStream()); - result.SetStatus(eReturnStatusSuccessFinishResult); - return true; - } - } else { - result.AppendErrorWithFormat("'%s' takes no arguments", - m_cmd_name.c_str()); + ProcessGDBRemote *process = + (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr(); + if (process) { + process->GetGDBRemote().DumpHistory(result.GetOutputStream()); + result.SetStatus(eReturnStatusSuccessFinishResult); + return true; } result.SetStatus(eReturnStatusFailed); return false; @@ -5132,7 +5027,10 @@ public: : CommandObjectParsed( interpreter, "process plugin packet xfer-size", "Maximum size that lldb will try to read/write one one chunk.", - nullptr) {} + nullptr) { + CommandArgumentData max_arg{eArgTypeUnsignedInteger, eArgRepeatPlain}; + m_arguments.push_back({max_arg}); + } ~CommandObjectProcessGDBRemotePacketXferSize() override = default; @@ -5173,7 +5071,10 @@ public: "The packet header and footer will automatically " "be added to the packet prior to sending and " "stripped from the result.", - nullptr) {} + nullptr) { + CommandArgumentData packet_arg{eArgTypeNone, eArgRepeatStar}; + m_arguments.push_back({packet_arg}); + } ~CommandObjectProcessGDBRemotePacketSend() override = default; 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 dd907042608d..50cef8e499dc 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 @@ -70,6 +70,8 @@ public: static std::chrono::seconds GetPacketTimeout(); + ArchSpec GetSystemArchitecture() override; + // Check if a given Process bool CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) override; @@ -281,7 +283,6 @@ protected: MMapMap m_addr_to_mmap_size; lldb::BreakpointSP m_thread_create_bp_sp; bool m_waiting_for_attach; - bool m_destroy_tried_resuming; lldb::CommandObjectSP m_command_sp; int64_t m_breakpoint_pc_offset; lldb::tid_t m_initial_tid; // The initial thread ID, given by stub on attach @@ -342,12 +343,11 @@ protected: void StopAsyncThread(); - static lldb::thread_result_t AsyncThread(void *arg); + lldb::thread_result_t AsyncThread(); - static bool + static void MonitorDebugserverProcess(std::weak_ptr<ProcessGDBRemote> process_wp, - lldb::pid_t pid, bool exited, int signo, - int exit_status); + lldb::pid_t pid, int signo, int exit_status); lldb::StateType SetThreadStopInfo(StringExtractor &stop_packet); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h index 730384204393..66b2f00f1ea9 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h @@ -10,6 +10,7 @@ #define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_PROCESSGDBREMOTELOG_H #include "lldb/Utility/Log.h" +#include "llvm/ADT/BitmaskEnum.h" namespace lldb_private { namespace process_gdb_remote { @@ -28,6 +29,7 @@ enum class GDBRLog : Log::MaskType { Watchpoints = Log::ChannelFlag<10>, LLVM_MARK_AS_BITMASK_ENUM(Watchpoints) }; +LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); class ProcessGDBRemoteLog { public: diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp index 61106ebcc430..ecf363aa2e73 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp @@ -12,6 +12,7 @@ #include "Plugins/Process/Utility/LinuxProcMaps.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" // C includes @@ -44,8 +45,7 @@ llvm::ArrayRef<uint8_t> MinidumpParser::GetData() { } llvm::ArrayRef<uint8_t> MinidumpParser::GetStream(StreamType stream_type) { - return m_file->getRawStream(stream_type) - .getValueOr(llvm::ArrayRef<uint8_t>()); + return m_file->getRawStream(stream_type).value_or(llvm::ArrayRef<uint8_t>()); } UUID MinidumpParser::GetModuleUUID(const minidump::Module *module) { @@ -84,8 +84,7 @@ llvm::ArrayRef<minidump::Thread> MinidumpParser::GetThreads() { if (ExpectedThreads) return *ExpectedThreads; - LLDB_LOG_ERROR(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD), - ExpectedThreads.takeError(), + LLDB_LOG_ERROR(GetLog(LLDBLog::Thread), ExpectedThreads.takeError(), "Failed to read thread list: {0}"); return {}; } @@ -141,8 +140,7 @@ ArchSpec MinidumpParser::GetArchitecture() { llvm::Expected<const SystemInfo &> system_info = m_file->getSystemInfo(); if (!system_info) { - LLDB_LOG_ERROR(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS), - system_info.takeError(), + LLDB_LOG_ERROR(GetLog(LLDBLog::Process), system_info.takeError(), "Failed to read SystemInfo stream: {0}"); return m_arch; } @@ -200,8 +198,7 @@ ArchSpec MinidumpParser::GetArchitecture() { triple.setOS(llvm::Triple::OSType::UnknownOS); auto ExpectedCSD = m_file->getString(system_info->CSDVersionRVA); if (!ExpectedCSD) { - LLDB_LOG_ERROR(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS), - ExpectedCSD.takeError(), + LLDB_LOG_ERROR(GetLog(LLDBLog::Process), ExpectedCSD.takeError(), "Failed to CSD Version string: {0}"); } else { if (ExpectedCSD->find("Linux") != std::string::npos) @@ -239,7 +236,7 @@ llvm::Optional<lldb::pid_t> MinidumpParser::GetPid() { } llvm::Optional<LinuxProcStatus> proc_status = GetLinuxProcStatus(); - if (proc_status.hasValue()) { + if (proc_status) { return proc_status->GetPid(); } @@ -251,8 +248,7 @@ llvm::ArrayRef<minidump::Module> MinidumpParser::GetModuleList() { if (ExpectedModules) return *ExpectedModules; - LLDB_LOG_ERROR(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES), - ExpectedModules.takeError(), + LLDB_LOG_ERROR(GetLog(LLDBLog::Modules), ExpectedModules.takeError(), "Failed to read module list: {0}"); return {}; } @@ -264,7 +260,7 @@ CreateRegionsCacheFromLinuxMaps(MinidumpParser &parser, if (data.empty()) return false; - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + Log *log = GetLog(LLDBLog::Expressions); ParseLinuxMapRegions( llvm::toStringRef(data), [®ions, &log](llvm::Expected<MemoryRegionInfo> region) -> bool { @@ -345,7 +341,7 @@ static bool CheckForLinuxExecutable(ConstString path, } std::vector<const minidump::Module *> MinidumpParser::GetFilteredModuleList() { - Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES); + Log *log = GetLog(LLDBLog::Modules); auto ExpectedModules = GetMinidumpFile().getModuleList(); if (!ExpectedModules) { LLDB_LOG_ERROR(log, ExpectedModules.takeError(), @@ -425,8 +421,7 @@ const minidump::ExceptionStream *MinidumpParser::GetExceptionStream() { if (ExpectedStream) return &*ExpectedStream; - LLDB_LOG_ERROR(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS), - ExpectedStream.takeError(), + LLDB_LOG_ERROR(GetLog(LLDBLog::Process), ExpectedStream.takeError(), "Failed to read minidump exception stream: {0}"); return nullptr; } @@ -434,7 +429,7 @@ const minidump::ExceptionStream *MinidumpParser::GetExceptionStream() { llvm::Optional<minidump::Range> MinidumpParser::FindMemoryRange(lldb::addr_t addr) { llvm::ArrayRef<uint8_t> data64 = GetStream(StreamType::Memory64List); - Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES); + Log *log = GetLog(LLDBLog::Modules); auto ExpectedMemory = GetMinidumpFile().getMemoryList(); if (!ExpectedMemory) { @@ -519,7 +514,7 @@ llvm::ArrayRef<uint8_t> MinidumpParser::GetMemory(lldb::addr_t addr, static bool CreateRegionsCacheFromMemoryInfoList(MinidumpParser &parser, std::vector<MemoryRegionInfo> ®ions) { - Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES); + Log *log = GetLog(LLDBLog::Modules); auto ExpectedInfo = parser.GetMinidumpFile().getMemoryInfoList(); if (!ExpectedInfo) { LLDB_LOG_ERROR(log, ExpectedInfo.takeError(), @@ -556,7 +551,7 @@ CreateRegionsCacheFromMemoryInfoList(MinidumpParser &parser, static bool CreateRegionsCacheFromMemoryList(MinidumpParser &parser, std::vector<MemoryRegionInfo> ®ions) { - Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES); + Log *log = GetLog(LLDBLog::Modules); auto ExpectedMemory = parser.GetMinidumpFile().getMemoryList(); if (!ExpectedMemory) { LLDB_LOG_ERROR(log, ExpectedMemory.takeError(), 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 162697bed7e9..c91c111d8df3 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp @@ -27,6 +27,7 @@ #include "lldb/Target/Target.h" #include "lldb/Target/UnixSignals.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/State.h" #include "llvm/BinaryFormat/Magic.h" @@ -291,12 +292,12 @@ Status ProcessMinidump::DoLoadCore() { llvm::Optional<lldb::pid_t> pid = m_minidump_parser->GetPid(); if (!pid) { - GetTarget().GetDebugger().GetAsyncErrorStream()->PutCString( - "Unable to retrieve process ID from minidump file, setting process ID " - "to 1.\n"); + Debugger::ReportWarning("unable to retrieve process ID from minidump file, " + "setting process ID to 1", + GetTarget().GetDebugger().GetID()); pid = 1; } - SetID(pid.getValue()); + SetID(*pid); return error; } @@ -480,7 +481,7 @@ bool ProcessMinidump::DoUpdateThreadList(ThreadList &old_thread_list, ModuleSP ProcessMinidump::GetOrCreateModule(UUID minidump_uuid, llvm::StringRef name, ModuleSpec module_spec) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); Status error; ModuleSP module_sp = @@ -528,7 +529,7 @@ void ProcessMinidump::ReadModuleList() { std::vector<const minidump::Module *> filtered_modules = m_minidump_parser->GetFilteredModuleList(); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); for (auto module : filtered_modules) { std::string name = cantFail(m_minidump_parser->GetMinidumpFile().getString( diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp index 38d7de77e3bf..7681002c6fb8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp @@ -27,7 +27,7 @@ lldb::DataBufferSP lldb_private::minidump::ConvertMinidumpContext_x86_32( const RegisterInfo *reg_info = target_reg_interface->GetRegisterInfo(); - lldb::DataBufferSP result_context_buf( + lldb::WritableDataBufferSP result_context_buf( new DataBufferHeap(target_reg_interface->GetGPRSize(), 0)); uint8_t *result_base = result_context_buf->GetBytes(); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp index 3c593f0db6ec..917140cab297 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp @@ -50,7 +50,7 @@ lldb::DataBufferSP lldb_private::minidump::ConvertMinidumpContext_x86_64( const RegisterInfo *reg_info = target_reg_interface->GetRegisterInfo(); - lldb::DataBufferSP result_context_buf( + lldb::WritableDataBufferSP result_context_buf( new DataBufferHeap(target_reg_interface->GetGPRSize(), 0)); uint8_t *result_base = result_context_buf->GetBytes(); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp index c231ea6b0d10..cd2d4fe4fd23 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp @@ -20,6 +20,7 @@ #include "lldb/Interpreter/ScriptInterpreter.h" #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/RegisterContext.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/State.h" #include <mutex> @@ -66,8 +67,7 @@ lldb::ProcessSP ScriptedProcess::CreateInstance(lldb::TargetSP target_sp, 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()); + LLDB_LOGF(GetLog(LLDBLog::Process), "%s", error.AsCString()); return nullptr; } @@ -170,12 +170,13 @@ Status ScriptedProcess::DoLaunch(Module *exe_module, void ScriptedProcess::DidLaunch() { CheckInterpreterAndScriptObject(); m_pid = GetInterface().GetProcessID(); + GetLoadedDynamicLibrariesInfos(); } Status ScriptedProcess::DoResume() { CheckInterpreterAndScriptObject(); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); // FIXME: Fetch data from thread. const StateType thread_resume_state = eStateRunning; LLDB_LOGF(log, "ScriptedProcess::%s thread_resume_state = %s", __FUNCTION__, @@ -199,7 +200,7 @@ Status ScriptedProcess::DoResume() { Status ScriptedProcess::DoStop() { CheckInterpreterAndScriptObject(); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); if (GetInterface().ShouldStop()) { SetPrivateState(eStateStopped); @@ -308,27 +309,50 @@ bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list, LLVM_PRETTY_FUNCTION, "Couldn't fetch thread list from Scripted Process.", error); + // Because `StructuredData::Dictionary` uses a `std::map<ConstString, + // ObjectSP>` for storage, each item is sorted based on the key alphabetical + // order. Since `GetThreadsInfo` provides thread indices as the key element, + // thread info comes ordered alphabetically, instead of numerically, so we + // need to sort the thread indices before creating thread. + + StructuredData::ArraySP keys = thread_info_sp->GetKeys(); + + std::map<size_t, StructuredData::ObjectSP> sorted_threads; + auto sort_keys = [&sorted_threads, + &thread_info_sp](StructuredData::Object *item) -> bool { + if (!item) + return false; + + llvm::StringRef key = item->GetStringValue(); + size_t idx = 0; + + // Make sure the provided index is actually an integer + if (!llvm::to_integer(key, idx)) + return false; + + sorted_threads[idx] = thread_info_sp->GetValueForKey(key); + return true; + }; + + size_t thread_count = thread_info_sp->GetSize(); + + if (!keys->ForEach(sort_keys) || sorted_threads.size() != thread_count) + // Might be worth showing the unsorted thread list instead of return early. + return ScriptedInterface::ErrorWithMessage<bool>( + LLVM_PRETTY_FUNCTION, "Couldn't sort thread list.", error); + auto create_scripted_thread = - [this, &old_thread_list, &error, - &new_thread_list](ConstString key, StructuredData::Object *val) -> bool { - if (!val) - return ScriptedInterface::ErrorWithMessage<bool>( - LLVM_PRETTY_FUNCTION, "Invalid thread info object", error); + [this, &error, &new_thread_list]( + const std::pair<size_t, StructuredData::ObjectSP> pair) -> bool { + size_t idx = pair.first; + StructuredData::ObjectSP object_sp = pair.second; - lldb::tid_t tid = LLDB_INVALID_THREAD_ID; - if (!llvm::to_integer(key.AsCString(), tid)) + if (!object_sp) return ScriptedInterface::ErrorWithMessage<bool>( - LLVM_PRETTY_FUNCTION, "Invalid thread id", error); - - if (ThreadSP thread_sp = - old_thread_list.FindThreadByID(tid, false /*=can_update*/)) { - // If the thread was already in the old_thread_list, - // just add it back to the new_thread_list. - new_thread_list.AddThread(thread_sp); - return true; - } + LLVM_PRETTY_FUNCTION, "Invalid thread info object", error); - auto thread_or_error = ScriptedThread::Create(*this, val->GetAsGeneric()); + auto thread_or_error = + ScriptedThread::Create(*this, object_sp->GetAsGeneric()); if (!thread_or_error) return ScriptedInterface::ErrorWithMessage<bool>( @@ -341,8 +365,7 @@ bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list, if (!reg_ctx_sp) return ScriptedInterface::ErrorWithMessage<bool>( LLVM_PRETTY_FUNCTION, - llvm::Twine("Invalid Register Context for thread " + - llvm::Twine(key.AsCString())) + llvm::Twine("Invalid Register Context for thread " + llvm::Twine(idx)) .str(), error); @@ -351,7 +374,7 @@ bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list, return true; }; - thread_info_sp->ForEach(create_scripted_thread); + llvm::for_each(sorted_threads, create_scripted_thread); return new_thread_list.GetSize(false) > 0; } @@ -359,6 +382,7 @@ bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list, void ScriptedProcess::RefreshStateAfterStop() { // Let all threads recover from stopping and do any clean up based on the // previous thread state (if any). + m_thread_list.RefreshStateAfterStop(); } bool ScriptedProcess::GetProcessInfo(ProcessInstanceInfo &info) { @@ -374,6 +398,93 @@ bool ScriptedProcess::GetProcessInfo(ProcessInstanceInfo &info) { return true; } +lldb_private::StructuredData::ObjectSP +ScriptedProcess::GetLoadedDynamicLibrariesInfos() { + CheckInterpreterAndScriptObject(); + + Status error; + auto error_with_message = [&error](llvm::StringRef message) { + return ScriptedInterface::ErrorWithMessage<bool>(LLVM_PRETTY_FUNCTION, + message.data(), error); + }; + + StructuredData::ArraySP loaded_images_sp = GetInterface().GetLoadedImages(); + + if (!loaded_images_sp || !loaded_images_sp->GetSize()) + return GetInterface().ErrorWithMessage<StructuredData::ObjectSP>( + LLVM_PRETTY_FUNCTION, "No loaded images.", error); + + ModuleList module_list; + Target &target = GetTarget(); + + auto reload_image = [&target, &module_list, &error_with_message]( + StructuredData::Object *obj) -> bool { + StructuredData::Dictionary *dict = obj->GetAsDictionary(); + + if (!dict) + return error_with_message("Couldn't cast image object into dictionary."); + + ModuleSpec module_spec; + llvm::StringRef value; + + bool has_path = dict->HasKey("path"); + bool has_uuid = dict->HasKey("uuid"); + if (!has_path && !has_uuid) + return error_with_message("Dictionary should have key 'path' or 'uuid'"); + if (!dict->HasKey("load_addr")) + return error_with_message("Dictionary is missing key 'load_addr'"); + + if (has_path) { + dict->GetValueForKeyAsString("path", value); + module_spec.GetFileSpec().SetPath(value); + } + + if (has_uuid) { + dict->GetValueForKeyAsString("uuid", value); + module_spec.GetUUID().SetFromStringRef(value); + } + module_spec.GetArchitecture() = target.GetArchitecture(); + + ModuleSP module_sp = + target.GetOrCreateModule(module_spec, true /* notify */); + + if (!module_sp) + return error_with_message("Couldn't create or get module."); + + lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; + lldb::addr_t slide = LLDB_INVALID_OFFSET; + dict->GetValueForKeyAsInteger("load_addr", load_addr); + dict->GetValueForKeyAsInteger("slide", slide); + if (load_addr == LLDB_INVALID_ADDRESS) + return error_with_message( + "Couldn't get valid load address or slide offset."); + + if (slide != LLDB_INVALID_OFFSET) + load_addr += slide; + + bool changed = false; + module_sp->SetLoadAddress(target, load_addr, false /*=value_is_offset*/, + changed); + + if (!changed && !module_sp->GetObjectFile()) + return error_with_message("Couldn't set the load address for module."); + + dict->GetValueForKeyAsString("path", value); + FileSpec objfile(value); + module_sp->SetFileSpecAndObjectName(objfile, objfile.GetFilename()); + + return module_list.AppendIfNeeded(module_sp); + }; + + if (!loaded_images_sp->ForEach(reload_image)) + return GetInterface().ErrorWithMessage<StructuredData::ObjectSP>( + LLVM_PRETTY_FUNCTION, "Couldn't reload all images.", error); + + target.ModulesDidLoad(module_list); + + return loaded_images_sp; +} + 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 index c8355f35548a..7edd95e230a1 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.h @@ -89,6 +89,9 @@ public: bool GetProcessInfo(ProcessInstanceInfo &info) override; + lldb_private::StructuredData::ObjectSP + GetLoadedDynamicLibrariesInfos() override; + protected: Status DoStop(); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp index b6cbb62fd6e6..e28f66015dd5 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp @@ -15,9 +15,7 @@ #include "lldb/Target/StopInfo.h" #include "lldb/Target/Unwind.h" #include "lldb/Utility/DataBufferHeap.h" -#include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" - +#include "lldb/Utility/LLDBLog.h" #include <memory> using namespace lldb; @@ -123,25 +121,25 @@ ScriptedThread::CreateRegisterContextForFrame(StackFrame *frame) { llvm::Optional<std::string> reg_data = GetInterface()->GetRegisterContext(); if (!reg_data) - return GetInterface()->ErrorWithMessage<lldb::RegisterContextSP>( + return ScriptedInterface::ErrorWithMessage<lldb::RegisterContextSP>( LLVM_PRETTY_FUNCTION, "Failed to get scripted thread registers data.", - error, LIBLLDB_LOG_THREAD); + error, LLDBLog::Thread); DataBufferSP data_sp( std::make_shared<DataBufferHeap>(reg_data->c_str(), reg_data->size())); if (!data_sp->GetByteSize()) - return GetInterface()->ErrorWithMessage<lldb::RegisterContextSP>( + return ScriptedInterface::ErrorWithMessage<lldb::RegisterContextSP>( LLVM_PRETTY_FUNCTION, "Failed to copy raw registers data.", error, - LIBLLDB_LOG_THREAD); + LLDBLog::Thread); std::shared_ptr<RegisterContextMemory> reg_ctx_memory = std::make_shared<RegisterContextMemory>( *this, 0, *GetDynamicRegisterInfo(), LLDB_INVALID_ADDRESS); if (!reg_ctx_memory) - return GetInterface()->ErrorWithMessage<lldb::RegisterContextSP>( + return ScriptedInterface::ErrorWithMessage<lldb::RegisterContextSP>( LLVM_PRETTY_FUNCTION, "Failed to create a register context.", error, - LIBLLDB_LOG_THREAD); + LLDBLog::Thread); reg_ctx_memory->SetAllRegisterData(data_sp); m_reg_context_sp = reg_ctx_memory; @@ -149,30 +147,97 @@ ScriptedThread::CreateRegisterContextForFrame(StackFrame *frame) { return m_reg_context_sp; } +bool ScriptedThread::LoadArtificialStackFrames() { + StructuredData::ArraySP arr_sp = GetInterface()->GetStackFrames(); + + Status error; + if (!arr_sp) + return ScriptedInterface::ErrorWithMessage<bool>( + LLVM_PRETTY_FUNCTION, "Failed to get scripted thread stackframes.", + error, LLDBLog::Thread); + + size_t arr_size = arr_sp->GetSize(); + if (arr_size > std::numeric_limits<uint32_t>::max()) + return ScriptedInterface::ErrorWithMessage<bool>( + LLVM_PRETTY_FUNCTION, + llvm::Twine( + "StackFrame array size (" + llvm::Twine(arr_size) + + llvm::Twine( + ") is greater than maximum autorized for a StackFrameList.")) + .str(), + error, LLDBLog::Thread); + + StackFrameListSP frames = GetStackFrameList(); + + for (size_t idx = 0; idx < arr_size; idx++) { + + StructuredData::Dictionary *dict; + + if (!arr_sp->GetItemAtIndexAsDictionary(idx, dict) || !dict) + return ScriptedInterface::ErrorWithMessage<bool>( + LLVM_PRETTY_FUNCTION, + llvm::Twine( + "Couldn't get artificial stackframe dictionary at index (" + + llvm::Twine(idx) + llvm::Twine(") from stackframe array.")) + .str(), + error, LLDBLog::Thread); + + lldb::addr_t pc; + if (!dict->GetValueForKeyAsInteger("pc", pc)) + return ScriptedInterface::ErrorWithMessage<bool>( + LLVM_PRETTY_FUNCTION, + "Couldn't find value for key 'pc' in stackframe dictionary.", error, + LLDBLog::Thread); + + Address symbol_addr; + symbol_addr.SetLoadAddress(pc, &this->GetProcess()->GetTarget()); + + lldb::addr_t cfa = LLDB_INVALID_ADDRESS; + bool cfa_is_valid = false; + const bool behaves_like_zeroth_frame = false; + SymbolContext sc; + symbol_addr.CalculateSymbolContext(&sc); + + StackFrameSP synth_frame_sp = std::make_shared<StackFrame>( + this->shared_from_this(), idx, idx, cfa, cfa_is_valid, pc, + StackFrame::Kind::Artificial, behaves_like_zeroth_frame, &sc); + + if (!frames->SetFrameAtIndex(static_cast<uint32_t>(idx), synth_frame_sp)) + return ScriptedInterface::ErrorWithMessage<bool>( + LLVM_PRETTY_FUNCTION, + llvm::Twine("Couldn't add frame (" + llvm::Twine(idx) + + llvm::Twine(") to ScriptedThread StackFrameList.")) + .str(), + error, LLDBLog::Thread); + } + + return true; +} + bool ScriptedThread::CalculateStopInfo() { StructuredData::DictionarySP dict_sp = GetInterface()->GetStopReason(); Status error; if (!dict_sp) - return GetInterface()->ErrorWithMessage<bool>( + return ScriptedInterface::ErrorWithMessage<bool>( LLVM_PRETTY_FUNCTION, "Failed to get scripted thread stop info.", error, - LIBLLDB_LOG_THREAD); + LLDBLog::Thread); lldb::StopInfoSP stop_info_sp; lldb::StopReason stop_reason_type; if (!dict_sp->GetValueForKeyAsInteger("type", stop_reason_type)) - return GetInterface()->ErrorWithMessage<bool>( + return ScriptedInterface::ErrorWithMessage<bool>( LLVM_PRETTY_FUNCTION, "Couldn't find value for key 'type' in stop reason dictionary.", error, - LIBLLDB_LOG_THREAD); + LLDBLog::Thread); StructuredData::Dictionary *data_dict; if (!dict_sp->GetValueForKeyAsDictionary("data", data_dict)) - return GetInterface()->ErrorWithMessage<bool>( + return ScriptedInterface::ErrorWithMessage<bool>( LLVM_PRETTY_FUNCTION, "Couldn't find value for key 'data' in stop reason dictionary.", error, - LIBLLDB_LOG_THREAD); + LLDBLog::Thread); switch (stop_reason_type) { case lldb::eStopReasonNone: @@ -201,12 +266,12 @@ bool ScriptedThread::CalculateStopInfo() { StopInfo::CreateStopReasonWithException(*this, description.data()); } break; default: - return GetInterface()->ErrorWithMessage<bool>( + return ScriptedInterface::ErrorWithMessage<bool>( LLVM_PRETTY_FUNCTION, llvm::Twine("Unsupported stop reason type (" + llvm::Twine(stop_reason_type) + llvm::Twine(").")) .str(), - error, LIBLLDB_LOG_THREAD); + error, LLDBLog::Thread); } if (!stop_info_sp) @@ -218,6 +283,7 @@ bool ScriptedThread::CalculateStopInfo() { void ScriptedThread::RefreshStateAfterStop() { GetRegisterContext()->InvalidateIfNeeded(/*force=*/false); + LoadArtificialStackFrames(); } lldb::ScriptedThreadInterfaceSP ScriptedThread::GetInterface() const { @@ -236,7 +302,7 @@ std::shared_ptr<DynamicRegisterInfo> ScriptedThread::GetDynamicRegisterInfo() { ->ErrorWithMessage<std::shared_ptr<DynamicRegisterInfo>>( LLVM_PRETTY_FUNCTION, "Failed to get scripted thread registers info.", error, - LIBLLDB_LOG_THREAD); + LLDBLog::Thread); m_register_info_sp = std::make_shared<DynamicRegisterInfo>( *reg_info, m_scripted_process.GetTarget().GetArchitecture()); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.h b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.h index 8d8a7c2a3df9..959f498edf24 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.h @@ -42,6 +42,8 @@ public: lldb::RegisterContextSP CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override; + bool LoadArtificialStackFrames(); + bool CalculateStopInfo() override; const char *GetInfo() override { return nullptr; } diff --git a/contrib/llvm-project/lldb/source/Plugins/REPL/Clang/ClangREPL.cpp b/contrib/llvm-project/lldb/source/Plugins/REPL/Clang/ClangREPL.cpp index 5060dbb7ddba..2bd38f81786b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/REPL/Clang/ClangREPL.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/REPL/Clang/ClangREPL.cpp @@ -19,7 +19,7 @@ ClangREPL::ClangREPL(lldb::LanguageType language, Target &target) : REPL(eKindClang, target), m_language(language), m_implicit_expr_result_regex("\\$[0-9]+") {} -ClangREPL::~ClangREPL() {} +ClangREPL::~ClangREPL() = default; void ClangREPL::Initialize() { LanguageSet languages; 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 c677abfaa5f2..5b9d1b7c1520 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp @@ -217,7 +217,6 @@ bool ScriptInterpreterLua::LoadScriptingModule( lldb_private::Status &error, StructuredData::ObjectSP *module_sp, FileSpec extra_search_dir) { - FileSystem::Instance().Collect(filename); if (llvm::Error e = m_lua->LoadModule(filename)) { error.SetErrorStringWithFormatv("lua failed to import '{0}': {1}\n", filename, llvm::toString(std::move(e))); 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 68f4e90d70f6..ae61736fbbb3 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp @@ -16,6 +16,7 @@ #include "lldb/Host/File.h" #include "lldb/Host/FileSystem.h" #include "lldb/Interpreter/ScriptInterpreter.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Stream.h" @@ -70,9 +71,7 @@ Expected<std::string> python::As<std::string>(Expected<PythonObject> &&obj) { } static bool python_is_finalizing() { -#if PY_MAJOR_VERSION == 2 - return false; -#elif PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 7 +#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 7 return _Py_Finalizing != nullptr; #else return _Py_IsFinalizing(); @@ -96,12 +95,6 @@ void PythonObject::Reset() { Expected<long long> PythonObject::AsLongLong() const { if (!m_py_obj) return nullDeref(); -#if PY_MAJOR_VERSION < 3 - if (!PyLong_Check(m_py_obj)) { - PythonInteger i(PyRefType::Borrowed, m_py_obj); - return i.AsLongLong(); - } -#endif assert(!PyErr_Occurred()); long long r = PyLong_AsLongLong(m_py_obj); if (PyErr_Occurred()) @@ -112,12 +105,6 @@ Expected<long long> PythonObject::AsLongLong() const { Expected<long long> PythonObject::AsUnsignedLongLong() const { if (!m_py_obj) return nullDeref(); -#if PY_MAJOR_VERSION < 3 - if (!PyLong_Check(m_py_obj)) { - PythonInteger i(PyRefType::Borrowed, m_py_obj); - return i.AsUnsignedLongLong(); - } -#endif assert(!PyErr_Occurred()); long long r = PyLong_AsUnsignedLongLong(m_py_obj); if (PyErr_Occurred()) @@ -129,12 +116,6 @@ Expected<long long> PythonObject::AsUnsignedLongLong() const { Expected<unsigned long long> PythonObject::AsModuloUnsignedLongLong() const { if (!m_py_obj) return nullDeref(); -#if PY_MAJOR_VERSION < 3 - if (!PyLong_Check(m_py_obj)) { - PythonInteger i(PyRefType::Borrowed, m_py_obj); - return i.AsModuloUnsignedLongLong(); - } -#endif assert(!PyErr_Occurred()); unsigned long long r = PyLong_AsUnsignedLongLongMask(m_py_obj); if (PyErr_Occurred()) @@ -182,10 +163,8 @@ PyObjectType PythonObject::GetObjectType() const { return PyObjectType::Dictionary; if (PythonString::Check(m_py_obj)) return PyObjectType::String; -#if PY_MAJOR_VERSION >= 3 if (PythonBytes::Check(m_py_obj)) return PyObjectType::Bytes; -#endif if (PythonByteArray::Check(m_py_obj)) return PyObjectType::ByteArray; if (PythonBoolean::Check(m_py_obj)) @@ -281,9 +260,7 @@ PythonObject PythonObject::GetAttributeValue(llvm::StringRef attr) const { } StructuredData::ObjectSP PythonObject::CreateStructuredObject() const { -#if PY_MAJOR_VERSION >= 3 assert(PyGILState_Check()); -#endif switch (GetObjectType()) { case PyObjectType::Dictionary: return PythonDictionary(PyRefType::Borrowed, m_py_obj) @@ -397,11 +374,7 @@ StructuredData::StringSP PythonByteArray::CreateStructuredString() const { // PythonString Expected<PythonString> PythonString::FromUTF8(llvm::StringRef string) { -#if PY_MAJOR_VERSION >= 3 PyObject *str = PyUnicode_FromStringAndSize(string.data(), string.size()); -#else - PyObject *str = PyString_FromStringAndSize(string.data(), string.size()); -#endif if (!str) return llvm::make_error<PythonException>(); return Take<PythonString>(str); @@ -415,35 +388,9 @@ bool PythonString::Check(PyObject *py_obj) { if (PyUnicode_Check(py_obj)) return true; -#if PY_MAJOR_VERSION < 3 - if (PyString_Check(py_obj)) - return true; -#endif return false; } -void PythonString::Convert(PyRefType &type, PyObject *&py_obj) { -#if PY_MAJOR_VERSION < 3 - // In Python 2, Don't store PyUnicode objects directly, because we need - // access to their underlying character buffers which Python 2 doesn't - // provide. - if (PyUnicode_Check(py_obj)) { - PyObject *s = PyUnicode_AsUTF8String(py_obj); - if (s == nullptr) { - PyErr_Clear(); - if (type == PyRefType::Owned) - Py_DECREF(py_obj); - return; - } - if (type == PyRefType::Owned) - Py_DECREF(py_obj); - else - type = PyRefType::Owned; - py_obj = s; - } -#endif -} - llvm::StringRef PythonString::GetString() const { auto s = AsUTF8(); if (!s) { @@ -460,15 +407,7 @@ Expected<llvm::StringRef> PythonString::AsUTF8() const { Py_ssize_t size; const char *data; -#if PY_MAJOR_VERSION >= 3 data = PyUnicode_AsUTF8AndSize(m_py_obj, &size); -#else - char *c = NULL; - int r = PyString_AsStringAndSize(m_py_obj, &c, &size); - if (r < 0) - c = NULL; - data = c; -#endif if (!data) return exception(); @@ -478,15 +417,11 @@ Expected<llvm::StringRef> PythonString::AsUTF8() const { size_t PythonString::GetSize() const { if (IsValid()) { -#if PY_MAJOR_VERSION >= 3 #if PY_MINOR_VERSION >= 3 return PyUnicode_GetLength(m_py_obj); #else return PyUnicode_GetSize(m_py_obj); #endif -#else - return PyString_Size(m_py_obj); -#endif } return 0; } @@ -515,41 +450,9 @@ bool PythonInteger::Check(PyObject *py_obj) { if (!py_obj) return false; -#if PY_MAJOR_VERSION >= 3 // Python 3 does not have PyInt_Check. There is only one type of integral // value, long. return PyLong_Check(py_obj); -#else - return PyLong_Check(py_obj) || PyInt_Check(py_obj); -#endif -} - -void PythonInteger::Convert(PyRefType &type, PyObject *&py_obj) { -#if PY_MAJOR_VERSION < 3 - // Always store this as a PyLong, which makes interoperability between Python - // 2.x and Python 3.x easier. This is only necessary in 2.x, since 3.x - // doesn't even have a PyInt. - if (PyInt_Check(py_obj)) { - // Since we converted the original object to a different type, the new - // object is an owned object regardless of the ownership semantics - // requested by the user. - long long value = PyInt_AsLong(py_obj); - PyObject *l = nullptr; - if (!PyErr_Occurred()) - l = PyLong_FromLongLong(value); - if (l == nullptr) { - PyErr_Clear(); - if (type == PyRefType::Owned) - Py_DECREF(py_obj); - return; - } - if (type == PyRefType::Owned) - Py_DECREF(py_obj); - else - type = PyRefType::Owned; - py_obj = l; - } -#endif } void PythonInteger::SetInteger(int64_t value) { @@ -761,13 +664,9 @@ Expected<PythonObject> PythonDictionary::GetItem(const PythonObject &key) const { if (!IsValid()) return nullDeref(); -#if PY_MAJOR_VERSION >= 3 PyObject *o = PyDict_GetItemWithError(m_py_obj, key.get()); if (PyErr_Occurred()) return exception(); -#else - PyObject *o = PyDict_GetItem(m_py_obj, key.get()); -#endif if (!o) return keyError(); return Retain<PythonObject>(o); @@ -825,13 +724,7 @@ PythonDictionary::CreateStructuredDictionary() const { return result; } -PythonModule PythonModule::BuiltinsModule() { -#if PY_MAJOR_VERSION >= 3 - return AddModule("builtins"); -#else - return AddModule("__builtin__"); -#endif -} +PythonModule PythonModule::BuiltinsModule() { return AddModule("builtins"); } PythonModule PythonModule::MainModule() { return AddModule("__main__"); } @@ -999,9 +892,6 @@ operator()(std::initializer_list<PythonObject> args) { bool PythonFile::Check(PyObject *py_obj) { if (!py_obj) return false; -#if PY_MAJOR_VERSION < 3 - return PyFile_Check(py_obj); -#else // In Python 3, there is no `PyFile_Check`, and in fact PyFile is not even a // first-class object type anymore. `PyFile_FromFd` is just a thin wrapper // over `io.open()`, which returns some object derived from `io.IOBase`. As a @@ -1023,7 +913,6 @@ bool PythonFile::Check(PyObject *py_obj) { return false; } return !!r; -#endif } const char *PythonException::toCString() const { @@ -1050,7 +939,7 @@ PythonException::PythonException(const char *caller) { PyErr_Clear(); } } - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT); + Log *log = GetLog(LLDBLog::Script); if (caller) LLDB_LOGF(log, "%s failed with exception: %s", caller, toCString()); else @@ -1120,7 +1009,6 @@ char PythonException::ID = 0; llvm::Expected<File::OpenOptions> GetOptionsForPyObject(const PythonObject &obj) { -#if PY_MAJOR_VERSION >= 3 auto options = File::OpenOptions(0); auto readable = As<bool>(obj.CallMethod("readable")); if (!readable) @@ -1135,10 +1023,6 @@ GetOptionsForPyObject(const PythonObject &obj) { else if (readable.get()) options |= File::eOpenOptionReadOnly; return options; -#else - PythonString py_mode = obj.GetAttributeValue("mode").AsType<PythonString>(); - return File::GetOptionsFromMode(py_mode.GetString()); -#endif } // Base class template for python files. All it knows how to do @@ -1222,8 +1106,6 @@ public: char SimplePythonFile::ID = 0; } // namespace -#if PY_MAJOR_VERSION >= 3 - namespace { class PythonBuffer { public: @@ -1413,8 +1295,6 @@ public: }; } // namespace -#endif - llvm::Expected<FileSP> PythonFile::ConvertToFile(bool borrowed) { if (!IsValid()) return llvm::createStringError(llvm::inconvertibleErrorCode(), @@ -1465,13 +1345,6 @@ PythonFile::ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed) { return llvm::createStringError(llvm::inconvertibleErrorCode(), "invalid PythonFile"); -#if PY_MAJOR_VERSION < 3 - - return llvm::createStringError(llvm::inconvertibleErrorCode(), - "not supported on python 2"); - -#else - int fd = PyObject_AsFileDescriptor(m_py_obj); if (fd < 0) { PyErr_Clear(); @@ -1521,8 +1394,6 @@ PythonFile::ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed) { "invalid File"); return file_sp; - -#endif } Expected<PythonFile> PythonFile::FromFile(File &file, const char *mode) { @@ -1532,10 +1403,8 @@ Expected<PythonFile> PythonFile::FromFile(File &file, const char *mode) { if (auto *simple = llvm::dyn_cast<SimplePythonFile>(&file)) return Retain<PythonFile>(simple->GetPythonObject()); -#if PY_MAJOR_VERSION >= 3 if (auto *pythonio = llvm::dyn_cast<PythonIOFile>(&file)) return Retain<PythonFile>(pythonio->GetPythonObject()); -#endif if (!mode) { auto m = file.GetOpenMode(); @@ -1545,26 +1414,8 @@ Expected<PythonFile> PythonFile::FromFile(File &file, const char *mode) { } PyObject *file_obj; -#if PY_MAJOR_VERSION >= 3 file_obj = PyFile_FromFd(file.GetDescriptor(), nullptr, mode, -1, nullptr, "ignore", nullptr, /*closefd=*/0); -#else - // I'd like to pass ::fflush here if the file is writable, so that - // when the python side destructs the file object it will be flushed. - // However, this would be dangerous. It can cause fflush to be called - // after fclose if the python program keeps a reference to the file after - // the original lldb_private::File has been destructed. - // - // It's all well and good to ask a python program not to use a closed file - // but asking a python program to make sure objects get released in a - // particular order is not safe. - // - // The tradeoff here is that if a python 2 program wants to make sure this - // file gets flushed, they'll have to do it explicitly or wait untill the - // original lldb File itself gets flushed. - file_obj = PyFile_FromFile(file.GetStream(), py2_const_cast(""), - py2_const_cast(mode), [](FILE *) { return 0; }); -#endif if (!file_obj) return exception(); @@ -1611,12 +1462,7 @@ python::runStringOneLine(const llvm::Twine &string, return exception(); auto code_ref = Take<PythonObject>(code); -#if PY_MAJOR_VERSION < 3 - PyObject *result = - PyEval_EvalCode((PyCodeObject *)code, globals.get(), locals.get()); -#else PyObject *result = PyEval_EvalCode(code, globals.get(), locals.get()); -#endif if (!result) return exception(); 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 2094f0b3afd2..76ad47f2907e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h @@ -181,13 +181,7 @@ inline llvm::Error keyError() { "key not in dict"); } -#if PY_MAJOR_VERSION < 3 -// The python 2 API declares some arguments as char* that should -// be const char *, but it doesn't actually modify them. -inline char *py2_const_cast(const char *s) { return const_cast<char *>(s); } -#else inline const char *py2_const_cast(const char *s) { return s; } -#endif enum class PyInitialValue { Invalid, Empty }; @@ -391,14 +385,9 @@ llvm::Expected<std::string> As<std::string>(llvm::Expected<PythonObject> &&obj); template <class T> class TypedPythonObject : public PythonObject { public: - // override to perform implicit type conversions on Reset - // This can be eliminated once we drop python 2 support. - static void Convert(PyRefType &type, PyObject *&py_obj) {} - TypedPythonObject(PyRefType type, PyObject *py_obj) { if (!py_obj) return; - T::Convert(type, py_obj); if (T::Check(py_obj)) PythonObject::operator=(PythonObject(type, py_obj)); else if (type == PyRefType::Owned) @@ -453,7 +442,6 @@ public: explicit PythonString(llvm::StringRef string); // safe, null on error static bool Check(PyObject *py_obj); - static void Convert(PyRefType &type, PyObject *&py_obj); llvm::StringRef GetString() const; // safe, empty string on error @@ -475,7 +463,6 @@ public: explicit PythonInteger(int64_t value); static bool Check(PyObject *py_obj); - static void Convert(PyRefType &type, PyObject *&py_obj); void SetInteger(int64_t value); @@ -649,7 +636,7 @@ public: const char *toCString() const; PythonException(const char *caller = nullptr); void Restore(); - ~PythonException(); + ~PythonException() override; void log(llvm::raw_ostream &OS) const override; std::error_code convertToErrorCode() const override; bool Matches(PyObject *exc) const; 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 95a3365ed983..2753847f39f8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonReadline.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonReadline.cpp @@ -22,7 +22,6 @@ PyDoc_STRVAR(moduleDocumentation, "Simple readline module implementation based on libedit."); -#if PY_MAJOR_VERSION >= 3 static struct PyModuleDef readline_module = { PyModuleDef_HEAD_INIT, // m_base "lldb_editline", // m_name @@ -34,26 +33,13 @@ static struct PyModuleDef readline_module = { nullptr, // m_clear nullptr, // m_free }; -#else -static struct PyMethodDef moduleMethods[] = {{nullptr, nullptr, 0, nullptr}}; -#endif -static char * -#if PY_MAJOR_VERSION >= 3 -simple_readline(FILE *stdin, FILE *stdout, const char *prompt) -#else -simple_readline(FILE *stdin, FILE *stdout, char *prompt) -#endif -{ +static char *simple_readline(FILE *stdin, FILE *stdout, const char *prompt) { rl_instream = stdin; rl_outstream = stdout; char *line = readline(prompt); if (!line) { -#if PY_MAJOR_VERSION >= 3 char *ret = (char *)PyMem_RawMalloc(1); -#else - char *ret = (char *)PyMem_Malloc(1); -#endif if (ret != NULL) *ret = '\0'; return ret; @@ -61,11 +47,7 @@ simple_readline(FILE *stdin, FILE *stdout, char *prompt) if (*line) add_history(line); int n = strlen(line); -#if PY_MAJOR_VERSION >= 3 char *ret = (char *)PyMem_RawMalloc(n + 2); -#else - char *ret = (char *)PyMem_Malloc(n + 2); -#endif if (ret) { memcpy(ret, line, n); free(line); @@ -78,11 +60,6 @@ simple_readline(FILE *stdin, FILE *stdout, char *prompt) PyMODINIT_FUNC initlldb_readline(void) { PyOS_ReadlineFunctionPointer = simple_readline; -#if PY_MAJOR_VERSION >= 3 return PyModule_Create(&readline_module); -#else - Py_InitModule4("readline", moduleMethods, moduleDocumentation, - static_cast<PyObject *>(NULL), PYTHON_API_VERSION); -#endif } #endif 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 1bf647e4acfc..53e2bcaccafb 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp @@ -38,6 +38,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlan.h" #include "lldb/Utility/Instrumentation.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Timer.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" @@ -59,17 +60,10 @@ using llvm::Expected; LLDB_PLUGIN_DEFINE(ScriptInterpreterPython) // Defined in the SWIG source file -#if PY_MAJOR_VERSION >= 3 extern "C" PyObject *PyInit__lldb(void); #define LLDBSwigPyInit PyInit__lldb -#else -extern "C" void init_lldb(void); - -#define LLDBSwigPyInit init_lldb -#endif - #if defined(_WIN32) // Don't mess with the signal handlers on Windows. #define LLDB_USE_PYTHON_SET_INTERRUPT 0 @@ -131,7 +125,7 @@ public: ~InitializePythonRAII() { if (m_was_already_initialized) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT)); + Log *log = GetLog(LLDBLog::Script); LLDB_LOGV(log, "Releasing PyGILState. Returning to state = {0}locked", m_gil_state == PyGILState_UNLOCKED ? "un" : ""); PyGILState_Release(m_gil_state); @@ -144,11 +138,7 @@ public: private: void InitializePythonHome() { #if LLDB_EMBED_PYTHON_HOME -#if PY_MAJOR_VERSION >= 3 - typedef wchar_t* str_type; -#else - typedef char* str_type; -#endif + typedef wchar_t *str_type; static str_type g_python_home = []() -> str_type { const char *lldb_python_home = LLDB_PYTHON_HOME; const char *absolute_python_home = nullptr; @@ -163,27 +153,12 @@ private: llvm::sys::path::append(path, lldb_python_home); absolute_python_home = path.c_str(); } -#if PY_MAJOR_VERSION >= 3 size_t size = 0; return Py_DecodeLocale(absolute_python_home, &size); -#else - return strdup(absolute_python_home); -#endif }(); if (g_python_home != nullptr) { Py_SetPythonHome(g_python_home); } -#else -#if defined(__APPLE__) && PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION == 7 - // For Darwin, the only Python version supported is the one shipped in the - // OS OS and linked with lldb. Other installation of Python may have higher - // priorities in the path, overriding PYTHONHOME and causing - // problems/incompatibilities. In order to avoid confusion, always hardcode - // the PythonHome to be right, as it's not going to change. - static char path[] = - "/System/Library/Frameworks/Python.framework/Versions/2.7"; - Py_SetPythonHome(path); -#endif #endif } @@ -201,7 +176,7 @@ private: #endif if (PyEval_ThreadsInitialized()) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT)); + Log *log = GetLog(LLDBLog::Script); m_was_already_initialized = true; m_gil_state = PyGILState_Ensure(); @@ -380,7 +355,7 @@ ScriptInterpreterPythonImpl::Locker::Locker( } bool ScriptInterpreterPythonImpl::Locker::DoAcquireLock() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT)); + Log *log = GetLog(LLDBLog::Script); m_GILState = PyGILState_Ensure(); LLDB_LOGV(log, "Ensured PyGILState. Previous state = {0}locked", m_GILState == PyGILState_UNLOCKED ? "un" : ""); @@ -404,7 +379,7 @@ bool ScriptInterpreterPythonImpl::Locker::DoInitSession(uint16_t on_entry_flags, } bool ScriptInterpreterPythonImpl::Locker::DoFreeLock() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT)); + Log *log = GetLog(LLDBLog::Script); LLDB_LOGV(log, "Releasing PyGILState. Returning to state = {0}locked", m_GILState == PyGILState_UNLOCKED ? "un" : ""); PyGILState_Release(m_GILState); @@ -590,7 +565,7 @@ ScriptInterpreterPythonImpl::CreateInstance(Debugger &debugger) { } void ScriptInterpreterPythonImpl::LeaveSession() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT)); + Log *log = GetLog(LLDBLog::Script); if (log) log->PutCString("ScriptInterpreterPythonImpl::LeaveSession()"); @@ -660,7 +635,7 @@ bool ScriptInterpreterPythonImpl::EnterSession(uint16_t on_entry_flags, FileSP err_sp) { // If we have already entered the session, without having officially 'left' // it, then there is no need to 'enter' it again. - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT)); + Log *log = GetLog(LLDBLog::Script); if (m_session_is_active) { LLDB_LOGF( log, @@ -962,7 +937,7 @@ bool ScriptInterpreterPythonImpl::Interrupt() { // just our (hardcoded) input signal code SIGINT, so that's not useful at all. return true; #else - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT)); + Log *log = GetLog(LLDBLog::Script); if (IsExecutingPython()) { PyThreadState *state = PyThreadState_GET(); @@ -2722,7 +2697,6 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule( } else { FileSpec module_file(pathname); FileSystem::Instance().Resolve(module_file); - FileSystem::Instance().Collect(module_file); fs::file_status st; std::error_code ec = status(module_file.GetPath(), st); diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp index e39f8be73e49..576bf69c9258 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp @@ -8,7 +8,6 @@ #include "lldb/Host/Config.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" #include "lldb/lldb-enumerations.h" #if LLDB_ENABLE_PYTHON @@ -125,9 +124,21 @@ lldb::DataExtractorSP ScriptedProcessPythonInterface::ReadMemoryAtAddress( address, size); } -StructuredData::DictionarySP ScriptedProcessPythonInterface::GetLoadedImages() { - // TODO: Implement - return {}; +StructuredData::ArraySP ScriptedProcessPythonInterface::GetLoadedImages() { + Status error; + StructuredData::ArraySP array = + Dispatch<StructuredData::ArraySP>("get_loaded_images", error); + + if (!array || !array->IsValid() || error.Fail()) { + return ScriptedInterface::ErrorWithMessage<StructuredData::ArraySP>( + LLVM_PRETTY_FUNCTION, + llvm::Twine("Null or invalid object (" + + llvm::Twine(error.AsCString()) + llvm::Twine(").")) + .str(), + error); + } + + return array; } lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() { diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h index e34a181849eb..7f458b1dd9bd 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h @@ -49,7 +49,7 @@ public: lldb::DataExtractorSP ReadMemoryAtAddress(lldb::addr_t address, size_t size, Status &error) override; - StructuredData::DictionarySP GetLoadedImages() override; + StructuredData::ArraySP GetLoadedImages() override; lldb::pid_t GetProcessID() override; diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp index 07bf952bf840..d5c527c61a5c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp @@ -8,7 +8,6 @@ #include "lldb/Host/Config.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" #include "lldb/lldb-enumerations.h" #if LLDB_ENABLE_PYTHON @@ -36,6 +35,14 @@ ScriptedPythonInterface::GetStatusFromMethod(llvm::StringRef method_name) { } template <> +StructuredData::ArraySP +ScriptedPythonInterface::ExtractValueFromPythonObject<StructuredData::ArraySP>( + python::PythonObject &p, Status &error) { + python::PythonList result_list(python::PyRefType::Borrowed, p.get()); + return result_list.CreateStructuredArray(); +} + +template <> StructuredData::DictionarySP ScriptedPythonInterface::ExtractValueFromPythonObject< StructuredData::DictionarySP>(python::PythonObject &p, Status &error) { diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h index da112eb72022..7c2fadc21d42 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h @@ -25,7 +25,7 @@ class ScriptInterpreterPythonImpl; class ScriptedPythonInterface : virtual public ScriptedInterface { public: ScriptedPythonInterface(ScriptInterpreterPythonImpl &interpreter); - virtual ~ScriptedPythonInterface() = default; + ~ScriptedPythonInterface() override = default; protected: template <typename T = StructuredData::ObjectSP> @@ -127,6 +127,11 @@ protected: }; template <> +StructuredData::ArraySP +ScriptedPythonInterface::ExtractValueFromPythonObject<StructuredData::ArraySP>( + python::PythonObject &p, Status &error); + +template <> StructuredData::DictionarySP ScriptedPythonInterface::ExtractValueFromPythonObject< StructuredData::DictionarySP>(python::PythonObject &p, Status &error); diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp index d471b2c5f7e3..3ff592fb83cd 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp @@ -8,7 +8,6 @@ #include "lldb/Host/Config.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" #include "lldb/lldb-enumerations.h" #if LLDB_ENABLE_PYTHON @@ -113,7 +112,14 @@ StructuredData::DictionarySP ScriptedThreadPythonInterface::GetStopReason() { } StructuredData::ArraySP ScriptedThreadPythonInterface::GetStackFrames() { - return nullptr; + Status error; + StructuredData::ArraySP arr = + Dispatch<StructuredData::ArraySP>("get_stackframes", error); + + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, arr, error)) + return {}; + + return arr; } StructuredData::DictionarySP ScriptedThreadPythonInterface::GetRegisterInfo() { 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 b024854f3981..85366d3f9f4b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp @@ -28,6 +28,7 @@ #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/ThreadPlanCallOnFunctionExit.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegularExpression.h" @@ -958,7 +959,7 @@ public: }; EnableOptionsSP ParseAutoEnableOptions(Status &error, Debugger &debugger) { - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS); + Log *log = GetLog(LLDBLog::Process); // We are abusing the options data model here so that we can parse options // without requiring the Debugger instance. @@ -1062,7 +1063,7 @@ bool StructuredDataDarwinLog::SupportsStructuredDataType( void StructuredDataDarwinLog::HandleArrivalOfStructuredData( Process &process, ConstString type_name, const StructuredData::ObjectSP &object_sp) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); if (log) { StreamString json_stream; if (object_sp) @@ -1211,7 +1212,7 @@ void StructuredDataDarwinLog::SetEnabled(bool enabled) { void StructuredDataDarwinLog::ModulesDidLoad(Process &process, ModuleList &module_list) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "StructuredDataDarwinLog::%s called (process uid %u)", __FUNCTION__, process.GetUniqueID()); @@ -1388,7 +1389,7 @@ Status StructuredDataDarwinLog::FilterLaunchInfo(ProcessLaunchInfo &launch_info, // done by adding an environment variable to the process on launch. (This // also means it is not possible to suppress this behavior if attaching to an // already-running app). - // Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); + // Log *log = GetLog(LLDBLog::Platform); // If the target architecture is not one that supports DarwinLog, we have // nothing to do here. @@ -1466,7 +1467,7 @@ bool StructuredDataDarwinLog::InitCompletionHookCallback( // finishes and control returns to our new thread plan, that is the time when // we can execute our logic to enable the logging support. - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "StructuredDataDarwinLog::%s() called", __FUNCTION__); // Get the current thread. @@ -1570,7 +1571,7 @@ bool StructuredDataDarwinLog::InitCompletionHookCallback( } void StructuredDataDarwinLog::AddInitCompletionHook(Process &process) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "StructuredDataDarwinLog::%s() called (process uid %u)", __FUNCTION__, process.GetUniqueID()); @@ -1769,7 +1770,7 @@ size_t StructuredDataDarwinLog::HandleDisplayOfEvent( } void StructuredDataDarwinLog::EnableNow() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "StructuredDataDarwinLog::%s() called", __FUNCTION__); // Run the enable command. @@ -1817,13 +1818,8 @@ void StructuredDataDarwinLog::EnableNow() { "enable command failed (process uid %u)", __FUNCTION__, process_sp->GetUniqueID()); } - // Report failures to the debugger error stream. - auto error_stream_sp = debugger_sp->GetAsyncErrorStream(); - if (error_stream_sp) { - error_stream_sp->Printf("failed to configure DarwinLog " - "support\n"); - error_stream_sp->Flush(); - } + Debugger::ReportError("failed to configure DarwinLog support", + debugger_sp->GetID()); return; } @@ -1851,13 +1847,8 @@ void StructuredDataDarwinLog::EnableNow() { "ConfigureStructuredData() call failed " "(process uid %u): %s", __FUNCTION__, process_sp->GetUniqueID(), error.AsCString()); - auto error_stream_sp = debugger_sp->GetAsyncErrorStream(); - if (error_stream_sp) { - error_stream_sp->Printf("failed to configure DarwinLog " - "support: %s\n", - error.AsCString()); - error_stream_sp->Flush(); - } + Debugger::ReportError("failed to configure DarwinLog support", + debugger_sp->GetID()); m_is_enabled = false; } else { m_is_enabled = true; 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 9d23f1baf931..b5615c358b95 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp @@ -17,6 +17,7 @@ #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolVendor.h" #include "lldb/Symbol/TypeMap.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" #include "llvm/ADT/StringExtras.h" @@ -228,7 +229,7 @@ FunctionSP SymbolFileBreakpad::GetOrCreateFunction(CompileUnit &comp_unit) { if (FunctionSP func_sp = comp_unit.FindFunctionByUID(id)) return func_sp; - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS); + Log *log = GetLog(LLDBLog::Symbols); FunctionSP func_sp; addr_t base = GetBaseFileAddress(); if (base == LLDB_INVALID_ADDRESS) { @@ -347,7 +348,7 @@ void SymbolFileBreakpad::ParseInlineOriginRecords() { return; m_inline_origins.emplace(); - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS); + Log *log = GetLog(LLDBLog::Symbols); for (llvm::StringRef line : lines(Record::InlineOrigin)) { auto record = InlineOriginRecord::parse(line); if (!record) { @@ -455,7 +456,7 @@ void SymbolFileBreakpad::FindTypes( llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) {} void SymbolFileBreakpad::AddSymbols(Symtab &symtab) { - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS); + Log *log = GetLog(LLDBLog::Symbols); Module &module = *m_objfile_sp->GetModule(); addr_t base = GetBaseFileAddress(); if (base == LLDB_INVALID_ADDRESS) { @@ -487,8 +488,8 @@ void SymbolFileBreakpad::AddSymbols(Symtab &symtab) { /*is_global*/ true, /*is_debug*/ false, /*is_trampoline*/ false, /*is_artificial*/ false, AddressRange(section_sp, address - section_sp->GetFileAddress(), - size.getValueOr(0)), - size.hasValue(), /*contains_linker_annotations*/ false, /*flags*/ 0); + size.value_or(0)), + size.has_value(), /*contains_linker_annotations*/ false, /*flags*/ 0); }; for (llvm::StringRef line : lines(Record::Public)) { @@ -510,7 +511,7 @@ SymbolFileBreakpad::GetParameterStackSize(Symbol &symbol) { symbol.GetAddress().GetFileAddress())) { auto record = StackWinRecord::parse( *LineIterator(*m_objfile_sp, Record::StackWin, entry->data)); - assert(record.hasValue()); + assert(record); return record->ParameterSize; } return llvm::createStringError(llvm::inconvertibleErrorCode(), @@ -581,7 +582,7 @@ llvm::ArrayRef<uint8_t> SymbolFileBreakpad::SaveAsDWARF(postfix::Node &node) { bool SymbolFileBreakpad::ParseCFIUnwindRow(llvm::StringRef unwind_rules, const RegisterInfoResolver &resolver, UnwindPlan::Row &row) { - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS); + Log *log = GetLog(LLDBLog::Symbols); llvm::BumpPtrAllocator node_alloc; llvm::Triple triple = m_objfile_sp->GetArchitecture().GetTriple(); @@ -654,7 +655,7 @@ SymbolFileBreakpad::ParseCFIUnwindPlan(const Bookmark &bookmark, LineIterator It(*m_objfile_sp, Record::StackCFI, bookmark), End(*m_objfile_sp); llvm::Optional<StackCFIRecord> init_record = StackCFIRecord::parse(*It); - assert(init_record.hasValue() && init_record->Size.hasValue() && + assert(init_record && init_record->Size && "Record already parsed successfully in ParseUnwindData!"); auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindLLDB); @@ -673,9 +674,9 @@ SymbolFileBreakpad::ParseCFIUnwindPlan(const Bookmark &bookmark, plan_sp->AppendRow(row_sp); for (++It; It != End; ++It) { llvm::Optional<StackCFIRecord> record = StackCFIRecord::parse(*It); - if (!record.hasValue()) + if (!record) return nullptr; - if (record->Size.hasValue()) + if (record->Size) break; row_sp = std::make_shared<UnwindPlan::Row>(*row_sp); @@ -690,15 +691,14 @@ SymbolFileBreakpad::ParseCFIUnwindPlan(const Bookmark &bookmark, UnwindPlanSP SymbolFileBreakpad::ParseWinUnwindPlan(const Bookmark &bookmark, const RegisterInfoResolver &resolver) { - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS); + Log *log = GetLog(LLDBLog::Symbols); addr_t base = GetBaseFileAddress(); if (base == LLDB_INVALID_ADDRESS) return nullptr; LineIterator It(*m_objfile_sp, Record::StackWin, bookmark); llvm::Optional<StackWinRecord> record = StackWinRecord::parse(*It); - assert(record.hasValue() && - "Record already parsed successfully in ParseUnwindData!"); + assert(record && "Record already parsed successfully in ParseUnwindData!"); auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindLLDB); plan_sp->SetSourceName("breakpad STACK WIN"); @@ -794,7 +794,7 @@ void SymbolFileBreakpad::ParseFileRecords() { return; m_files.emplace(); - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS); + Log *log = GetLog(LLDBLog::Symbols); for (llvm::StringRef line : lines(Record::File)) { auto record = FileRecord::parse(line); if (!record) { @@ -805,7 +805,7 @@ void SymbolFileBreakpad::ParseFileRecords() { if (record->Number >= m_files->size()) m_files->resize(record->Number + 1); FileSpec::Style style = FileSpec::GuessPathStyle(record->Name) - .getValueOr(FileSpec::Style::native); + .value_or(FileSpec::Style::native); (*m_files)[record->Number] = FileSpec(record->Name, style); } } @@ -815,7 +815,7 @@ void SymbolFileBreakpad::ParseCUData() { return; m_cu_data.emplace(); - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS); + Log *log = GetLog(LLDBLog::Symbols); addr_t base = GetBaseFileAddress(); if (base == LLDB_INVALID_ADDRESS) { LLDB_LOG(log, "SymbolFile parsing failed: Unable to fetch the base address " @@ -894,7 +894,7 @@ void SymbolFileBreakpad::ParseUnwindData() { return; m_unwind_data.emplace(); - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS); + Log *log = GetLog(LLDBLog::Symbols); addr_t base = GetBaseFileAddress(); if (base == LLDB_INVALID_ADDRESS) { LLDB_LOG(log, "SymbolFile parsing failed: Unable to fetch the base address " 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 bf3e25c1a63e..639d2e272adf 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h @@ -20,7 +20,7 @@ namespace lldb_private { namespace breakpad { -class SymbolFileBreakpad : public SymbolFile { +class SymbolFileBreakpad : public SymbolFileCommon { /// LLVM RTTI support. static char ID; @@ -28,7 +28,7 @@ public: /// LLVM RTTI support. /// \{ bool isA(const void *ClassID) const override { - return ClassID == &ID || SymbolFile::isA(ClassID); + return ClassID == &ID || SymbolFileCommon::isA(ClassID); } static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } /// \} @@ -49,7 +49,7 @@ public: // Constructors and Destructors SymbolFileBreakpad(lldb::ObjectFileSP objfile_sp) - : SymbolFile(std::move(objfile_sp)) {} + : SymbolFileCommon(std::move(objfile_sp)) {} ~SymbolFileBreakpad() override = default; diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp index ec4057efbbc5..4877169b3213 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp @@ -16,6 +16,7 @@ using namespace lldb_private; using namespace lldb; +using namespace lldb_private::dwarf; std::unique_ptr<AppleDWARFIndex> AppleDWARFIndex::Create( Module &module, DWARFDataExtractor apple_names, diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h index 23e1eec26ec3..4370039d1a8d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h @@ -29,7 +29,7 @@ public: DIERef(llvm::Optional<uint32_t> dwo_num, Section section, dw_offset_t die_offset) - : m_dwo_num(dwo_num.getValueOr(0)), m_dwo_num_valid(bool(dwo_num)), + : m_dwo_num(dwo_num.value_or(0)), m_dwo_num_valid(bool(dwo_num)), m_section(section), m_die_offset(die_offset) { assert(this->dwo_num() == dwo_num && "Dwo number out of range?"); } diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.cpp new file mode 100644 index 000000000000..364d34c73375 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.cpp @@ -0,0 +1,115 @@ +//===-- DWARFASTParser.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 "DWARFASTParser.h" +#include "DWARFAttribute.h" +#include "DWARFDIE.h" + +#include "lldb/Core/ValueObject.h" +#include "lldb/Symbol/SymbolFile.h" +#include "lldb/Target/StackFrame.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::dwarf; + +llvm::Optional<SymbolFile::ArrayInfo> +DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die, + const ExecutionContext *exe_ctx) { + SymbolFile::ArrayInfo array_info; + if (!parent_die) + return llvm::None; + + for (DWARFDIE die : parent_die.children()) { + const dw_tag_t tag = die.Tag(); + if (tag != DW_TAG_subrange_type) + continue; + + DWARFAttributes attributes; + const size_t num_child_attributes = die.GetAttributes(attributes); + if (num_child_attributes > 0) { + uint64_t num_elements = 0; + uint64_t lower_bound = 0; + uint64_t upper_bound = 0; + bool upper_bound_valid = false; + uint32_t i; + for (i = 0; i < num_child_attributes; ++i) { + const dw_attr_t attr = attributes.AttributeAtIndex(i); + DWARFFormValue form_value; + if (attributes.ExtractFormValueAtIndex(i, form_value)) { + switch (attr) { + case DW_AT_name: + break; + + case DW_AT_count: + if (DWARFDIE var_die = die.GetReferencedDIE(DW_AT_count)) { + if (var_die.Tag() == DW_TAG_variable) + if (exe_ctx) { + if (auto frame = exe_ctx->GetFrameSP()) { + Status error; + lldb::VariableSP var_sp; + auto valobj_sp = frame->GetValueForVariableExpressionPath( + var_die.GetName(), eNoDynamicValues, 0, var_sp, error); + if (valobj_sp) { + num_elements = valobj_sp->GetValueAsUnsigned(0); + break; + } + } + } + } else + num_elements = form_value.Unsigned(); + break; + + case DW_AT_bit_stride: + array_info.bit_stride = form_value.Unsigned(); + break; + + case DW_AT_byte_stride: + array_info.byte_stride = form_value.Unsigned(); + break; + + case DW_AT_lower_bound: + lower_bound = form_value.Unsigned(); + break; + + case DW_AT_upper_bound: + upper_bound_valid = true; + upper_bound = form_value.Unsigned(); + break; + + default: + break; + } + } + } + + if (num_elements == 0) { + if (upper_bound_valid && upper_bound >= lower_bound) + num_elements = upper_bound - lower_bound + 1; + } + + array_info.element_orders.push_back(num_elements); + } + } + return array_info; +} + +AccessType +DWARFASTParser::GetAccessTypeFromDWARF(uint32_t dwarf_accessibility) { + switch (dwarf_accessibility) { + case DW_ACCESS_public: + return eAccessPublic; + case DW_ACCESS_private: + return eAccessPrivate; + case DW_ACCESS_protected: + return eAccessProtected; + default: + break; + } + return eAccessNone; +} 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 00123a4b9216..97b0ea1874e1 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h @@ -14,6 +14,7 @@ #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/CompilerDecl.h" #include "lldb/Symbol/CompilerDeclContext.h" +#include "lldb/lldb-enumerations.h" class DWARFDIE; namespace lldb_private { @@ -54,6 +55,8 @@ public: static llvm::Optional<lldb_private::SymbolFile::ArrayInfo> ParseChildArrayInfo(const DWARFDIE &parent_die, const lldb_private::ExecutionContext *exe_ctx = nullptr); + + static lldb::AccessType GetAccessTypeFromDWARF(uint32_t dwarf_accessibility); }; #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSER_H 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 2daffecee58e..2aacac3692be 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -8,6 +8,7 @@ #include <cstdlib> +#include "DWARFASTParser.h" #include "DWARFASTParserClang.h" #include "DWARFDebugInfo.h" #include "DWARFDeclContext.h" @@ -57,25 +58,12 @@ using namespace lldb; using namespace lldb_private; +using namespace lldb_private::dwarf; DWARFASTParserClang::DWARFASTParserClang(TypeSystemClang &ast) : m_ast(ast), m_die_to_decl_ctx(), m_decl_ctx_to_die() {} DWARFASTParserClang::~DWARFASTParserClang() = default; -static AccessType DW_ACCESS_to_AccessType(uint32_t dwarf_accessibility) { - switch (dwarf_accessibility) { - case DW_ACCESS_public: - return eAccessPublic; - case DW_ACCESS_private: - return eAccessPrivate; - case DW_ACCESS_protected: - return eAccessProtected; - default: - break; - } - return eAccessNone; -} - static bool DeclKindIsCXXClass(clang::Decl::Kind decl_kind) { switch (decl_kind) { case clang::Decl::CXXRecord: @@ -313,7 +301,7 @@ ParsedDWARFTypeAttributes::ParsedDWARFTypeAttributes(const DWARFDIE &die) { break; case DW_AT_accessibility: - accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); + accessibility = DWARFASTParser::GetAccessTypeFromDWARF(form_value.Unsigned()); break; case DW_AT_artificial: @@ -626,7 +614,7 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc, resolve_state = Type::ResolveState::Full; clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize( attrs.name.GetStringRef(), attrs.encoding, - attrs.byte_size.getValueOr(0) * 8); + attrs.byte_size.value_or(0) * 8); break; case DW_TAG_pointer_type: @@ -861,7 +849,7 @@ TypeSP DWARFASTParserClang::ParseEnum(const SymbolContext &sc, bool is_signed = false; enumerator_clang_type.IsIntegerType(is_signed); ParseChildEnumerators(clang_type, is_signed, - type_sp->GetByteSize(nullptr).getValueOr(0), die); + type_sp->GetByteSize(nullptr).value_or(0), die); } TypeSystemClang::CompleteTagDeclarationDefinition(clang_type); } else { @@ -1039,10 +1027,8 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, // struct and see if this is actually a C++ method Type *class_type = dwarf->ResolveType(decl_ctx_die); if (class_type) { - bool alternate_defn = false; if (class_type->GetID() != decl_ctx_die.GetID() || IsClangModuleFwdDecl(decl_ctx_die)) { - alternate_defn = true; // We uniqued the parent class of this function to another // class so we now need to associate all dies under @@ -1111,7 +1097,7 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, CompilerType class_opaque_type = class_type->GetForwardCompilerType(); if (TypeSystemClang::IsCXXClassType(class_opaque_type)) { - if (class_opaque_type.IsBeingDefined() || alternate_defn) { + if (class_opaque_type.IsBeingDefined()) { if (!is_static && !die.HasChildren()) { // We have a C++ member function with no children (this // pointer!) and clang will get mad if we try and make @@ -1119,84 +1105,50 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, // we will just skip it... type_handled = true; } else { - bool add_method = true; - if (alternate_defn) { - // If an alternate definition for the class exists, - // then add the method only if an equivalent is not - // already present. - clang::CXXRecordDecl *record_decl = - m_ast.GetAsCXXRecordDecl( - class_opaque_type.GetOpaqueQualType()); - if (record_decl) { - for (auto method_iter = record_decl->method_begin(); - method_iter != record_decl->method_end(); - method_iter++) { - clang::CXXMethodDecl *method_decl = *method_iter; - if (method_decl->getNameInfo().getAsString() == - attrs.name.GetStringRef()) { - if (method_decl->getType() == - ClangUtil::GetQualType(clang_type)) { - add_method = false; - LinkDeclContextToDIE(method_decl, die); - type_handled = true; - - break; - } - } - } - } - } - - if (add_method) { - llvm::PrettyStackTraceFormat stack_trace( - "SymbolFileDWARF::ParseType() is adding a method " - "%s to class %s in DIE 0x%8.8" PRIx64 " from %s", - attrs.name.GetCString(), - class_type->GetName().GetCString(), die.GetID(), - dwarf->GetObjectFile() - ->GetFileSpec() - .GetPath() - .c_str()); - - const bool is_attr_used = false; - // Neither GCC 4.2 nor clang++ currently set a valid - // accessibility in the DWARF for C++ methods... - // Default to public for now... - if (attrs.accessibility == eAccessNone) - attrs.accessibility = eAccessPublic; - - clang::CXXMethodDecl *cxx_method_decl = - m_ast.AddMethodToCXXRecordType( - class_opaque_type.GetOpaqueQualType(), - attrs.name.GetCString(), attrs.mangled_name, - clang_type, attrs.accessibility, attrs.is_virtual, - is_static, attrs.is_inline, attrs.is_explicit, - is_attr_used, attrs.is_artificial); - - type_handled = cxx_method_decl != nullptr; - // Artificial methods are always handled even when we - // don't create a new declaration for them. - type_handled |= attrs.is_artificial; - - if (cxx_method_decl) { - LinkDeclContextToDIE(cxx_method_decl, die); - - ClangASTMetadata metadata; - metadata.SetUserID(die.GetID()); - - if (!object_pointer_name.empty()) { - metadata.SetObjectPtrName( - object_pointer_name.c_str()); - LLDB_LOGF(log, - "Setting object pointer name: %s on method " - "object %p.\n", - object_pointer_name.c_str(), - static_cast<void *>(cxx_method_decl)); - } - m_ast.SetMetadata(cxx_method_decl, metadata); - } else { - ignore_containing_context = true; + llvm::PrettyStackTraceFormat stack_trace( + "SymbolFileDWARF::ParseType() is adding a method " + "%s to class %s in DIE 0x%8.8" PRIx64 " from %s", + attrs.name.GetCString(), + class_type->GetName().GetCString(), die.GetID(), + dwarf->GetObjectFile()->GetFileSpec().GetPath().c_str()); + + const bool is_attr_used = false; + // Neither GCC 4.2 nor clang++ currently set a valid + // accessibility in the DWARF for C++ methods... + // Default to public for now... + if (attrs.accessibility == eAccessNone) + attrs.accessibility = eAccessPublic; + + clang::CXXMethodDecl *cxx_method_decl = + m_ast.AddMethodToCXXRecordType( + class_opaque_type.GetOpaqueQualType(), + attrs.name.GetCString(), attrs.mangled_name, + clang_type, attrs.accessibility, attrs.is_virtual, + is_static, attrs.is_inline, attrs.is_explicit, + is_attr_used, attrs.is_artificial); + + type_handled = cxx_method_decl != nullptr; + // Artificial methods are always handled even when we + // don't create a new declaration for them. + type_handled |= attrs.is_artificial; + + if (cxx_method_decl) { + LinkDeclContextToDIE(cxx_method_decl, die); + + ClangASTMetadata metadata; + metadata.SetUserID(die.GetID()); + + if (!object_pointer_name.empty()) { + metadata.SetObjectPtrName(object_pointer_name.c_str()); + LLDB_LOGF(log, + "Setting object pointer name: %s on method " + "object %p.\n", + object_pointer_name.c_str(), + static_cast<void *>(cxx_method_decl)); } + m_ast.SetMetadata(cxx_method_decl, metadata); + } else { + ignore_containing_context = true; } } } else { @@ -1345,7 +1297,7 @@ TypeSP DWARFASTParserClang::ParseArrayType(const DWARFDIE &die, attrs.bit_stride = array_info->bit_stride; } if (attrs.byte_stride == 0 && attrs.bit_stride == 0) - attrs.byte_stride = element_type->GetByteSize(nullptr).getValueOr(0); + attrs.byte_stride = element_type->GetByteSize(nullptr).value_or(0); CompilerType array_element_type = element_type->GetForwardCompilerType(); RequireCompleteType(array_element_type); @@ -1458,7 +1410,7 @@ void DWARFASTParserClang::ParseInheritance( break; case DW_AT_accessibility: - accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); + accessibility = DWARFASTParser::GetAccessTypeFromDWARF(form_value.Unsigned()); break; case DW_AT_virtuality: @@ -1580,7 +1532,7 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, } if (dwarf->GetUniqueDWARFASTTypeMap().Find( - unique_typename, die, unique_decl, attrs.byte_size.getValueOr(-1), + unique_typename, die, unique_decl, attrs.byte_size.value_or(-1), *unique_ast_entry_up)) { type_sp = unique_ast_entry_up->m_type_sp; if (type_sp) { @@ -1805,7 +1757,7 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, unique_ast_entry_up->m_type_sp = type_sp; unique_ast_entry_up->m_die = die; unique_ast_entry_up->m_declaration = unique_decl; - unique_ast_entry_up->m_byte_size = attrs.byte_size.getValueOr(0); + unique_ast_entry_up->m_byte_size = attrs.byte_size.value_or(0); dwarf->GetUniqueDWARFASTTypeMap().Insert(unique_typename, *unique_ast_entry_up); @@ -2162,7 +2114,7 @@ bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die, if (!layout_info.field_offsets.empty() || !layout_info.base_offsets.empty() || !layout_info.vbase_offsets.empty()) { if (type) - layout_info.bit_size = type->GetByteSize(nullptr).getValueOr(0) * 8; + layout_info.bit_size = type->GetByteSize(nullptr).value_or(0) * 8; if (layout_info.bit_size == 0) layout_info.bit_size = die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8; @@ -2184,7 +2136,7 @@ bool DWARFASTParserClang::CompleteEnumType(const DWARFDIE &die, bool is_signed = false; clang_type.IsIntegerType(is_signed); ParseChildEnumerators(clang_type, is_signed, - type->GetByteSize(nullptr).getValueOr(0), die); + type->GetByteSize(nullptr).value_or(0), die); } TypeSystemClang::CompleteTagDeclarationDefinition(clang_type); } @@ -2443,8 +2395,6 @@ struct MemberAttributes { /// structure. uint32_t member_byte_offset; bool is_artificial = false; - /// On DW_TAG_members, this means the member is static. - bool is_external = false; }; /// Parsed form of all attributes that are relevant for parsing Objective-C @@ -2515,14 +2465,11 @@ MemberAttributes::MemberAttributes(const DWARFDIE &die, break; case DW_AT_accessibility: - accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); + accessibility = DWARFASTParser::GetAccessTypeFromDWARF(form_value.Unsigned()); break; case DW_AT_artificial: is_artificial = form_value.Boolean(); break; - case DW_AT_external: - is_external = form_value.Boolean(); - break; default: break; } @@ -2541,7 +2488,7 @@ MemberAttributes::MemberAttributes(const DWARFDIE &die, // are not sane, remove them. If we don't do this then we will end up // with a crash if we try to use this type in an expression when clang // becomes unhappy with its recycled debug info. - if (byte_size.getValueOr(0) == 0 && bit_offset < 0) { + if (byte_size.value_or(0) == 0 && bit_offset < 0) { bit_size = 0; bit_offset = 0; } @@ -2667,8 +2614,10 @@ void DWARFASTParserClang::ParseSingleMember( if (class_is_objc_object_or_interface) attrs.accessibility = eAccessNone; - // Handle static members - if (attrs.is_external && attrs.member_byte_offset == UINT32_MAX) { + // Handle static members, which is any member that doesn't have a bit or a + // byte member offset. + if (attrs.member_byte_offset == UINT32_MAX && + attrs.data_bit_offset == UINT64_MAX) { Type *var_type = die.ResolveTypeUID(attrs.encoding_form.Reference()); if (var_type) { @@ -2720,7 +2669,7 @@ void DWARFASTParserClang::ParseSingleMember( ObjectFile *objfile = die.GetDWARF()->GetObjectFile(); if (objfile->GetByteOrder() == eByteOrderLittle) { - this_field_info.bit_offset += attrs.byte_size.getValueOr(0) * 8; + this_field_info.bit_offset += attrs.byte_size.value_or(0) * 8; this_field_info.bit_offset -= (attrs.bit_offset + attrs.bit_size); } else { this_field_info.bit_offset += attrs.bit_offset; @@ -3057,99 +3006,6 @@ size_t DWARFASTParserClang::ParseChildParameters( return arg_idx; } -llvm::Optional<SymbolFile::ArrayInfo> -DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die, - const ExecutionContext *exe_ctx) { - SymbolFile::ArrayInfo array_info; - if (!parent_die) - return llvm::None; - - for (DWARFDIE die : parent_die.children()) { - const dw_tag_t tag = die.Tag(); - if (tag != DW_TAG_subrange_type) - continue; - - DWARFAttributes attributes; - const size_t num_child_attributes = die.GetAttributes(attributes); - if (num_child_attributes > 0) { - uint64_t num_elements = 0; - uint64_t lower_bound = 0; - uint64_t upper_bound = 0; - bool upper_bound_valid = false; - uint32_t i; - for (i = 0; i < num_child_attributes; ++i) { - const dw_attr_t attr = attributes.AttributeAtIndex(i); - DWARFFormValue form_value; - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attr) { - case DW_AT_name: - break; - - case DW_AT_count: - if (DWARFDIE var_die = die.GetReferencedDIE(DW_AT_count)) { - if (var_die.Tag() == DW_TAG_variable) - if (exe_ctx) { - if (auto frame = exe_ctx->GetFrameSP()) { - Status error; - lldb::VariableSP var_sp; - auto valobj_sp = frame->GetValueForVariableExpressionPath( - var_die.GetName(), eNoDynamicValues, 0, var_sp, - error); - if (valobj_sp) { - num_elements = valobj_sp->GetValueAsUnsigned(0); - break; - } - } - } - } else - num_elements = form_value.Unsigned(); - break; - - case DW_AT_bit_stride: - array_info.bit_stride = form_value.Unsigned(); - break; - - case DW_AT_byte_stride: - array_info.byte_stride = form_value.Unsigned(); - break; - - case DW_AT_lower_bound: - lower_bound = form_value.Unsigned(); - break; - - case DW_AT_upper_bound: - upper_bound_valid = true; - upper_bound = form_value.Unsigned(); - break; - - default: - case DW_AT_abstract_origin: - case DW_AT_accessibility: - case DW_AT_allocated: - case DW_AT_associated: - case DW_AT_data_location: - case DW_AT_declaration: - case DW_AT_description: - case DW_AT_sibling: - case DW_AT_threads_scaled: - case DW_AT_type: - case DW_AT_visibility: - break; - } - } - } - - if (num_elements == 0) { - if (upper_bound_valid && upper_bound >= lower_bound) - num_elements = upper_bound - lower_bound + 1; - } - - array_info.element_orders.push_back(num_elements); - } - } - return array_info; -} - Type *DWARFASTParserClang::GetTypeForDIE(const DWARFDIE &die) { if (die) { SymbolFileDWARF *dwarf = die.GetDWARF(); @@ -3498,49 +3354,37 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes( // in "dst_cu" and "dst_class_die" class_type->GetFullCompilerType(); - DWARFDIE src_die; - DWARFDIE dst_die; + auto gather = [](DWARFDIE die, UniqueCStringMap<DWARFDIE> &map, + UniqueCStringMap<DWARFDIE> &map_artificial) { + if (die.Tag() != DW_TAG_subprogram) + return; + // Make sure this is a declaration and not a concrete instance by looking + // for DW_AT_declaration set to 1. Sometimes concrete function instances are + // placed inside the class definitions and shouldn't be included in the list + // of things are are tracking here. + if (die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) != 1) + return; + + if (const char *name = die.GetMangledName()) { + ConstString const_name(name); + if (die.GetAttributeValueAsUnsigned(DW_AT_artificial, 0)) + map_artificial.Append(const_name, die); + else + map.Append(const_name, die); + } + }; + UniqueCStringMap<DWARFDIE> src_name_to_die; 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(); + for (DWARFDIE src_die = src_class_die.GetFirstChild(); src_die.IsValid(); src_die = src_die.GetSibling()) { - 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 - // are placed inside the class definitions and shouldn't be included in - // the list of things are are tracking here. - if (src_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 1) { - const char *src_name = src_die.GetMangledName(); - if (src_name) { - ConstString src_const_name(src_name); - if (src_die.GetAttributeValueAsUnsigned(DW_AT_artificial, 0)) - src_name_to_die_artificial.Append(src_const_name, src_die); - else - src_name_to_die.Append(src_const_name, src_die); - } - } - } + gather(src_die, src_name_to_die, src_name_to_die_artificial); } - for (dst_die = dst_class_die.GetFirstChild(); dst_die.IsValid(); + for (DWARFDIE dst_die = dst_class_die.GetFirstChild(); dst_die.IsValid(); dst_die = dst_die.GetSibling()) { - 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 - // are placed inside the class definitions and shouldn't be included in - // the list of things are are tracking here. - if (dst_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 1) { - const char *dst_name = dst_die.GetMangledName(); - if (dst_name) { - ConstString dst_const_name(dst_name); - if (dst_die.GetAttributeValueAsUnsigned(DW_AT_artificial, 0)) - dst_name_to_die_artificial.Append(dst_const_name, dst_die); - else - dst_name_to_die.Append(dst_const_name, dst_die); - } - } - } + gather(dst_die, dst_name_to_die, dst_name_to_die_artificial); } const uint32_t src_size = src_name_to_die.GetSize(); const uint32_t dst_size = dst_name_to_die.GetSize(); @@ -3555,8 +3399,8 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes( if (fast_path) { for (idx = 0; idx < src_size; ++idx) { - src_die = src_name_to_die.GetValueAtIndexUnchecked(idx); - dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx); + DWARFDIE src_die = src_name_to_die.GetValueAtIndexUnchecked(idx); + DWARFDIE dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx); if (src_die.Tag() != dst_die.Tag()) fast_path = false; @@ -3574,28 +3418,29 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes( DWARFASTParserClang *src_dwarf_ast_parser = static_cast<DWARFASTParserClang *>( - SymbolFileDWARF::GetDWARFParser(*src_die.GetCU())); + SymbolFileDWARF::GetDWARFParser(*src_class_die.GetCU())); DWARFASTParserClang *dst_dwarf_ast_parser = static_cast<DWARFASTParserClang *>( - SymbolFileDWARF::GetDWARFParser(*dst_die.GetCU())); + SymbolFileDWARF::GetDWARFParser(*dst_class_die.GetCU())); + auto link = [&](DWARFDIE src, DWARFDIE dst) { + SymbolFileDWARF::DIEToTypePtr &die_to_type = + dst_class_die.GetDWARF()->GetDIEToType(); + clang::DeclContext *dst_decl_ctx = + dst_dwarf_ast_parser->m_die_to_decl_ctx[dst.GetDIE()]; + if (dst_decl_ctx) + src_dwarf_ast_parser->LinkDeclContextToDIE(dst_decl_ctx, src); + + if (Type *src_child_type = die_to_type[src.GetDIE()]) + die_to_type[dst.GetDIE()] = src_child_type; + }; // Now do the work of linking the DeclContexts and Types. if (fast_path) { // We can do this quickly. Just run across the tables index-for-index // since we know each node has matching names and tags. for (idx = 0; idx < src_size; ++idx) { - src_die = src_name_to_die.GetValueAtIndexUnchecked(idx); - dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx); - - clang::DeclContext *src_decl_ctx = - src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()]; - if (src_decl_ctx) - dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, dst_die); - - Type *src_child_type = - dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()]; - if (src_child_type) - dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type; + link(src_name_to_die.GetValueAtIndexUnchecked(idx), + dst_name_to_die.GetValueAtIndexUnchecked(idx)); } } else { // We must do this slowly. For each member of the destination, look up a @@ -3607,24 +3452,13 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes( for (idx = 0; idx < dst_size; ++idx) { ConstString dst_name = dst_name_to_die.GetCStringAtIndex(idx); - dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx); - src_die = src_name_to_die.Find(dst_name, DWARFDIE()); - - if (src_die && (src_die.Tag() == dst_die.Tag())) { - clang::DeclContext *src_decl_ctx = - src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()]; - if (src_decl_ctx) - dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, dst_die); - - Type *src_child_type = - dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()]; - if (src_child_type) { - dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = - src_child_type; - } - } else { + DWARFDIE dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx); + DWARFDIE src_die = src_name_to_die.Find(dst_name, DWARFDIE()); + + if (src_die && (src_die.Tag() == dst_die.Tag())) + link(src_die, dst_die); + else failures.push_back(dst_die); - } } } } @@ -3638,29 +3472,21 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes( for (idx = 0; idx < src_size_artificial; ++idx) { ConstString src_name_artificial = src_name_to_die_artificial.GetCStringAtIndex(idx); - src_die = src_name_to_die_artificial.GetValueAtIndexUnchecked(idx); - dst_die = + DWARFDIE src_die = + src_name_to_die_artificial.GetValueAtIndexUnchecked(idx); + DWARFDIE dst_die = dst_name_to_die_artificial.Find(src_name_artificial, DWARFDIE()); - if (dst_die) { - // Both classes have the artificial types, link them - clang::DeclContext *src_decl_ctx = - src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()]; - if (src_decl_ctx) - dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, dst_die); - - Type *src_child_type = - dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()]; - if (src_child_type) - dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type; - } + // Both classes have the artificial types, link them + if (dst_die) + link(src_die, dst_die); } } if (dst_size_artificial) { for (idx = 0; idx < dst_size_artificial; ++idx) { - dst_die = dst_name_to_die_artificial.GetValueAtIndexUnchecked(idx); - failures.push_back(dst_die); + failures.push_back( + dst_name_to_die_artificial.GetValueAtIndexUnchecked(idx)); } } 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 2f6b36c79b80..62d75c69afa8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp @@ -16,13 +16,13 @@ #include "DWARFFormValue.h" using namespace lldb_private; +using namespace lldb_private::dwarf; DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() : m_attributes() {} DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration(dw_tag_t tag, uint8_t has_children) - : m_code(InvalidCode), m_tag(tag), m_has_children(has_children), - m_attributes() {} + : m_tag(tag), m_has_children(has_children), m_attributes() {} llvm::Expected<DWARFEnumState> DWARFAbbreviationDeclaration::extract(const DWARFDataExtractor &data, 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 134f6b2bd114..00b56537ae2b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp @@ -10,6 +10,8 @@ #include "DWARFUnit.h" #include "DWARFDebugInfo.h" +using namespace lldb_private::dwarf; + DWARFAttributes::DWARFAttributes() : m_infos() {} DWARFAttributes::~DWARFAttributes() = default; 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 529007e31b9e..ec074be581b5 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp @@ -15,6 +15,7 @@ #include "DWARFUnit.h" using namespace lldb_private; +using namespace lldb_private::dwarf; namespace { diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp index 0f0f50a645db..d890288cdf56 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp @@ -12,7 +12,6 @@ using namespace lldb; using namespace lldb_private; -using namespace std; // DWARFAbbreviationDeclarationSet::Clear() void DWARFAbbreviationDeclarationSet::Clear() { 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 b72c7406ece1..8933b0804a01 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp @@ -27,7 +27,6 @@ using namespace lldb; using namespace lldb_private; -using namespace std; // Constructor DWARFDebugInfo::DWARFDebugInfo(SymbolFileDWARF &dwarf, 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 39915aa889ff..95c0cb6472c5 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -31,7 +31,7 @@ #include "SymbolFileDWARFDwo.h" using namespace lldb_private; -using namespace std; +using namespace lldb_private::dwarf; extern int g_verbose; // Extract a debug info entry for a given DWARFUnit from the data diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp index 278950a9f336..19c6448c4e74 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp @@ -14,6 +14,7 @@ #include "DWARFDataExtractor.h" using namespace lldb_private; +using namespace lldb_private::dwarf; DWARFDebugMacroHeader DWARFDebugMacroHeader::ParseHeader(const DWARFDataExtractor &debug_macro_data, diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h index 5c0338e950eb..cbf762458331 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h @@ -43,9 +43,9 @@ private: SkipOperandTable(const lldb_private::DWARFDataExtractor &debug_macro_data, lldb::offset_t *offset); - uint16_t m_version; - bool m_offset_is_64_bit; - uint64_t m_debug_line_offset; + uint16_t m_version = 0; + bool m_offset_is_64_bit = false; + uint64_t m_debug_line_offset = 0; }; class DWARFDebugMacroEntry { diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp index f4c8c14cc8af..393de0038e65 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp @@ -8,6 +8,8 @@ #include "DWARFDeclContext.h" +using namespace lldb_private::dwarf; + const char *DWARFDeclContext::GetQualifiedName() const { if (m_qualified_name.empty()) { // The declaration context array for a class named "foo" in namespace 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 4c498705da45..08b241683776 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp @@ -20,6 +20,7 @@ class DWARFUnit; using namespace lldb_private; +using namespace lldb_private::dwarf; void DWARFFormValue::Clear() { m_unit = nullptr; diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp index 6707d471e09b..5131584f5522 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp @@ -68,7 +68,8 @@ DWARFIndex::DIERefCallbackImpl::DIERefCallbackImpl( const DWARFIndex &index, llvm::function_ref<bool(DWARFDIE die)> callback, llvm::StringRef name) : m_index(index), - m_dwarf(*llvm::cast<SymbolFileDWARF>(index.m_module.GetSymbolFile())), + m_dwarf(*llvm::cast<SymbolFileDWARF>( + index.m_module.GetSymbolFile()->GetBackingSymbolFile())), m_callback(callback), m_name(name) {} bool DWARFIndex::DIERefCallbackImpl::operator()(DIERef ref) const { 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 5487f709d223..903cd2e38f76 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -13,6 +13,7 @@ #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timer.h" +#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h" #include "llvm/Object/Error.h" #include "DWARFCompileUnit.h" @@ -24,7 +25,7 @@ using namespace lldb; using namespace lldb_private; -using namespace std; +using namespace lldb_private::dwarf; extern int g_verbose; @@ -447,7 +448,7 @@ ParseListTableHeader(const llvm::DWARFDataExtractor &data, uint64_t offset, uint64_t HeaderSize = llvm::DWARFListTableHeader::getHeaderSize(format); if (offset < HeaderSize) - return llvm::createStringError(errc::invalid_argument, + return llvm::createStringError(std::errc::invalid_argument, "did not detect a valid" " list table with base = 0x%" PRIx64 "\n", offset); @@ -557,10 +558,10 @@ DWARFUnit::GetRnglistTable() { // 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, + return llvm::createStringError(std::errc::invalid_argument, "missing or invalid range list table"); if (!m_ranges_base) - return llvm::createStringError(errc::invalid_argument, + return llvm::createStringError(std::errc::invalid_argument, "DW_FORM_rnglistx cannot be used without " "DW_AT_rnglists_base for CU at 0x%8.8x", GetOffset()); @@ -568,7 +569,7 @@ llvm::Expected<uint64_t> DWARFUnit::GetRnglistOffset(uint32_t Index) { GetRnglistData().GetAsLLVM(), Index)) return *off + m_ranges_base; return llvm::createStringError( - errc::invalid_argument, + std::errc::invalid_argument, "invalid range list table index %u; OffsetEntryCount is %u, " "DW_AT_rnglists_base is %" PRIu64, Index, GetRnglistTable()->getOffsetEntryCount(), m_ranges_base); @@ -771,7 +772,8 @@ removeHostnameFromPathname(llvm::StringRef path_from_dwarf) { // check whether we have a windows path, and so the first character is a // drive-letter not a hostname. - if (host.size() == 1 && llvm::isAlpha(host[0]) && path.startswith("\\")) + if (host.size() == 1 && llvm::isAlpha(host[0]) && + (path.startswith("\\") || path.startswith("/"))) return path_from_dwarf; return path; @@ -787,7 +789,7 @@ void DWARFUnit::ComputeCompDirAndGuessPathStyle() { die->GetAttributeValueAsString(this, DW_AT_comp_dir, nullptr)); if (!comp_dir.empty()) { FileSpec::Style comp_dir_style = - FileSpec::GuessPathStyle(comp_dir).getValueOr(FileSpec::Style::native); + FileSpec::GuessPathStyle(comp_dir).value_or(FileSpec::Style::native); m_comp_dir = FileSpec(comp_dir, comp_dir_style); } else { // Try to detect the style based on the DW_AT_name attribute, but just store @@ -795,7 +797,7 @@ void DWARFUnit::ComputeCompDirAndGuessPathStyle() { const char *name = die->GetAttributeValueAsString(this, DW_AT_name, nullptr); m_comp_dir = FileSpec( - "", FileSpec::GuessPathStyle(name).getValueOr(FileSpec::Style::native)); + "", FileSpec::GuessPathStyle(name).value_or(FileSpec::Style::native)); } } @@ -863,14 +865,24 @@ DWARFUnitHeader::extract(const DWARFDataExtractor &data, section == DIERef::Section::DebugTypes ? DW_UT_type : DW_UT_compile; } + if (header.IsTypeUnit()) { + header.m_type_hash = data.GetU64(offset_ptr); + header.m_type_offset = data.GetDWARFOffset(offset_ptr); + } + if (context.isDwo()) { + const llvm::DWARFUnitIndex *Index; if (header.IsTypeUnit()) { - header.m_index_entry = - context.GetAsLLVM().getTUIndex().getFromOffset(header.m_offset); + Index = &context.GetAsLLVM().getTUIndex(); + if (*Index) + header.m_index_entry = Index->getFromHash(header.m_type_hash); } else { - header.m_index_entry = - context.GetAsLLVM().getCUIndex().getFromOffset(header.m_offset); + Index = &context.GetAsLLVM().getCUIndex(); + if (*Index && header.m_version >= 5) + header.m_index_entry = Index->getFromHash(header.m_dwo_id); } + if (!header.m_index_entry) + header.m_index_entry = Index->getFromOffset(header.m_offset); } if (header.m_index_entry) { @@ -893,10 +905,6 @@ DWARFUnitHeader::extract(const DWARFDataExtractor &data, } header.m_abbr_offset = abbr_entry->Offset; } - if (header.IsTypeUnit()) { - header.m_type_hash = data.GetU64(offset_ptr); - header.m_type_offset = data.GetDWARFOffset(offset_ptr); - } bool length_OK = data.ValidOffset(header.GetNextUnitOffset() - 1); bool version_OK = SymbolFileDWARF::SupportedVersion(header.m_version); @@ -997,7 +1005,7 @@ DWARFUnit::FindRnglistFromOffset(dw_offset_t offset) { } if (!GetRnglistTable()) - return llvm::createStringError(errc::invalid_argument, + return llvm::createStringError(std::errc::invalid_argument, "missing or invalid range list table"); llvm::DWARFDataExtractor data = GetRnglistData().GetAsLLVM(); 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 2457e8276e20..265e28b51c99 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -11,8 +11,9 @@ #include "DWARFDIE.h" #include "DWARFDebugInfoEntry.h" -#include "lldb/lldb-enumerations.h" #include "lldb/Utility/XcodeSDK.h" +#include "lldb/lldb-enumerations.h" +#include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h" #include "llvm/Support/RWMutex.h" #include <atomic> @@ -68,7 +69,8 @@ public: dw_offset_t GetTypeOffset() const { return m_type_offset; } uint64_t GetDWOId() const { return m_dwo_id; } bool IsTypeUnit() const { - return m_unit_type == DW_UT_type || m_unit_type == DW_UT_split_type; + return m_unit_type == llvm::dwarf::DW_UT_type || + m_unit_type == llvm::dwarf::DW_UT_split_type; } uint32_t GetNextUnitOffset() const { return m_offset + m_length + 4; } @@ -153,7 +155,7 @@ public: const DWARFAbbreviationDeclarationSet *GetAbbreviations() const; dw_offset_t GetAbbrevOffset() const; uint8_t GetAddressByteSize() const { return m_header.GetAddressByteSize(); } - dw_addr_t GetAddrBase() const { return m_addr_base.getValueOr(0); } + dw_addr_t GetAddrBase() const { return m_addr_base.value_or(0); } dw_addr_t GetBaseAddress() const { return m_base_addr; } dw_offset_t GetLineTableOffset(); dw_addr_t GetRangesBase() const { return m_ranges_base; } diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp index 2350c8fc3d5b..ad22078ffa3e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp @@ -16,6 +16,7 @@ using namespace lldb_private; using namespace lldb; +using namespace lldb_private::dwarf; llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>> DebugNamesDWARFIndex::Create(Module &module, DWARFDataExtractor debug_names, @@ -64,8 +65,8 @@ bool DebugNamesDWARFIndex::ProcessEntry( llvm::Optional<DIERef> ref = ToDIERef(entry); if (!ref) return true; - SymbolFileDWARF &dwarf = - *llvm::cast<SymbolFileDWARF>(m_module.GetSymbolFile()); + SymbolFileDWARF &dwarf = *llvm::cast<SymbolFileDWARF>( + m_module.GetSymbolFile()->GetBackingSymbolFile()); DWARFDIE die = dwarf.GetDIE(*ref); if (!die) return true; 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 ce71281db8bd..fdc24e23d16b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp @@ -9,6 +9,8 @@ #include "HashedNameToDIE.h" #include "llvm/ADT/StringRef.h" +using namespace lldb_private::dwarf; + bool DWARFMappedHash::ExtractDIEArray( const DIEInfoArray &die_info_array, llvm::function_ref<bool(DIERef ref)> callback) { diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h index aa3ed4afed25..662aa6757e2f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h @@ -10,6 +10,7 @@ #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_LOGCHANNELDWARF_H #include "lldb/Utility/Log.h" +#include "llvm/ADT/BitmaskEnum.h" namespace lldb_private { @@ -21,6 +22,7 @@ enum class DWARFLog : Log::MaskType { TypeCompletion = Log::ChannelFlag<4>, LLVM_MARK_AS_BITMASK_ENUM(TypeCompletion) }; +LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); class LogChannelDWARF { public: 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 e8fbd5dd664b..b743c84c10e0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp @@ -13,6 +13,7 @@ #include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h" #include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h" #include "lldb/Core/DataFileCache.h" +#include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" #include "lldb/Core/Progress.h" #include "lldb/Symbol/ObjectFile.h" @@ -25,6 +26,7 @@ using namespace lldb_private; using namespace lldb; +using namespace lldb_private::dwarf; void ManualDWARFIndex::Index() { if (m_indexed) @@ -93,7 +95,7 @@ void ManualDWARFIndex::Index() { // Share one thread pool across operations to avoid the overhead of // recreating the threads. - llvm::ThreadPool pool(llvm::optimal_concurrency(units_to_index.size())); + llvm::ThreadPoolTaskGroup task_group(Debugger::GetThreadPool()); // Create a task runner that extracts dies for each DWARF unit in a // separate thread. @@ -104,14 +106,14 @@ void ManualDWARFIndex::Index() { // to wait until all units have been indexed in case a DIE in one // unit refers to another and the indexes accesses those DIEs. for (size_t i = 0; i < units_to_index.size(); ++i) - pool.async(extract_fn, i); - pool.wait(); + task_group.async(extract_fn, i); + task_group.wait(); // Now create a task runner that can index each DWARF unit in a // separate thread so we can index quickly. for (size_t i = 0; i < units_to_index.size(); ++i) - pool.async(parser_fn, i); - pool.wait(); + task_group.async(parser_fn, i); + task_group.wait(); auto finalize_fn = [this, &sets, &progress](NameToDIE(IndexSet::*index)) { NameToDIE &result = m_set.*index; @@ -121,15 +123,15 @@ void ManualDWARFIndex::Index() { progress.Increment(); }; - pool.async(finalize_fn, &IndexSet::function_basenames); - pool.async(finalize_fn, &IndexSet::function_fullnames); - pool.async(finalize_fn, &IndexSet::function_methods); - pool.async(finalize_fn, &IndexSet::function_selectors); - pool.async(finalize_fn, &IndexSet::objc_class_selectors); - pool.async(finalize_fn, &IndexSet::globals); - pool.async(finalize_fn, &IndexSet::types); - pool.async(finalize_fn, &IndexSet::namespaces); - pool.wait(); + task_group.async(finalize_fn, &IndexSet::function_basenames); + task_group.async(finalize_fn, &IndexSet::function_fullnames); + task_group.async(finalize_fn, &IndexSet::function_methods); + task_group.async(finalize_fn, &IndexSet::function_selectors); + task_group.async(finalize_fn, &IndexSet::objc_class_selectors); + task_group.async(finalize_fn, &IndexSet::globals); + task_group.async(finalize_fn, &IndexSet::types); + task_group.async(finalize_fn, &IndexSet::namespaces); + task_group.wait(); SaveToCache(); } diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp index 413920f33619..de98403421e0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp @@ -100,16 +100,27 @@ bool NameToDIE::Decode(const DataExtractor &data, lldb::offset_t *offset_ptr, if (identifier != kIdentifierNameToDIE) return false; const uint32_t count = data.GetU32(offset_ptr); + m_map.Reserve(count); for (uint32_t i = 0; i < count; ++i) { llvm::StringRef str(strtab.Get(data.GetU32(offset_ptr))); // No empty strings allowed in the name to DIE maps. if (str.empty()) return false; if (llvm::Optional<DIERef> die_ref = DIERef::Decode(data, offset_ptr)) - m_map.Append(ConstString(str), die_ref.getValue()); + m_map.Append(ConstString(str), *die_ref); else return false; } + // We must sort the UniqueCStringMap after decoding it since it is a vector + // of UniqueCStringMap::Entry objects which contain a ConstString and type T. + // ConstString objects are sorted by "const char *" and then type T and + // the "const char *" are point values that will depend on the order in which + // ConstString objects are created and in which of the 256 string pools they + // are created in. So after we decode all of the entries, we must sort the + // name map to ensure name lookups succeed. If we encode and decode within + // the same process we wouldn't need to sort, so unit testing didn't catch + // this issue when first checked in. + m_map.Sort(std::less<DIERef>()); return true; } 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 027a4caf5555..c0bf13e0281d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -21,6 +21,7 @@ #include "lldb/Core/StreamFile.h" #include "lldb/Core/Value.h" #include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Scalar.h" #include "lldb/Utility/StreamString.h" @@ -95,6 +96,7 @@ using namespace lldb; using namespace lldb_private; +using namespace lldb_private::dwarf; LLDB_PLUGIN_DEFINE(SymbolFileDWARF) @@ -272,7 +274,7 @@ TypeList &SymbolFileDWARF::GetTypeList() { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile()) return debug_map_symfile->GetTypeList(); - return SymbolFile::GetTypeList(); + return SymbolFileCommon::GetTypeList(); } void SymbolFileDWARF::GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset, dw_offset_t max_die_offset, uint32_t type_mask, @@ -405,7 +407,7 @@ SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE &child_die) { SymbolFileDWARF::SymbolFileDWARF(ObjectFileSP objfile_sp, SectionList *dwo_section_list) - : SymbolFile(std::move(objfile_sp)), + : SymbolFileCommon(std::move(objfile_sp)), UserID(0x7fffffff00000000), // Used by SymbolFileDWARFDebugMap to // when this class parses .o files to // contain the .o file index/ID @@ -564,23 +566,21 @@ uint32_t SymbolFileDWARF::CalculateAbilities() { if (section) debug_line_file_size = section->GetFileSize(); } else { - const char *symfile_dir_cstr = - m_objfile_sp->GetFileSpec().GetDirectory().GetCString(); - if (symfile_dir_cstr) { - if (strcasestr(symfile_dir_cstr, ".dsym")) { - if (m_objfile_sp->GetType() == ObjectFile::eTypeDebugInfo) { - // We have a dSYM file that didn't have a any debug info. If the - // string table has a size of 1, then it was made from an - // executable with no debug info, or from an executable that was - // stripped. - section = - section_list->FindSectionByType(eSectionTypeDWARFDebugStr, true) - .get(); - if (section && section->GetFileSize() == 1) { - m_objfile_sp->GetModule()->ReportWarning( - "empty dSYM file detected, dSYM was created with an " - "executable with no debug info."); - } + llvm::StringRef symfile_dir = + m_objfile_sp->GetFileSpec().GetDirectory().GetStringRef(); + if (symfile_dir.contains_insensitive(".dsym")) { + if (m_objfile_sp->GetType() == ObjectFile::eTypeDebugInfo) { + // We have a dSYM file that didn't have a any debug info. If the + // string table has a size of 1, then it was made from an + // executable with no debug info, or from an executable that was + // stripped. + section = + section_list->FindSectionByType(eSectionTypeDWARFDebugStr, true) + .get(); + if (section && section->GetFileSize() == 1) { + m_objfile_sp->GetModule()->ReportWarning( + "empty dSYM file detected, dSYM was created with an " + "executable with no debug info."); } } } @@ -825,8 +825,8 @@ Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit, auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU())); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Unable to parse function"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Unable to parse function"); return nullptr; } DWARFASTParser *dwarf_ast = type_system_or_err->GetDWARFParser(); @@ -1371,9 +1371,9 @@ user_id_t SymbolFileDWARF::GetUID(DIERef ref) { if (GetDebugMapSymfile()) return GetID() | ref.die_offset(); - lldbassert(GetDwoNum().getValueOr(0) <= 0x3fffffff); - return user_id_t(GetDwoNum().getValueOr(0)) << 32 | ref.die_offset() | - lldb::user_id_t(GetDwoNum().hasValue()) << 62 | + lldbassert(GetDwoNum().value_or(0) <= 0x3fffffff); + return user_id_t(GetDwoNum().value_or(0)) << 32 | ref.die_offset() | + lldb::user_id_t(GetDwoNum().has_value()) << 62 | lldb::user_id_t(ref.section() == DIERef::Section::DebugTypes) << 63; } @@ -1744,8 +1744,14 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit( dwo_file.AppendPathComponent(dwo_name); } - if (!FileSystem::Instance().Exists(dwo_file)) + if (!FileSystem::Instance().Exists(dwo_file)) { + if (m_dwo_warning_issued.test_and_set(std::memory_order_relaxed) == false) { + GetObjectFile()->GetModule()->ReportWarning( + "unable to locate separate debug file (dwo, dwp). Debugging will be " + "degraded."); + } return nullptr; + } const lldb::offset_t file_offset = 0; DataBufferSP dwo_file_data_sp; @@ -1891,7 +1897,7 @@ SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() { lldb::addr_t byte_size = 1; if (var_sp->GetType()) byte_size = - var_sp->GetType()->GetByteSize(nullptr).getValueOr(0); + var_sp->GetType()->GetByteSize(nullptr).value_or(0); m_global_aranges_up->Append(GlobalVariableMap::Entry( file_addr, byte_size, var_sp.get())); } @@ -2098,8 +2104,7 @@ bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile( auto type_system_or_err = GetTypeSystemForLanguage( decl_ctx_type_system->GetMinimumLanguage(nullptr)); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), "Unable to match namespace decl using TypeSystem"); return false; } @@ -2868,10 +2873,9 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext( if (language != eLanguageTypeUnknown) { auto type_system_or_err = GetTypeSystemForLanguage(language); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR( - lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Cannot get TypeSystem for language {}", - Language::GetNameForLanguageType(language)); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Cannot get TypeSystem for language {}", + Language::GetNameForLanguageType(language)); } else { type_system = &type_system_or_err.get(); } @@ -2967,8 +2971,8 @@ TypeSP SymbolFileDWARF::ParseType(const SymbolContext &sc, const DWARFDIE &die, auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU())); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Unable to parse type"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Unable to parse type"); return {}; } @@ -3240,7 +3244,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, DataExtractor data = die.GetCU()->GetLocationData(); dw_offset_t offset = location_form.Unsigned(); if (location_form.Form() == DW_FORM_loclistx) - offset = die.GetCU()->GetLoclistOffset(offset).getValueOr(-1); + offset = die.GetCU()->GetLoclistOffset(offset).value_or(-1); if (data.ValidOffset(offset)) { data = DataExtractor(data, offset, data.GetByteSize() - offset); location = DWARFExpression(module, data, die.GetCU()); @@ -3461,7 +3465,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, if (use_type_size_for_value && type_sp->GetType()) location.UpdateValue(const_value_form.Unsigned(), - type_sp->GetType()->GetByteSize(nullptr).getValueOr(0), + type_sp->GetType()->GetByteSize(nullptr).value_or(0), die.GetCU()->GetAddressByteSize()); return std::make_shared<Variable>( @@ -3801,7 +3805,7 @@ SymbolFileDWARF::CollectCallEdges(ModuleSP module, DWARFDIE function_die) { if (!has_call_edges) return {}; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); LLDB_LOG(log, "CollectCallEdges: Found call site info in {0}", function_die.GetPubname()); @@ -3924,7 +3928,7 @@ SymbolFileDWARF::CollectCallEdges(ModuleSP module, DWARFDIE function_die) { if (log) { StreamString call_target_desc; call_target->GetDescription(&call_target_desc, eDescriptionLevelBrief, - LLDB_INVALID_ADDRESS, nullptr); + nullptr); LLDB_LOG(log, "CollectCallEdges: Found indirect call target: {0}", call_target_desc.GetString()); } @@ -3937,11 +3941,9 @@ SymbolFileDWARF::CollectCallEdges(ModuleSP module, DWARFDIE function_die) { for (const CallSiteParameter ¶m : parameters) { StreamString callee_loc_desc, caller_loc_desc; param.LocationInCallee.GetDescription(&callee_loc_desc, - eDescriptionLevelBrief, - LLDB_INVALID_ADDRESS, nullptr); + eDescriptionLevelBrief, nullptr); param.LocationInCaller.GetDescription(&caller_loc_desc, - eDescriptionLevelBrief, - LLDB_INVALID_ADDRESS, nullptr); + eDescriptionLevelBrief, nullptr); LLDB_LOG(log, "CollectCallEdges: \tparam: {0} => {1}", callee_loc_desc.GetString(), caller_loc_desc.GetString()); } @@ -3966,7 +3968,7 @@ SymbolFileDWARF::ParseCallEdgesInFunction(UserID func_id) { } void SymbolFileDWARF::Dump(lldb_private::Stream &s) { - SymbolFile::Dump(s); + SymbolFileCommon::Dump(s); m_index->Dump(s); } @@ -3985,8 +3987,8 @@ SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() { if (m_debug_map_symfile == nullptr) { lldb::ModuleSP module_sp(m_debug_map_module_wp.lock()); if (module_sp) { - m_debug_map_symfile = - static_cast<SymbolFileDWARFDebugMap *>(module_sp->GetSymbolFile()); + m_debug_map_symfile = llvm::cast<SymbolFileDWARFDebugMap>( + module_sp->GetSymbolFile()->GetBackingSymbolFile()); } } return m_debug_map_symfile; @@ -4025,8 +4027,8 @@ llvm::Expected<TypeSystem &> SymbolFileDWARF::GetTypeSystem(DWARFUnit &unit) { DWARFASTParser *SymbolFileDWARF::GetDWARFParser(DWARFUnit &unit) { auto type_system_or_err = GetTypeSystem(unit); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Unable to get DWARFASTParser"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Unable to get DWARFASTParser"); return nullptr; } return type_system_or_err->GetDWARFParser(); 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 f84a78620e17..2403ee2624ea 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -56,7 +56,7 @@ class SymbolFileDWARFDwp; #define DIE_IS_BEING_PARSED ((lldb_private::Type *)1) -class SymbolFileDWARF : public lldb_private::SymbolFile, +class SymbolFileDWARF : public lldb_private::SymbolFileCommon, public lldb_private::UserID { /// LLVM RTTI support. static char ID; @@ -65,7 +65,7 @@ public: /// LLVM RTTI support. /// \{ bool isA(const void *ClassID) const override { - return ClassID == &ID || SymbolFile::isA(ClassID); + return ClassID == &ID || SymbolFileCommon::isA(ClassID); } static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } /// \} @@ -560,6 +560,7 @@ protected: /// address in the module. lldb::addr_t m_first_code_address = LLDB_INVALID_ADDRESS; lldb_private::StatsDuration m_parse_time; + std::atomic_flag m_dwo_warning_issued = ATOMIC_FLAG_INIT; }; #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARF_H 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 08bfe37fd92f..7637726892a0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -237,7 +237,7 @@ SymbolFile *SymbolFileDWARFDebugMap::CreateInstance(ObjectFileSP objfile_sp) { } SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap(ObjectFileSP objfile_sp) - : SymbolFile(std::move(objfile_sp)), m_flags(), m_compile_unit_infos(), + : SymbolFileCommon(std::move(objfile_sp)), m_flags(), m_compile_unit_infos(), m_func_indexes(), m_glob_indexes(), m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {} @@ -409,7 +409,6 @@ Module *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo( FileSpec oso_file(oso_path); ConstString oso_object; if (FileSystem::Instance().Exists(oso_file)) { - FileSystem::Instance().Collect(oso_file); // The modification time returned by the FS can have a higher precision // than the one from the CU. auto oso_mod_time = std::chrono::time_point_cast<std::chrono::seconds>( @@ -1185,25 +1184,13 @@ void SymbolFileDWARFDebugMap::FindTypes( llvm::ArrayRef<CompilerContext> context, LanguageSet languages, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, TypeMap &types) { + LLDB_SCOPED_TIMER(); ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { oso_dwarf->FindTypes(context, languages, searched_symbol_files, types); return false; }); } -// -// uint32_t -// SymbolFileDWARFDebugMap::FindTypes (const SymbolContext& sc, const -// RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding -// encoding, lldb::user_id_t udt_uid, TypeList& types) -//{ -// SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); -// if (oso_dwarf) -// return oso_dwarf->FindTypes (sc, regex, append, max_matches, encoding, -// udt_uid, types); -// return 0; -//} - CompilerDeclContext SymbolFileDWARFDebugMap::FindNamespace( lldb_private::ConstString name, const CompilerDeclContext &parent_decl_ctx) { @@ -1430,53 +1417,16 @@ SymbolFileDWARFDebugMap::AddOSOARanges(SymbolFileDWARF *dwarf2Data, return num_line_entries_added; } -uint64_t SymbolFileDWARFDebugMap::GetDebugInfoSize() { - uint64_t debug_info_size = 0; - ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { - ObjectFile *oso_objfile = oso_dwarf->GetObjectFile(); - if (!oso_objfile) - return false; // Keep iterating - ModuleSP module_sp = oso_objfile->GetModule(); - if (!module_sp) - return false; // Keep iterating - SectionList *section_list = module_sp->GetSectionList(); - if (section_list) - debug_info_size += section_list->GetDebugInfoSize(); - return false; // Keep iterating - }); - return debug_info_size; -} - -StatsDuration::Duration SymbolFileDWARFDebugMap::GetDebugInfoParseTime() { - StatsDuration::Duration elapsed(0.0); +ModuleList SymbolFileDWARFDebugMap::GetDebugInfoModules() { + ModuleList oso_modules; ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { ObjectFile *oso_objfile = oso_dwarf->GetObjectFile(); if (oso_objfile) { ModuleSP module_sp = oso_objfile->GetModule(); - if (module_sp) { - SymbolFile *symfile = module_sp->GetSymbolFile(); - if (symfile) - elapsed += symfile->GetDebugInfoParseTime(); - } - } - return false; // Keep iterating - }); - return elapsed; -} - -StatsDuration::Duration SymbolFileDWARFDebugMap::GetDebugInfoIndexTime() { - StatsDuration::Duration elapsed(0.0); - ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { - ObjectFile *oso_objfile = oso_dwarf->GetObjectFile(); - if (oso_objfile) { - ModuleSP module_sp = oso_objfile->GetModule(); - if (module_sp) { - SymbolFile *symfile = module_sp->GetSymbolFile(); - if (symfile) - elapsed += symfile->GetDebugInfoIndexTime(); - } + if (module_sp) + oso_modules.Append(module_sp); } return false; // Keep iterating }); - return elapsed; + return oso_modules; } 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 2a6232a501b4..52c4d77a10b6 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -22,7 +22,7 @@ class SymbolFileDWARF; class DWARFDebugAranges; class DWARFDeclContext; -class SymbolFileDWARFDebugMap : public lldb_private::SymbolFile { +class SymbolFileDWARFDebugMap : public lldb_private::SymbolFileCommon { /// LLVM RTTI support. static char ID; @@ -30,7 +30,7 @@ public: /// LLVM RTTI support. /// \{ bool isA(const void *ClassID) const override { - return ClassID == &ID || SymbolFile::isA(ClassID); + return ClassID == &ID || SymbolFileCommon::isA(ClassID); } static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } /// \} @@ -142,9 +142,8 @@ public: // PluginInterface protocol llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } - uint64_t GetDebugInfoSize() override; - lldb_private::StatsDuration::Duration GetDebugInfoParseTime() override; - lldb_private::StatsDuration::Duration GetDebugInfoIndexTime() override; + // Statistics overrides. + lldb_private::ModuleList GetDebugInfoModules() override; protected: enum { kHaveInitializedOSOs = (1 << 0), kNumFlags }; 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 34ff23667465..22a921cf6138 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp @@ -10,6 +10,8 @@ #include "lldb/Core/Declaration.h" +using namespace lldb_private::dwarf; + bool UniqueDWARFASTTypeList::Find(const DWARFDIE &die, const lldb_private::Declaration &decl, const int32_t byte_size, diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp index ca9ddcec287f..3d8030916c84 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp @@ -10,10 +10,196 @@ #include "lldb/lldb-defines.h" +#include "Plugins/Process/Utility/lldb-arm64-register-enums.h" #include "Plugins/Process/Utility/lldb-x86-register-enums.h" using namespace lldb_private; +static const uint32_t g_code_view_to_lldb_registers_arm64[] = { + LLDB_INVALID_REGNUM, // NONE + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_w0_arm64, // ARM64_W0, 10) + gpr_w1_arm64, // ARM64_W1, 11) + gpr_w2_arm64, // ARM64_W2, 12) + gpr_w3_arm64, // ARM64_W3, 13) + gpr_w4_arm64, // ARM64_W4, 14) + gpr_w5_arm64, // ARM64_W5, 15) + gpr_w6_arm64, // ARM64_W6, 16) + gpr_w7_arm64, // ARM64_W7, 17) + gpr_w8_arm64, // ARM64_W8, 18) + gpr_w9_arm64, // ARM64_W9, 19) + gpr_w10_arm64, // ARM64_W10, 20) + gpr_w11_arm64, // ARM64_W11, 21) + gpr_w12_arm64, // ARM64_W12, 22) + gpr_w13_arm64, // ARM64_W13, 23) + gpr_w14_arm64, // ARM64_W14, 24) + gpr_w15_arm64, // ARM64_W15, 25) + gpr_w16_arm64, // ARM64_W16, 26) + gpr_w17_arm64, // ARM64_W17, 27) + gpr_w18_arm64, // ARM64_W18, 28) + gpr_w19_arm64, // ARM64_W19, 29) + gpr_w20_arm64, // ARM64_W20, 30) + gpr_w21_arm64, // ARM64_W21, 31) + gpr_w22_arm64, // ARM64_W22, 32) + gpr_w23_arm64, // ARM64_W23, 33) + gpr_w24_arm64, // ARM64_W24, 34) + gpr_w25_arm64, // ARM64_W25, 35) + gpr_w26_arm64, // ARM64_W26, 36) + gpr_w27_arm64, // ARM64_W27, 37) + gpr_w28_arm64, // ARM64_W28, 38) + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_x0_arm64, // ARM64_X0, 50) + gpr_x1_arm64, // ARM64_X1, 51) + gpr_x2_arm64, // ARM64_X2, 52) + gpr_x3_arm64, // ARM64_X3, 53) + gpr_x4_arm64, // ARM64_X4, 54) + gpr_x5_arm64, // ARM64_X5, 55) + gpr_x6_arm64, // ARM64_X6, 56) + gpr_x7_arm64, // ARM64_X7, 57) + gpr_x8_arm64, // ARM64_X8, 58) + gpr_x9_arm64, // ARM64_X9, 59) + gpr_x10_arm64, // ARM64_X10, 60) + gpr_x11_arm64, // ARM64_X11, 61) + gpr_x12_arm64, // ARM64_X12, 62) + gpr_x13_arm64, // ARM64_X13, 63) + gpr_x14_arm64, // ARM64_X14, 64) + gpr_x15_arm64, // ARM64_X15, 65) + gpr_x16_arm64, // ARM64_X16, 66) + gpr_x17_arm64, // ARM64_X17, 67) + gpr_x18_arm64, // ARM64_X18, 68) + gpr_x19_arm64, // ARM64_X19, 69) + gpr_x20_arm64, // ARM64_X20, 70) + gpr_x21_arm64, // ARM64_X21, 71) + gpr_x22_arm64, // ARM64_X22, 72) + gpr_x23_arm64, // ARM64_X23, 73) + gpr_x24_arm64, // ARM64_X24, 74) + gpr_x25_arm64, // ARM64_X25, 75) + gpr_x26_arm64, // ARM64_X26, 76) + gpr_x27_arm64, // ARM64_X27, 77) + gpr_x28_arm64, // ARM64_X28, 78) + gpr_fp_arm64, // ARM64_FP, 79) + gpr_lr_arm64, // ARM64_LR, 80) + gpr_sp_arm64, // ARM64_SP, 81) + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_cpsr_arm64, // ARM64_NZCV, 90) + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s0_arm64, // (ARM64_S0, 100) + fpu_s1_arm64, // (ARM64_S1, 101) + fpu_s2_arm64, // (ARM64_S2, 102) + fpu_s3_arm64, // (ARM64_S3, 103) + fpu_s4_arm64, // (ARM64_S4, 104) + fpu_s5_arm64, // (ARM64_S5, 105) + fpu_s6_arm64, // (ARM64_S6, 106) + fpu_s7_arm64, // (ARM64_S7, 107) + fpu_s8_arm64, // (ARM64_S8, 108) + fpu_s9_arm64, // (ARM64_S9, 109) + fpu_s10_arm64, // (ARM64_S10, 110) + fpu_s11_arm64, // (ARM64_S11, 111) + fpu_s12_arm64, // (ARM64_S12, 112) + fpu_s13_arm64, // (ARM64_S13, 113) + fpu_s14_arm64, // (ARM64_S14, 114) + fpu_s15_arm64, // (ARM64_S15, 115) + fpu_s16_arm64, // (ARM64_S16, 116) + fpu_s17_arm64, // (ARM64_S17, 117) + fpu_s18_arm64, // (ARM64_S18, 118) + fpu_s19_arm64, // (ARM64_S19, 119) + fpu_s20_arm64, // (ARM64_S20, 120) + fpu_s21_arm64, // (ARM64_S21, 121) + fpu_s22_arm64, // (ARM64_S22, 122) + fpu_s23_arm64, // (ARM64_S23, 123) + fpu_s24_arm64, // (ARM64_S24, 124) + fpu_s25_arm64, // (ARM64_S25, 125) + fpu_s26_arm64, // (ARM64_S26, 126) + fpu_s27_arm64, // (ARM64_S27, 127) + fpu_s28_arm64, // (ARM64_S28, 128) + fpu_s29_arm64, // (ARM64_S29, 129) + fpu_s30_arm64, // (ARM64_S30, 130) + fpu_s31_arm64, // (ARM64_S31, 131) + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_d0_arm64, // (ARM64_D0, 140) + fpu_d1_arm64, // (ARM64_D1, 141) + fpu_d2_arm64, // (ARM64_D2, 142) + fpu_d3_arm64, // (ARM64_D3, 143) + fpu_d4_arm64, // (ARM64_D4, 144) + fpu_d5_arm64, // (ARM64_D5, 145) + fpu_d6_arm64, // (ARM64_D6, 146) + fpu_d7_arm64, // (ARM64_D7, 147) + fpu_d8_arm64, // (ARM64_D8, 148) + fpu_d9_arm64, // (ARM64_D9, 149) + fpu_d10_arm64, // (ARM64_D10, 150) + fpu_d11_arm64, // (ARM64_D11, 151) + fpu_d12_arm64, // (ARM64_D12, 152) + fpu_d13_arm64, // (ARM64_D13, 153) + fpu_d14_arm64, // (ARM64_D14, 154) + fpu_d15_arm64, // (ARM64_D15, 155) + fpu_d16_arm64, // (ARM64_D16, 156) + fpu_d17_arm64, // (ARM64_D17, 157) + fpu_d18_arm64, // (ARM64_D18, 158) + fpu_d19_arm64, // (ARM64_D19, 159) + fpu_d20_arm64, // (ARM64_D20, 160) + fpu_d21_arm64, // (ARM64_D21, 161) + fpu_d22_arm64, // (ARM64_D22, 162) + fpu_d23_arm64, // (ARM64_D23, 163) + fpu_d24_arm64, // (ARM64_D24, 164) + fpu_d25_arm64, // (ARM64_D25, 165) + fpu_d26_arm64, // (ARM64_D26, 166) + fpu_d27_arm64, // (ARM64_D27, 167) + fpu_d28_arm64, // (ARM64_D28, 168) + fpu_d29_arm64, // (ARM64_D29, 169) + fpu_d30_arm64, // (ARM64_D30, 170) + fpu_d31_arm64, // (ARM64_D31, 171) + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_v0_arm64, // (ARM64_Q0, 180) + fpu_v1_arm64, // (ARM64_Q1, 181) + fpu_v2_arm64, // (ARM64_Q2, 182) + fpu_v3_arm64, // (ARM64_Q3, 183) + fpu_v4_arm64, // (ARM64_Q4, 184) + fpu_v5_arm64, // (ARM64_Q5, 185) + fpu_v6_arm64, // (ARM64_Q6, 186) + fpu_v7_arm64, // (ARM64_Q7, 187) + fpu_v8_arm64, // (ARM64_Q8, 188) + fpu_v9_arm64, // (ARM64_Q9, 189) + fpu_v10_arm64, // (ARM64_Q10, 190) + fpu_v11_arm64, // (ARM64_Q11, 191) + fpu_v12_arm64, // (ARM64_Q12, 192) + fpu_v13_arm64, // (ARM64_Q13, 193) + fpu_v14_arm64, // (ARM64_Q14, 194) + fpu_v15_arm64, // (ARM64_Q15, 195) + fpu_v16_arm64, // (ARM64_Q16, 196) + fpu_v17_arm64, // (ARM64_Q17, 197) + fpu_v18_arm64, // (ARM64_Q18, 198) + fpu_v19_arm64, // (ARM64_Q19, 199) + fpu_v20_arm64, // (ARM64_Q20, 200) + fpu_v21_arm64, // (ARM64_Q21, 201) + fpu_v22_arm64, // (ARM64_Q22, 202) + fpu_v23_arm64, // (ARM64_Q23, 203) + fpu_v24_arm64, // (ARM64_Q24, 204) + fpu_v25_arm64, // (ARM64_Q25, 205) + fpu_v26_arm64, // (ARM64_Q26, 206) + fpu_v27_arm64, // (ARM64_Q27, 207) + fpu_v28_arm64, // (ARM64_Q28, 208) + fpu_v29_arm64, // (ARM64_Q29, 209) + fpu_v30_arm64, // (ARM64_Q30, 210) + fpu_v31_arm64, // (ARM64_Q31, 211) + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_fpsr_arm64 // ARM64_FPSR, 220) +}; + static const uint32_t g_code_view_to_lldb_registers_x86[] = { LLDB_INVALID_REGNUM, // NONE lldb_al_i386, // AL @@ -424,6 +610,14 @@ static const uint32_t g_code_view_to_lldb_registers_x86_64[] = { uint32_t lldb_private::npdb::GetLLDBRegisterNumber( llvm::Triple::ArchType arch_type, llvm::codeview::RegisterId register_id) { switch (arch_type) { + case llvm::Triple::aarch64: + if (static_cast<uint16_t>(register_id) < + sizeof(g_code_view_to_lldb_registers_arm64) / + sizeof(g_code_view_to_lldb_registers_arm64[0])) + return g_code_view_to_lldb_registers_arm64[static_cast<uint16_t>( + register_id)]; + + return LLDB_INVALID_REGNUM; case llvm::Triple::x86: if (static_cast<uint16_t>(register_id) < sizeof(g_code_view_to_lldb_registers_x86) / 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 d8f737612c25..d15c0ee99f96 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp @@ -162,7 +162,7 @@ CompilandIndexItem &CompileUnitIndex::GetOrCreateCompiland(uint16_t modi) { ParseExtendedInfo(m_index, *cci); ParseInlineeLineTableForCompileUnit(*cci); - cci->m_strings.initialize(debug_stream.getSubsectionsArray()); + cci->m_strings.initialize(cci->m_debug_stream.getSubsectionsArray()); PDBStringTable &strings = cantFail(m_index.pdb().getStringTable()); cci->m_strings.setStrings(strings.getStringTable()); diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp index d0672352a58f..3ba0079c96e6 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp @@ -250,3 +250,30 @@ DWARFExpression lldb_private::npdb::MakeConstantLocationExpression( DWARFExpression result(nullptr, extractor, nullptr); return result; } + +DWARFExpression lldb_private::npdb::MakeEnregisteredLocationExpressionForClass( + std::map<uint64_t, std::pair<RegisterId, uint32_t>> &members_info, + lldb::ModuleSP module) { + return MakeLocationExpressionInternal( + module, [&](Stream &stream, RegisterKind ®ister_kind) -> bool { + for (auto pair : members_info) { + std::pair<RegisterId, uint32_t> member_info = pair.second; + if (member_info.first != llvm::codeview::RegisterId::NONE) { + uint32_t reg_num = + GetRegisterNumber(module->GetArchitecture().GetMachine(), + member_info.first, register_kind); + if (reg_num == LLDB_INVALID_REGNUM) + return false; + if (reg_num > 31) { + stream.PutHex8(llvm::dwarf::DW_OP_regx); + stream.PutULEB128(reg_num); + } else { + stream.PutHex8(llvm::dwarf::DW_OP_reg0 + reg_num); + } + } + stream.PutHex8(llvm::dwarf::DW_OP_piece); + stream.PutULEB128(member_info.second); + } + return true; + }); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h index 99da09b70fe1..1ed6c55fea74 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h @@ -10,7 +10,9 @@ #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_DWARFLOCATIONEXPRESSION_H #include "lldb/lldb-forward.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/DebugInfo/CodeView/CodeView.h" +#include <map> namespace llvm { class APSInt; @@ -39,6 +41,10 @@ DWARFExpression MakeGlobalLocationExpression(uint16_t section, uint32_t offset, DWARFExpression MakeConstantLocationExpression( llvm::codeview::TypeIndex underlying_ti, llvm::pdb::TpiStream &tpi, const llvm::APSInt &constant, lldb::ModuleSP module); +DWARFExpression MakeEnregisteredLocationExpressionForClass( + std::map<uint64_t, std::pair<llvm::codeview::RegisterId, uint32_t>> + &members_info, + lldb::ModuleSP module); } // namespace npdb } // namespace lldb_private 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 dc0969a0ce7c..6dcce738b79f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp @@ -118,12 +118,6 @@ static llvm::Optional<PdbCompilandSymId> FindSymbolScope(PdbIndex &index, std::vector<PdbCompilandSymId> scope_stack; while (begin != end) { - if (id.offset == begin.offset()) { - // We have a match! Return the top of the stack - if (scope_stack.empty()) - return llvm::None; - return scope_stack.back(); - } if (begin.offset() > id.offset) { // We passed it. We couldn't even find this symbol record. lldbassert(false && "Invalid compiland symbol id!"); @@ -136,7 +130,7 @@ static llvm::Optional<PdbCompilandSymId> FindSymbolScope(PdbIndex &index, // We can use the end offset of the scope to determine whether or not // we can just outright skip this entire scope. uint32_t scope_end = getScopeEndOffset(*begin); - if (scope_end < id.modi) { + if (scope_end < id.offset) { begin = syms.at(scope_end); } else { // The symbol we're looking for is somewhere in this scope. @@ -147,8 +141,10 @@ static llvm::Optional<PdbCompilandSymId> FindSymbolScope(PdbIndex &index, } ++begin; } - - return llvm::None; + if (scope_stack.empty()) + return llvm::None; + // We have a match! Return the top of the stack + return scope_stack.back(); } static clang::TagTypeKind TranslateUdtKind(const TagRecord &cr) { @@ -327,6 +323,8 @@ PdbAstBuilder::CreateDeclInfoForType(const TagRecord &record, TypeIndex ti) { // LLDB TypeSP for the parent. This will cause the AST to automatically get // the right DeclContext created for any parent. clang::QualType parent_qt = GetOrCreateType(parent_iter->second); + if (parent_qt.isNull()) + return {nullptr, ""}; context = clang::TagDecl::castToDeclContext(parent_qt->getAsTagDecl()); return {context, uname}; @@ -403,10 +401,13 @@ void PdbAstBuilder::BuildParentMap() { } }; - CVType field_list = m_index.tpi().getType(tag.asTag().FieldList); + CVType field_list_cvt = m_index.tpi().getType(tag.asTag().FieldList); ProcessTpiStream process(m_index, *ti, tag, m_parent_types); - llvm::Error error = visitMemberRecordStream(field_list.data(), process); - if (error) + FieldListRecord field_list; + if (llvm::Error error = TypeDeserializer::deserializeAs<FieldListRecord>( + field_list_cvt, field_list)) + llvm::consumeError(std::move(error)); + if (llvm::Error error = visitMemberRecordStream(field_list.Data, process)) llvm::consumeError(std::move(error)); } @@ -501,7 +502,8 @@ clang::Decl *PdbAstBuilder::GetOrCreateSymbolForId(PdbCompilandSymId id) { if (isLocalVariableType(cvs.kind())) { clang::DeclContext *scope = GetParentDeclContext(id); clang::Decl *scope_decl = clang::Decl::castFromDeclContext(scope); - PdbCompilandSymId scope_id(id.modi, m_decl_to_status[scope_decl].uid); + PdbCompilandSymId scope_id = + PdbSymUid(m_decl_to_status[scope_decl].uid).asCompilandSym(); return GetOrCreateVariableDecl(scope_id, id); } @@ -517,6 +519,8 @@ clang::Decl *PdbAstBuilder::GetOrCreateSymbolForId(PdbCompilandSymId id) { return nullptr; case S_BLOCK32: return GetOrCreateBlockDecl(id); + case S_INLINESITE: + return GetOrCreateInlinedFunctionDecl(id); default: return nullptr; } @@ -533,6 +537,8 @@ llvm::Optional<CompilerDecl> PdbAstBuilder::GetOrCreateDeclForUid(PdbSymUid uid) break; case PdbSymUidKind::Type: { clang::QualType qt = GetOrCreateType(uid.asTypeSym()); + if (qt.isNull()) + return llvm::None; if (auto *tag = qt->getAsTagDecl()) { result = tag; break; @@ -542,6 +548,9 @@ llvm::Optional<CompilerDecl> PdbAstBuilder::GetOrCreateDeclForUid(PdbSymUid uid) default: return llvm::None; } + + if (!result) + return llvm::None; m_uid_to_decl[toOpaqueUid(uid)] = result; return ToCompilerDecl(*result); } @@ -554,7 +563,7 @@ clang::DeclContext *PdbAstBuilder::GetOrCreateDeclContextForUid(PdbSymUid uid) { auto option = GetOrCreateDeclForUid(uid); if (!option) return nullptr; - clang::Decl *decl = FromCompilerDecl(option.getValue()); + clang::Decl *decl = FromCompilerDecl(*option); if (!decl) return nullptr; @@ -579,6 +588,8 @@ PdbAstBuilder::CreateDeclInfoForUndecoratedName(llvm::StringRef name) { std::vector<TypeIndex> types = m_index.tpi().findRecordsByName(scope_name); while (!types.empty()) { clang::QualType qt = GetOrCreateType(types.back()); + if (qt.isNull()) + continue; clang::TagDecl *tag = qt->getAsTagDecl(); if (tag) return {clang::TagDecl::castToDeclContext(tag), std::string(uname)}; @@ -620,6 +631,8 @@ PdbAstBuilder::GetParentDeclContextForSymbol(const CVSymbol &sym) { std::vector<TypeIndex> matches = m_index.tpi().findRecordsByName(qname); while (!matches.empty()) { clang::QualType qt = GetOrCreateType(matches.back()); + if (qt.isNull()) + continue; clang::TagDecl *tag = qt->getAsTagDecl(); if (tag) return clang::TagDecl::castToDeclContext(tag); @@ -698,7 +711,13 @@ clang::DeclContext *PdbAstBuilder::GetParentDeclContext(PdbSymUid uid) { } bool PdbAstBuilder::CompleteType(clang::QualType qt) { + if (qt.isNull()) + return false; clang::TagDecl *tag = qt->getAsTagDecl(); + if (qt->isArrayType()) { + const clang::Type *element_type = qt->getArrayElementTypeNoTypeQual(); + tag = element_type->getAsTagDecl(); + } if (!tag) return false; @@ -741,22 +760,26 @@ bool PdbAstBuilder::CompleteTagDecl(clang::TagDecl &tag) { CVType field_list_cvt = m_index.tpi().getType(field_list_ti); if (field_list_cvt.kind() != LF_FIELDLIST) return false; + FieldListRecord field_list; + if (llvm::Error error = TypeDeserializer::deserializeAs<FieldListRecord>( + field_list_cvt, field_list)) + llvm::consumeError(std::move(error)); // Visit all members of this class, then perform any finalization necessary // to complete the class. CompilerType ct = ToCompilerType(tag_qt); UdtRecordCompleter completer(best_ti, ct, tag, *this, m_index, m_cxx_record_map); - auto error = - llvm::codeview::visitMemberRecordStream(field_list_cvt.data(), completer); + llvm::Error error = + llvm::codeview::visitMemberRecordStream(field_list.Data, completer); completer.complete(); status.resolved = true; - if (!error) - return true; - - llvm::consumeError(std::move(error)); - return false; + if (error) { + llvm::consumeError(std::move(error)); + return false; + } + return true; } clang::QualType PdbAstBuilder::CreateSimpleType(TypeIndex ti) { @@ -765,6 +788,8 @@ clang::QualType PdbAstBuilder::CreateSimpleType(TypeIndex ti) { if (ti.getSimpleMode() != SimpleTypeMode::Direct) { clang::QualType direct_type = GetOrCreateType(ti.makeDirect()); + if (direct_type.isNull()) + return {}; return m_clang.getASTContext().getPointerType(direct_type); } @@ -789,7 +814,8 @@ clang::QualType PdbAstBuilder::CreatePointerType(const PointerRecord &pointer) { if (pointer.isPointerToMember()) { MemberPointerInfo mpi = pointer.getMemberInfo(); clang::QualType class_type = GetOrCreateType(mpi.ContainingType); - + if (class_type.isNull()) + return {}; return m_clang.getASTContext().getMemberPointerType( pointee_type, class_type.getTypePtr()); } @@ -833,6 +859,9 @@ clang::QualType PdbAstBuilder::CreateRecordType(PdbTypeSymId id, clang::DeclContext *context = nullptr; std::string uname; std::tie(context, uname) = CreateDeclInfoForType(record, id.index); + if (!context) + return {}; + clang::TagTypeKind ttk = TranslateUdtKind(record); lldb::AccessType access = (ttk == clang::TTK_Class) ? lldb::eAccessPrivate : lldb::eAccessPublic; @@ -897,6 +926,8 @@ clang::VarDecl *PdbAstBuilder::CreateVariableDecl(PdbSymUid uid, CVSymbol sym, clang::DeclContext &scope) { VariableInfo var_info = GetVariableNameInfo(sym); clang::QualType qt = GetOrCreateType(var_info.type); + if (qt.isNull()) + return nullptr; clang::VarDecl *var_decl = m_clang.CreateVariableDeclaration( &scope, OptionalClangModuleID(), var_info.name.str().c_str(), qt); @@ -916,6 +947,8 @@ PdbAstBuilder::GetOrCreateVariableDecl(PdbCompilandSymId scope_id, return llvm::dyn_cast<clang::VarDecl>(decl); clang::DeclContext *scope = GetOrCreateDeclContextForUid(scope_id); + if (!scope) + return nullptr; CVSymbol sym = m_index.ReadSymbolRecord(var_id); return CreateVariableDecl(PdbSymUid(var_id), sym, *scope); @@ -943,6 +976,8 @@ PdbAstBuilder::GetOrCreateTypedefDecl(PdbGlobalSymId id) { PdbTypeSymId real_type_id{udt.Type, false}; clang::QualType qt = GetOrCreateType(real_type_id); + if (qt.isNull()) + return nullptr; std::string uname = std::string(DropNameScope(udt.Name)); @@ -1013,6 +1048,9 @@ clang::QualType PdbAstBuilder::CreateType(PdbTypeSymId type) { } clang::QualType PdbAstBuilder::GetOrCreateType(PdbTypeSymId type) { + if (type.index.isNoneType()) + return {}; + lldb::user_id_t uid = toOpaqueUid(type); auto iter = m_uid_to_type.find(uid); if (iter != m_uid_to_type.end()) @@ -1025,6 +1063,8 @@ clang::QualType PdbAstBuilder::GetOrCreateType(PdbTypeSymId type) { // This is a forward decl. Call GetOrCreate on the full decl, then map the // forward decl id to the full decl QualType. clang::QualType qt = GetOrCreateType(best_type); + if (qt.isNull()) + return {}; m_uid_to_type[toOpaqueUid(type)] = qt; return qt; } @@ -1032,6 +1072,9 @@ clang::QualType PdbAstBuilder::GetOrCreateType(PdbTypeSymId type) { // This is either a full decl, or a forward decl with no matching full decl // in the debug info. qt = CreateType(type); + if (qt.isNull()) + return {}; + m_uid_to_type[toOpaqueUid(type)] = qt; if (IsTagRecord(type, m_index.tpi())) { clang::TagDecl *tag = qt->getAsTagDecl(); @@ -1045,40 +1088,11 @@ clang::QualType PdbAstBuilder::GetOrCreateType(PdbTypeSymId type) { } clang::FunctionDecl * -PdbAstBuilder::GetOrCreateFunctionDecl(PdbCompilandSymId func_id) { - if (clang::Decl *decl = TryGetDecl(func_id)) - return llvm::dyn_cast<clang::FunctionDecl>(decl); - - clang::DeclContext *parent = GetParentDeclContext(PdbSymUid(func_id)); - std::string context_name; - if (clang::NamespaceDecl *ns = llvm::dyn_cast<clang::NamespaceDecl>(parent)) { - context_name = ns->getQualifiedNameAsString(); - } else if (clang::TagDecl *tag = llvm::dyn_cast<clang::TagDecl>(parent)) { - context_name = tag->getQualifiedNameAsString(); - } - - CVSymbol cvs = m_index.ReadSymbolRecord(func_id); - ProcSym proc(static_cast<SymbolRecordKind>(cvs.kind())); - llvm::cantFail(SymbolDeserializer::deserializeAs<ProcSym>(cvs, proc)); - - PdbTypeSymId type_id(proc.FunctionType); - clang::QualType qt = GetOrCreateType(type_id); - if (qt.isNull()) - return nullptr; - - clang::StorageClass storage = clang::SC_None; - if (proc.Kind == SymbolRecordKind::ProcSym) - storage = clang::SC_Static; - - const clang::FunctionProtoType *func_type = - llvm::dyn_cast<clang::FunctionProtoType>(qt); - - CompilerType func_ct = ToCompilerType(qt); - - llvm::StringRef proc_name = proc.Name; - proc_name.consume_front(context_name); - proc_name.consume_front("::"); - +PdbAstBuilder::CreateFunctionDecl(PdbCompilandSymId func_id, + llvm::StringRef func_name, TypeIndex func_ti, + CompilerType func_ct, uint32_t param_count, + clang::StorageClass func_storage, + bool is_inline, clang::DeclContext *parent) { clang::FunctionDecl *function_decl = nullptr; if (parent->isRecord()) { clang::QualType parent_qt = llvm::cast<clang::TypeDecl>(parent) @@ -1086,55 +1100,186 @@ PdbAstBuilder::GetOrCreateFunctionDecl(PdbCompilandSymId func_id) { ->getCanonicalTypeInternal(); lldb::opaque_compiler_type_t parent_opaque_ty = ToCompilerType(parent_qt).GetOpaqueQualType(); - + // FIXME: Remove this workaround. auto iter = m_cxx_record_map.find(parent_opaque_ty); if (iter != m_cxx_record_map.end()) { - if (iter->getSecond().contains({proc_name, func_ct})) { + if (iter->getSecond().contains({func_name, func_ct})) { return nullptr; } } - CVType cvt = m_index.tpi().getType(type_id.index); + CVType cvt = m_index.tpi().getType(func_ti); MemberFunctionRecord func_record(static_cast<TypeRecordKind>(cvt.kind())); llvm::cantFail(TypeDeserializer::deserializeAs<MemberFunctionRecord>( cvt, func_record)); TypeIndex class_index = func_record.getClassType(); + CVType parent_cvt = m_index.tpi().getType(class_index); - ClassRecord class_record = CVTagRecord::create(parent_cvt).asClass(); + TagRecord tag_record = CVTagRecord::create(parent_cvt).asTag(); // If it's a forward reference, try to get the real TypeIndex. - if (class_record.isForwardRef()) { + if (tag_record.isForwardRef()) { llvm::Expected<TypeIndex> eti = m_index.tpi().findFullDeclForForwardRef(class_index); if (eti) { - class_record = - CVTagRecord::create(m_index.tpi().getType(*eti)).asClass(); + tag_record = CVTagRecord::create(m_index.tpi().getType(*eti)).asTag(); } } - if (!class_record.FieldList.isSimple()) { - CVType field_list = m_index.tpi().getType(class_record.FieldList); - CreateMethodDecl process(m_index, m_clang, type_id.index, function_decl, - parent_opaque_ty, proc_name, func_ct); - if (llvm::Error err = visitMemberRecordStream(field_list.data(), process)) + if (!tag_record.FieldList.isSimple()) { + CVType field_list_cvt = m_index.tpi().getType(tag_record.FieldList); + FieldListRecord field_list; + if (llvm::Error error = TypeDeserializer::deserializeAs<FieldListRecord>( + field_list_cvt, field_list)) + llvm::consumeError(std::move(error)); + CreateMethodDecl process(m_index, m_clang, func_ti, function_decl, + parent_opaque_ty, func_name, func_ct); + if (llvm::Error err = visitMemberRecordStream(field_list.Data, process)) llvm::consumeError(std::move(err)); } if (!function_decl) { function_decl = m_clang.AddMethodToCXXRecordType( - parent_opaque_ty, proc_name, + parent_opaque_ty, func_name, /*mangled_name=*/nullptr, func_ct, /*access=*/lldb::AccessType::eAccessPublic, /*is_virtual=*/false, /*is_static=*/false, /*is_inline=*/false, /*is_explicit=*/false, /*is_attr_used=*/false, /*is_artificial=*/false); } - - m_cxx_record_map[parent_opaque_ty].insert({proc_name, func_ct}); + m_cxx_record_map[parent_opaque_ty].insert({func_name, func_ct}); } else { function_decl = m_clang.CreateFunctionDeclaration( - parent, OptionalClangModuleID(), proc_name, func_ct, storage, false); - CreateFunctionParameters(func_id, *function_decl, - func_type->getNumParams()); + parent, OptionalClangModuleID(), func_name, func_ct, func_storage, + is_inline); + CreateFunctionParameters(func_id, *function_decl, param_count); } + return function_decl; +} + +clang::FunctionDecl * +PdbAstBuilder::GetOrCreateInlinedFunctionDecl(PdbCompilandSymId inlinesite_id) { + CompilandIndexItem *cii = + m_index.compilands().GetCompiland(inlinesite_id.modi); + CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(inlinesite_id.offset); + InlineSiteSym inline_site(static_cast<SymbolRecordKind>(sym.kind())); + cantFail(SymbolDeserializer::deserializeAs<InlineSiteSym>(sym, inline_site)); + + // Inlinee is the id index to the function id record that is inlined. + PdbTypeSymId func_id(inline_site.Inlinee, true); + // Look up the function decl by the id index to see if we have created a + // function decl for a different inlinesite that refers the same function. + if (clang::Decl *decl = TryGetDecl(func_id)) + return llvm::dyn_cast<clang::FunctionDecl>(decl); + clang::FunctionDecl *function_decl = + CreateFunctionDeclFromId(func_id, inlinesite_id); + if (function_decl == nullptr) + return nullptr; + + // Use inline site id in m_decl_to_status because it's expected to be a + // PdbCompilandSymId so that we can parse local variables info after it. + uint64_t inlinesite_uid = toOpaqueUid(inlinesite_id); + DeclStatus status; + status.resolved = true; + status.uid = inlinesite_uid; + m_decl_to_status.insert({function_decl, status}); + // Use the index in IPI stream as uid in m_uid_to_decl, because index in IPI + // stream are unique and there could be multiple inline sites (different ids) + // referring the same inline function. This avoid creating multiple same + // inline function delcs. + uint64_t func_uid = toOpaqueUid(func_id); + lldbassert(m_uid_to_decl.count(func_uid) == 0); + m_uid_to_decl[func_uid] = function_decl; + return function_decl; +} + +clang::FunctionDecl * +PdbAstBuilder::CreateFunctionDeclFromId(PdbTypeSymId func_tid, + PdbCompilandSymId func_sid) { + lldbassert(func_tid.is_ipi); + CVType func_cvt = m_index.ipi().getType(func_tid.index); + llvm::StringRef func_name; + TypeIndex func_ti; + clang::DeclContext *parent = nullptr; + switch (func_cvt.kind()) { + case LF_MFUNC_ID: { + MemberFuncIdRecord mfr; + cantFail( + TypeDeserializer::deserializeAs<MemberFuncIdRecord>(func_cvt, mfr)); + func_name = mfr.getName(); + func_ti = mfr.getFunctionType(); + PdbTypeSymId class_type_id(mfr.ClassType, false); + parent = GetOrCreateDeclContextForUid(class_type_id); + break; + } + case LF_FUNC_ID: { + FuncIdRecord fir; + cantFail(TypeDeserializer::deserializeAs<FuncIdRecord>(func_cvt, fir)); + func_name = fir.getName(); + func_ti = fir.getFunctionType(); + parent = FromCompilerDeclContext(GetTranslationUnitDecl()); + if (!fir.ParentScope.isNoneType()) { + CVType parent_cvt = m_index.ipi().getType(fir.ParentScope); + if (parent_cvt.kind() == LF_STRING_ID) { + StringIdRecord sir; + cantFail( + TypeDeserializer::deserializeAs<StringIdRecord>(parent_cvt, sir)); + parent = GetOrCreateNamespaceDecl(sir.String.data(), *parent); + } + } + break; + } + default: + lldbassert(false && "Invalid function id type!"); + } + clang::QualType func_qt = GetOrCreateType(func_ti); + if (func_qt.isNull()) + return nullptr; + CompilerType func_ct = ToCompilerType(func_qt); + uint32_t param_count = + llvm::cast<clang::FunctionProtoType>(func_qt)->getNumParams(); + return CreateFunctionDecl(func_sid, func_name, func_ti, func_ct, param_count, + clang::SC_None, true, parent); +} + +clang::FunctionDecl * +PdbAstBuilder::GetOrCreateFunctionDecl(PdbCompilandSymId func_id) { + if (clang::Decl *decl = TryGetDecl(func_id)) + return llvm::dyn_cast<clang::FunctionDecl>(decl); + + clang::DeclContext *parent = GetParentDeclContext(PdbSymUid(func_id)); + std::string context_name; + if (clang::NamespaceDecl *ns = llvm::dyn_cast<clang::NamespaceDecl>(parent)) { + context_name = ns->getQualifiedNameAsString(); + } else if (clang::TagDecl *tag = llvm::dyn_cast<clang::TagDecl>(parent)) { + context_name = tag->getQualifiedNameAsString(); + } + + CVSymbol cvs = m_index.ReadSymbolRecord(func_id); + ProcSym proc(static_cast<SymbolRecordKind>(cvs.kind())); + llvm::cantFail(SymbolDeserializer::deserializeAs<ProcSym>(cvs, proc)); + + PdbTypeSymId type_id(proc.FunctionType); + clang::QualType qt = GetOrCreateType(type_id); + if (qt.isNull()) + return nullptr; + + clang::StorageClass storage = clang::SC_None; + if (proc.Kind == SymbolRecordKind::ProcSym) + storage = clang::SC_Static; + + const clang::FunctionProtoType *func_type = + llvm::dyn_cast<clang::FunctionProtoType>(qt); + + CompilerType func_ct = ToCompilerType(qt); + + llvm::StringRef proc_name = proc.Name; + proc_name.consume_front(context_name); + proc_name.consume_front("::"); + + clang::FunctionDecl *function_decl = + CreateFunctionDecl(func_id, proc_name, proc.FunctionType, func_ct, + func_type->getNumParams(), storage, false, parent); + if (function_decl == nullptr) + return nullptr; lldbassert(m_uid_to_decl.count(toOpaqueUid(func_id)) == 0); m_uid_to_decl[toOpaqueUid(func_id)] = function_decl; @@ -1153,10 +1298,11 @@ void PdbAstBuilder::CreateFunctionParameters(PdbCompilandSymId func_id, CVSymbolArray scope = cii->m_debug_stream.getSymbolArrayForScope(func_id.offset); + scope.drop_front(); auto begin = scope.begin(); auto end = scope.end(); std::vector<clang::ParmVarDecl *> params; - while (begin != end && param_count > 0) { + for (uint32_t i = 0; i < param_count && begin != end;) { uint32_t record_offset = begin.offset(); CVSymbol sym = *begin++; @@ -1187,9 +1333,11 @@ void PdbAstBuilder::CreateFunctionParameters(PdbCompilandSymId func_id, break; } case S_BLOCK32: - // All parameters should come before the first block. If that isn't the - // case, then perhaps this is bad debug info that doesn't contain - // information about all parameters. + case S_INLINESITE: + case S_INLINESITE2: + // All parameters should come before the first block/inlinesite. If that + // isn't the case, then perhaps this is bad debug info that doesn't + // contain information about all parameters. return; default: continue; @@ -1197,6 +1345,8 @@ void PdbAstBuilder::CreateFunctionParameters(PdbCompilandSymId func_id, PdbCompilandSymId param_uid(func_id.modi, record_offset); clang::QualType qt = GetOrCreateType(param_type); + if (qt.isNull()) + return; CompilerType param_type_ct = m_clang.GetType(qt); clang::ParmVarDecl *param = m_clang.CreateParameterDeclaration( @@ -1206,10 +1356,10 @@ void PdbAstBuilder::CreateFunctionParameters(PdbCompilandSymId func_id, m_uid_to_decl[toOpaqueUid(param_uid)] = param; params.push_back(param); - --param_count; + ++i; } - if (!params.empty()) + if (!params.empty() && params.size() == param_count) m_clang.SetFunctionParameters(&function_decl, params); } @@ -1218,7 +1368,12 @@ clang::QualType PdbAstBuilder::CreateEnumType(PdbTypeSymId id, clang::DeclContext *decl_context = nullptr; std::string uname; std::tie(decl_context, uname) = CreateDeclInfoForType(er, id.index); + if (!decl_context) + return {}; + clang::QualType underlying_type = GetOrCreateType(er.UnderlyingType); + if (underlying_type.isNull()) + return {}; Declaration declaration; CompilerType enum_ct = m_clang.CreateEnumerationType( @@ -1234,8 +1389,10 @@ clang::QualType PdbAstBuilder::CreateEnumType(PdbTypeSymId id, clang::QualType PdbAstBuilder::CreateArrayType(const ArrayRecord &ar) { clang::QualType element_type = GetOrCreateType(ar.ElementType); - uint64_t element_count = - ar.Size / GetSizeOfType({ar.ElementType}, m_index.tpi()); + uint64_t element_size = GetSizeOfType({ar.ElementType}, m_index.tpi()); + if (element_type.isNull() || element_size == 0) + return {}; + uint64_t element_count = ar.Size / element_size; CompilerType array_ct = m_clang.CreateArrayType(ToCompilerType(element_type), element_count, false); @@ -1261,10 +1418,14 @@ clang::QualType PdbAstBuilder::CreateFunctionType( for (TypeIndex arg_index : arg_indices) { clang::QualType arg_type = GetOrCreateType(arg_index); + if (arg_type.isNull()) + continue; arg_types.push_back(ToCompilerType(arg_type)); } clang::QualType return_type = GetOrCreateType(return_type_idx); + if (return_type.isNull()) + return {}; llvm::Optional<clang::CallingConv> cc = TranslateCallingConvention(calling_convention); @@ -1303,7 +1464,7 @@ void PdbAstBuilder::ParseAllNamespacesPlusChildrenOf( CVTagRecord tag = CVTagRecord::create(cvt); - if (!parent.hasValue()) { + if (!parent) { clang::QualType qt = GetOrCreateType(tid); CompleteType(qt); continue; @@ -1315,7 +1476,7 @@ void PdbAstBuilder::ParseAllNamespacesPlusChildrenOf( clang::DeclContext *context = nullptr; std::string uname; std::tie(context, uname) = CreateDeclInfoForType(tag.asTag(), tid.index); - if (!context->isNamespace()) + if (!context || !context->isNamespace()) continue; clang::NamespaceDecl *ns = llvm::cast<clang::NamespaceDecl>(context); @@ -1385,7 +1546,7 @@ static CVSymbolArray skipFunctionParameters(clang::Decl &decl, void PdbAstBuilder::ParseBlockChildren(PdbCompilandSymId block_id) { CVSymbol sym = m_index.ReadSymbolRecord(block_id); lldbassert(sym.kind() == S_GPROC32 || sym.kind() == S_LPROC32 || - sym.kind() == S_BLOCK32); + sym.kind() == S_BLOCK32 || sym.kind() == S_INLINESITE); CompilandIndexItem &cii = m_index.compilands().GetOrCreateCompiland(block_id.modi); CVSymbolArray symbols = @@ -1397,11 +1558,12 @@ void PdbAstBuilder::ParseBlockChildren(PdbCompilandSymId block_id) { symbols = skipFunctionParameters(*m_uid_to_decl[toOpaqueUid(block_id)], symbols); + symbols.drop_front(); auto begin = symbols.begin(); while (begin != symbols.end()) { PdbCompilandSymId child_sym_id(block_id.modi, begin.offset()); GetOrCreateSymbolForId(child_sym_id); - if (begin->kind() == S_BLOCK32) { + if (begin->kind() == S_BLOCK32 || begin->kind() == S_INLINESITE) { ParseBlockChildren(child_sym_id); begin = symbols.at(getScopeEndOffset(*begin)); } diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h index 73accf5e5e68..40425dd4c6e7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h @@ -61,6 +61,8 @@ public: clang::DeclContext *GetParentDeclContext(PdbSymUid uid); clang::FunctionDecl *GetOrCreateFunctionDecl(PdbCompilandSymId func_id); + clang::FunctionDecl * + GetOrCreateInlinedFunctionDecl(PdbCompilandSymId inlinesite_id); clang::BlockDecl *GetOrCreateBlockDecl(PdbCompilandSymId block_id); clang::VarDecl *GetOrCreateVariableDecl(PdbCompilandSymId scope_id, PdbCompilandSymId var_id); @@ -116,7 +118,13 @@ private: clang::NamespaceDecl *GetOrCreateNamespaceDecl(const char *name, clang::DeclContext &context); - + clang::FunctionDecl *CreateFunctionDeclFromId(PdbTypeSymId func_tid, + PdbCompilandSymId func_sid); + clang::FunctionDecl * + CreateFunctionDecl(PdbCompilandSymId func_id, llvm::StringRef func_name, + TypeIndex func_ti, CompilerType func_ct, + uint32_t param_count, clang::StorageClass func_storage, + bool is_inline, clang::DeclContext *parent); void ParseAllNamespacesPlusChildrenOf(llvm::Optional<llvm::StringRef> parent); void ParseDeclsForSimpleContext(clang::DeclContext &context); void ParseBlockChildren(PdbCompilandSymId block_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 4f570d5e6788..c45db174e534 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp @@ -18,6 +18,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/EnumTables.h" +#include "llvm/Support/ScopedPrinter.h" using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp index dc964f64a915..3a76f8bff316 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp @@ -60,15 +60,11 @@ PdbIndex::create(llvm::pdb::PDBFile *file) { lldb::addr_t PdbIndex::MakeVirtualAddress(uint16_t segment, uint32_t offset) const { - // Segment indices are 1-based. - lldbassert(segment > 0); - uint32_t max_section = dbi().getSectionHeaders().size(); - lldbassert(segment <= max_section + 1); - + // Segment indices are 1-based. // If this is an absolute symbol, it's indicated by the magic section index // |max_section+1|. In this case, the offset is meaningless, so just return. - if (segment == max_section + 1) + if (segment == 0 || segment > max_section) return LLDB_INVALID_ADDRESS; const llvm::object::coff_section &cs = dbi().getSectionHeaders()[segment - 1]; @@ -76,10 +72,6 @@ lldb::addr_t PdbIndex::MakeVirtualAddress(uint16_t segment, static_cast<lldb::addr_t>(offset); } -lldb::addr_t PdbIndex::MakeVirtualAddress(const SegmentOffset &so) const { - return MakeVirtualAddress(so.segment, so.offset); -} - llvm::Optional<uint16_t> PdbIndex::GetModuleIndexForAddr(uint16_t segment, uint32_t offset) const { return GetModuleIndexForVa(MakeVirtualAddress(segment, offset)); @@ -107,6 +99,8 @@ void PdbIndex::ParseSectionContribs() { return; uint64_t va = m_ctx.MakeVirtualAddress(C.ISect, C.Off); + if (va == LLDB_INVALID_ADDRESS) + return; uint64_t end = va + C.Size; // IntervalMap's start and end represent a closed range, not a half-open // range, so we have to subtract 1. @@ -128,7 +122,9 @@ void PdbIndex::BuildAddrToSymbolMap(CompilandIndexItem &cci) { continue; SegmentOffset so = GetSegmentAndOffset(*iter); - lldb::addr_t va = MakeVirtualAddress(so); + lldb::addr_t va = MakeVirtualAddress(so.segment, so.offset); + if (va == LLDB_INVALID_ADDRESS) + continue; PdbCompilandSymId cu_sym_id(modi, iter.offset()); @@ -175,7 +171,10 @@ std::vector<SymbolAndUid> PdbIndex::FindSymbolsByVa(lldb::addr_t va) { else sol.so = GetSegmentAndOffset(sym); - lldb::addr_t start = MakeVirtualAddress(sol.so); + lldb::addr_t start = MakeVirtualAddress(sol.so.segment, sol.so.offset); + if (start == LLDB_INVALID_ADDRESS) + continue; + lldb::addr_t end = start + sol.length; if (va >= start && va < end) result.push_back({std::move(sym), iter->second}); diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h index edbdd9ee290b..138c63d79a59 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h @@ -143,7 +143,6 @@ public: const CompileUnitIndex &compilands() const { return m_cus; } lldb::addr_t MakeVirtualAddress(uint16_t segment, uint32_t offset) const; - lldb::addr_t MakeVirtualAddress(const SegmentOffset &so) const; std::vector<SymbolAndUid> FindSymbolsByVa(lldb::addr_t va); diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp index b5a16447d9cf..7bb7c69eece7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp @@ -12,6 +12,7 @@ #include "PdbIndex.h" #include "PdbSymUid.h" +#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" #include "llvm/DebugInfo/CodeView/TypeDeserializer.h" #include "llvm/DebugInfo/PDB/Native/DbiStream.h" @@ -20,6 +21,7 @@ #include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h" #include "lldb/Symbol/Block.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/lldb-enumerations.h" using namespace lldb_private; @@ -32,15 +34,16 @@ MakeRangeList(const PdbIndex &index, const LocalVariableAddrRange &range, llvm::ArrayRef<LocalVariableAddrGap> gaps) { lldb::addr_t start = index.MakeVirtualAddress(range.ISectStart, range.OffsetStart); + if (start == LLDB_INVALID_ADDRESS) + return {}; lldb::addr_t end = start + range.Range; Variable::RangeList result; while (!gaps.empty()) { const LocalVariableAddrGap &gap = gaps.front(); - - lldb::addr_t size = gap.GapStartOffset - start; - result.Append(start, size); - start += gap.Range; + lldb::addr_t gap_start = start + gap.GapStartOffset; + result.Append(start, gap_start - start); + start = gap_start + gap.Range; gaps = gaps.drop_front(); } @@ -48,6 +51,24 @@ MakeRangeList(const PdbIndex &index, const LocalVariableAddrRange &range, return result; } +namespace { +struct FindMembersSize : public TypeVisitorCallbacks { + FindMembersSize( + std::map<uint64_t, std::pair<RegisterId, uint32_t>> &members_info, + TpiStream &tpi) + : members_info(members_info), tpi(tpi) {} + std::map<uint64_t, std::pair<RegisterId, uint32_t>> &members_info; + TpiStream &tpi; + llvm::Error visitKnownMember(CVMemberRecord &cvr, + DataMemberRecord &member) override { + members_info.insert( + {member.getFieldOffset(), + {llvm::codeview::RegisterId::NONE, GetSizeOfType(member.Type, tpi)}}); + return llvm::Error::success(); + } +}; +} // namespace + CVTagRecord CVTagRecord::create(CVType type) { assert(IsTagRecord(type) && "type is not a tag record!"); switch (type.kind()) { @@ -477,6 +498,8 @@ VariableInfo lldb_private::npdb::GetVariableNameInfo(CVSymbol sym) { cantFail(SymbolDeserializer::deserializeAs<LocalSym>(sym, local)); result.type = local.Type; result.name = local.Name; + result.is_param = + ((local.Flags & LocalSymFlags::IsParameter) != LocalSymFlags::None); return result; } @@ -563,7 +586,8 @@ static RegisterId GetBaseFrameRegister(PdbIndex &index, PdbCompilandSymId frame_proc_id, bool is_parameter) { CVSymbol frame_proc_cvs = index.ReadSymbolRecord(frame_proc_id); - lldbassert(frame_proc_cvs.kind() == S_FRAMEPROC); + if (frame_proc_cvs.kind() != S_FRAMEPROC) + return RegisterId::NONE; FrameProcSym frame_proc(SymbolRecordKind::FrameProcSym); cantFail(SymbolDeserializer::deserializeAs<FrameProcSym>(frame_proc_cvs, @@ -609,7 +633,8 @@ VariableInfo lldb_private::npdb::GetVariableLocationInfo( PdbCompilandSymId loc_specifier_id(var_id.modi, var_id.offset + sym.RecordData.size()); CVSymbol loc_specifier_cvs = index.ReadSymbolRecord(loc_specifier_id); - if (loc_specifier_cvs.kind() == S_DEFRANGE_FRAMEPOINTER_REL) { + switch(loc_specifier_cvs.kind()) { + case S_DEFRANGE_FRAMEPOINTER_REL: { DefRangeFramePointerRelSym loc( SymbolRecordKind::DefRangeFramePointerRelSym); cantFail(SymbolDeserializer::deserializeAs<DefRangeFramePointerRelSym>( @@ -632,11 +657,10 @@ VariableInfo lldb_private::npdb::GetVariableLocationInfo( PdbCompilandSymId frame_proc_id( func_scope_id.modi, func_scope_id.offset + func_block_cvs.length()); - bool is_parameter = - ((local.Flags & LocalSymFlags::IsParameter) != LocalSymFlags::None); RegisterId base_reg = - GetBaseFrameRegister(index, frame_proc_id, is_parameter); - + GetBaseFrameRegister(index, frame_proc_id, result.is_param); + if (base_reg == RegisterId::NONE) + break; if (base_reg == RegisterId::VFRAME) { llvm::StringRef program; if (GetFrameDataProgram(index, ranges, program)) { @@ -651,7 +675,9 @@ VariableInfo lldb_private::npdb::GetVariableLocationInfo( MakeRegRelLocationExpression(base_reg, loc.Hdr.Offset, module); result.ranges = std::move(ranges); } - } else if (loc_specifier_cvs.kind() == S_DEFRANGE_REGISTER_REL) { + break; + } + case S_DEFRANGE_REGISTER_REL: { DefRangeRegisterRelSym loc(SymbolRecordKind::DefRangeRegisterRelSym); cantFail(SymbolDeserializer::deserializeAs<DefRangeRegisterRelSym>( loc_specifier_cvs, loc)); @@ -674,9 +700,126 @@ VariableInfo lldb_private::npdb::GetVariableLocationInfo( base_reg, loc.Hdr.BasePointerOffset, module); result.ranges = std::move(ranges); } + break; + } + case S_DEFRANGE_REGISTER: { + DefRangeRegisterSym loc(SymbolRecordKind::DefRangeRegisterSym); + cantFail(SymbolDeserializer::deserializeAs<DefRangeRegisterSym>( + loc_specifier_cvs, loc)); + + RegisterId base_reg = (RegisterId)(uint16_t)loc.Hdr.Register; + result.ranges = MakeRangeList(index, loc.Range, loc.Gaps); + result.location = MakeEnregisteredLocationExpression(base_reg, module); + break; } + case S_DEFRANGE_SUBFIELD_REGISTER: { + // A map from offset in parent to pair of register id and size. If the + // variable is a simple type, then we don't know the number of subfields. + // Otherwise, the size of the map should be greater than or equal to the + // number of sub field record. + std::map<uint64_t, std::pair<RegisterId, uint32_t>> members_info; + bool is_simple_type = result.type.isSimple(); + if (!is_simple_type) { + CVType class_cvt = index.tpi().getType(result.type); + TypeIndex class_id = result.type; + if (class_cvt.kind() == LF_MODIFIER) + class_id = LookThroughModifierRecord(class_cvt); + if (IsForwardRefUdt(class_id, index.tpi())) { + auto expected_full_ti = + index.tpi().findFullDeclForForwardRef(class_id); + if (!expected_full_ti) { + llvm::consumeError(expected_full_ti.takeError()); + break; + } + class_cvt = index.tpi().getType(*expected_full_ti); + } + if (IsTagRecord(class_cvt)) { + TagRecord tag_record = CVTagRecord::create(class_cvt).asTag(); + CVType field_list_cvt = index.tpi().getType(tag_record.FieldList); + FieldListRecord field_list; + if (llvm::Error error = + TypeDeserializer::deserializeAs<FieldListRecord>( + field_list_cvt, field_list)) + llvm::consumeError(std::move(error)); + FindMembersSize find_members_size(members_info, index.tpi()); + if (llvm::Error err = visitMemberRecordStream(field_list.Data, + find_members_size)) { + llvm::consumeError(std::move(err)); + break; + } + } else { + // TODO: Handle poiner type. + break; + } + } + + size_t member_idx = 0; + // Assuming S_DEFRANGE_SUBFIELD_REGISTER is followed only by + // S_DEFRANGE_SUBFIELD_REGISTER, need to verify. + while (loc_specifier_cvs.kind() == S_DEFRANGE_SUBFIELD_REGISTER) { + if (!is_simple_type && member_idx >= members_info.size()) + break; + + DefRangeSubfieldRegisterSym loc( + SymbolRecordKind::DefRangeSubfieldRegisterSym); + cantFail(SymbolDeserializer::deserializeAs<DefRangeSubfieldRegisterSym>( + loc_specifier_cvs, loc)); + + if (result.ranges) { + result.ranges = Variable::RangeList::GetOverlaps( + *result.ranges, MakeRangeList(index, loc.Range, loc.Gaps)); + } else { + result.ranges = MakeRangeList(index, loc.Range, loc.Gaps); + result.ranges->Sort(); + } - // FIXME: Handle other kinds + if (is_simple_type) { + if (members_info.count(loc.Hdr.OffsetInParent)) { + // Malformed record. + result.ranges->Clear(); + return result; + } + members_info[loc.Hdr.OffsetInParent] = { + (RegisterId)(uint16_t)loc.Hdr.Register, 0}; + } else { + if (!members_info.count(loc.Hdr.OffsetInParent)) { + // Malformed record. + result.ranges->Clear(); + return result; + } + members_info[loc.Hdr.OffsetInParent].first = + (RegisterId)(uint16_t)loc.Hdr.Register; + } + // Go to next S_DEFRANGE_SUBFIELD_REGISTER. + loc_specifier_id = PdbCompilandSymId( + loc_specifier_id.modi, + loc_specifier_id.offset + loc_specifier_cvs.RecordData.size()); + loc_specifier_cvs = index.ReadSymbolRecord(loc_specifier_id); + } + // Fix size for simple type. + if (is_simple_type) { + auto cur = members_info.begin(); + auto end = members_info.end(); + auto next = cur; + ++next; + uint32_t size = 0; + while (next != end) { + cur->second.second = next->first - cur->first; + size += cur->second.second; + cur = next++; + } + cur->second.second = + GetTypeSizeForSimpleKind(result.type.getSimpleKind()) - size; + } + result.location = + MakeEnregisteredLocationExpressionForClass(members_info, module); + break; + } + default: + // FIXME: Handle other kinds. LLVM only generates the 4 types of records + // above. + break; + } return result; } llvm_unreachable("Symbol is not a local variable!"); @@ -704,6 +847,8 @@ lldb_private::npdb::GetCompilerTypeForSimpleKind(SimpleTypeKind kind) { return lldb::eBasicTypeChar16; case SimpleTypeKind::Character32: return lldb::eBasicTypeChar32; + case SimpleTypeKind::Character8: + return lldb::eBasicTypeChar8; case SimpleTypeKind::Complex80: return lldb::eBasicTypeLongDoubleComplex; case SimpleTypeKind::Complex64: @@ -796,6 +941,7 @@ size_t lldb_private::npdb::GetTypeSizeForSimpleKind(SimpleTypeKind kind) { case SimpleTypeKind::NarrowCharacter: case SimpleTypeKind::SignedCharacter: case SimpleTypeKind::SByte: + case SimpleTypeKind::Character8: return 1; case SimpleTypeKind::Void: default: diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h index c309c5c8ea1c..138c11aaeb43 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h @@ -105,6 +105,7 @@ struct VariableInfo { llvm::codeview::TypeIndex type; llvm::Optional<DWARFExpression> location; llvm::Optional<Variable::RangeList> ranges; + bool is_param; }; llvm::pdb::PDB_SymType CVSymToPDBSym(llvm::codeview::SymbolKind kind); 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 a035a791f868..7dc99818c244 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -29,6 +29,7 @@ #include "lldb/Symbol/SymbolVendor.h" #include "lldb/Symbol/Variable.h" #include "lldb/Symbol/VariableList.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "llvm/DebugInfo/CodeView/CVRecord.h" @@ -79,6 +80,8 @@ static lldb::LanguageType TranslateLanguage(PDB_Lang lang) { return lldb::LanguageType::eLanguageTypeC; case PDB_Lang::Swift: return lldb::LanguageType::eLanguageTypeSwift; + case PDB_Lang::Rust: + return lldb::LanguageType::eLanguageTypeRust; default: return lldb::LanguageType::eLanguageTypeUnknown; } @@ -170,6 +173,8 @@ static llvm::StringRef GetSimpleTypeName(SimpleTypeKind kind) { return "char16_t"; case SimpleTypeKind::Character32: return "char32_t"; + case SimpleTypeKind::Character8: + return "char8_t"; case SimpleTypeKind::Complex80: case SimpleTypeKind::Complex64: case SimpleTypeKind::Complex32: @@ -249,7 +254,7 @@ SymbolFile *SymbolFileNativePDB::CreateInstance(ObjectFileSP objfile_sp) { } SymbolFileNativePDB::SymbolFileNativePDB(ObjectFileSP objfile_sp) - : SymbolFile(std::move(objfile_sp)) {} + : SymbolFileCommon(std::move(objfile_sp)) {} SymbolFileNativePDB::~SymbolFileNativePDB() = default; @@ -302,8 +307,8 @@ void SymbolFileNativePDB::InitializeObject() { auto ts_or_err = m_objfile_sp->GetModule()->GetTypeSystemForLanguage( lldb::eLanguageTypeC_plus_plus); if (auto err = ts_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Failed to initialize"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Failed to initialize"); } else { ts_or_err->SetSymbolFile(this); auto *clang = llvm::cast_or_null<TypeSystemClang>(&ts_or_err.get()); @@ -367,7 +372,7 @@ Block &SymbolFileNativePDB::CreateBlock(PdbCompilandSymId block_id) { std::shared_ptr<InlineSite> inline_site = m_inline_sites[opaque_block_uid]; Block &parent_block = GetOrCreateBlock(inline_site->parent_id); parent_block.AddChild(child_block); - + m_ast->GetOrCreateInlinedFunctionDecl(block_id); // Copy ranges from InlineSite to Block. for (size_t i = 0; i < inline_site->ranges.GetSize(); ++i) { auto *entry = inline_site->ranges.GetEntryAtIndex(i); @@ -402,7 +407,8 @@ lldb::FunctionSP SymbolFileNativePDB::CreateFunction(PdbCompilandSymId func_id, lldbassert(sym_record.kind() == S_LPROC32 || sym_record.kind() == S_GPROC32); SegmentOffsetLength sol = GetSegmentOffsetAndLength(sym_record); - auto file_vm_addr = m_index->MakeVirtualAddress(sol.so); + auto file_vm_addr = + m_index->MakeVirtualAddress(sol.so.segment, sol.so.offset); if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0) return nullptr; @@ -444,7 +450,8 @@ SymbolFileNativePDB::CreateCompileUnit(const CompilandIndexItem &cci) { llvm::SmallString<64> source_file_name = m_index->compilands().GetMainSourceFile(cci); - FileSpec fs(source_file_name); + FileSpec fs(llvm::sys::path::convert_to_slash( + source_file_name, llvm::sys::path::Style::windows_backslash)); CompUnitSP cu_sp = std::make_shared<CompileUnit>(m_objfile_sp->GetModule(), nullptr, fs, @@ -721,6 +728,8 @@ TypeSP SymbolFileNativePDB::CreateAndCacheType(PdbTypeSymId type_id) { PdbTypeSymId best_decl_id = full_decl_uid ? *full_decl_uid : type_id; clang::QualType qt = m_ast->GetOrCreateType(best_decl_id); + if (qt.isNull()) + return nullptr; TypeSP result = CreateType(best_decl_id, m_ast->ToCompilerType(qt)); if (!result) @@ -799,11 +808,13 @@ VariableSP SymbolFileNativePDB::CreateGlobalVariable(PdbGlobalSymId var_id) { CompUnitSP comp_unit; llvm::Optional<uint16_t> modi = m_index->GetModuleIndexForVa(addr); - if (modi) { - CompilandIndexItem &cci = m_index->compilands().GetOrCreateCompiland(*modi); - comp_unit = GetOrCreateCompileUnit(cci); + if (!modi) { + return nullptr; } + CompilandIndexItem &cci = m_index->compilands().GetOrCreateCompiland(*modi); + comp_unit = GetOrCreateCompileUnit(cci); + Declaration decl; PdbTypeSymId tid(ti, false); SymbolFileTypeSP type_sp = @@ -861,8 +872,12 @@ SymbolFileNativePDB::CreateConstantSymbol(PdbGlobalSymId var_id, VariableSP SymbolFileNativePDB::GetOrCreateGlobalVariable(PdbGlobalSymId var_id) { auto emplace_result = m_global_vars.try_emplace(toOpaqueUid(var_id), nullptr); - if (emplace_result.second) - emplace_result.first->second = CreateGlobalVariable(var_id); + if (emplace_result.second) { + if (VariableSP var_sp = CreateGlobalVariable(var_id)) + emplace_result.first->second = var_sp; + else + return nullptr; + } return emplace_result.first->second; } @@ -979,7 +994,7 @@ uint32_t SymbolFileNativePDB::ResolveSymbolContext( llvm::Optional<uint16_t> modi = m_index->GetModuleIndexForVa(file_addr); if (!modi) return 0; - CompUnitSP cu_sp = GetCompileUnitAtIndex(modi.getValue()); + CompUnitSP cu_sp = GetCompileUnitAtIndex(*modi); if (!cu_sp) return 0; @@ -1094,6 +1109,8 @@ bool SymbolFileNativePDB::ParseLineTable(CompileUnit &comp_unit) { const LineFragmentHeader *lfh = lines.header(); uint64_t virtual_addr = m_index->MakeVirtualAddress(lfh->RelocSegment, lfh->RelocOffset); + if (virtual_addr == LLDB_INVALID_ADDRESS) + continue; for (const LineColumnEntry &group : lines) { llvm::Expected<uint32_t> file_index_or_err = @@ -1118,8 +1135,13 @@ bool SymbolFileNativePDB::ParseLineTable(CompileUnit &comp_unit) { uint32_t lno = cur_info.getStartLine(); - line_set.emplace(addr, lno, 0, file_index, is_statement, false, - is_prologue, is_epilogue, false); + LineTable::Entry new_entry(addr, lno, 0, file_index, is_statement, false, + is_prologue, is_epilogue, false); + // Terminal entry has lower precedence than new entry. + auto iter = line_set.find(new_entry); + if (iter != line_set.end() && iter->is_terminal_entry) + line_set.erase(iter); + line_set.insert(new_entry); if (line_entry.GetRangeBase() != LLDB_INVALID_ADDRESS) { line_entry.SetRangeEnd(addr); @@ -1153,7 +1175,11 @@ bool SymbolFileNativePDB::ParseLineTable(CompileUnit &comp_unit) { CVSymbol func_record = cii->m_debug_stream.readSymbolAtOffset(record_offset); SegmentOffsetLength sol = GetSegmentOffsetAndLength(func_record); - addr_t file_vm_addr = m_index->MakeVirtualAddress(sol.so); + addr_t file_vm_addr = + m_index->MakeVirtualAddress(sol.so.segment, sol.so.offset); + if (file_vm_addr == LLDB_INVALID_ADDRESS) + continue; + AddressRange func_range(file_vm_addr, sol.length, comp_unit.GetModule()->GetSectionList()); Address func_base = func_range.GetBaseAddress(); @@ -1215,9 +1241,6 @@ bool SymbolFileNativePDB::ParseDebugMacros(CompileUnit &comp_unit) { llvm::Expected<uint32_t> SymbolFileNativePDB::GetFileIndex(const CompilandIndexItem &cii, uint32_t file_id) { - auto index_iter = m_file_indexes.find(file_id); - if (index_iter != m_file_indexes.end()) - return index_iter->getSecond(); const auto &checksums = cii.m_strings.checksums().getArray(); const auto &strings = cii.m_strings.strings(); // Indices in this structure are actually offsets of records in the @@ -1234,9 +1257,9 @@ SymbolFileNativePDB::GetFileIndex(const CompilandIndexItem &cii, // LLDB wants the index of the file in the list of support files. auto fn_iter = llvm::find(cii.m_file_list, *efn); - lldbassert(fn_iter != cii.m_file_list.end()); - m_file_indexes[file_id] = std::distance(cii.m_file_list.begin(), fn_iter); - return m_file_indexes[file_id]; + if (fn_iter != cii.m_file_list.end()) + return std::distance(cii.m_file_list.begin(), fn_iter); + return llvm::make_error<RawError>(raw_error_code::no_entry); } bool SymbolFileNativePDB::ParseSupportFiles(CompileUnit &comp_unit, @@ -1293,8 +1316,8 @@ void SymbolFileNativePDB::ParseInlineSite(PdbCompilandSymId id, GetFileIndex(*cii, inlinee_line.Header->FileID); if (!file_index_or_err) return; - uint32_t decl_file_idx = file_index_or_err.get(); - decl_file = files.GetFileSpecAtIndex(decl_file_idx); + uint32_t file_offset = file_index_or_err.get(); + decl_file = files.GetFileSpecAtIndex(file_offset); uint32_t decl_line = inlinee_line.Header->SourceLineNum; std::unique_ptr<Declaration> decl_up = std::make_unique<Declaration>(decl_file, decl_line); @@ -1302,54 +1325,36 @@ void SymbolFileNativePDB::ParseInlineSite(PdbCompilandSymId id, // Parse range and line info. uint32_t code_offset = 0; int32_t line_offset = 0; - bool has_base = false; - bool is_new_line_offset = false; - - bool is_start_of_statement = false; + llvm::Optional<uint32_t> code_offset_base; + llvm::Optional<uint32_t> code_offset_end; + llvm::Optional<int32_t> cur_line_offset; + llvm::Optional<int32_t> next_line_offset; + llvm::Optional<uint32_t> next_file_offset; + + bool is_terminal_entry = false; + bool is_start_of_statement = true; // The first instruction is the prologue end. bool is_prologue_end = true; - auto change_code_offset = [&](uint32_t code_delta) { - if (has_base) { - inline_site_sp->ranges.Append(RangeSourceLineVector::Entry( - code_offset, code_delta, decl_line + line_offset)); - is_prologue_end = false; - is_start_of_statement = false; - } else { - is_start_of_statement = true; - } - has_base = true; - code_offset += code_delta; - - if (is_new_line_offset) { - LineTable::Entry line_entry(func_base + code_offset, - decl_line + line_offset, 0, decl_file_idx, - true, false, is_prologue_end, false, false); - inline_site_sp->line_entries.push_back(line_entry); - is_new_line_offset = false; - } - }; - auto change_code_length = [&](uint32_t length) { - inline_site_sp->ranges.Append(RangeSourceLineVector::Entry( - code_offset, length, decl_line + line_offset)); - has_base = false; - - LineTable::Entry end_line_entry(func_base + code_offset + length, - decl_line + line_offset, 0, decl_file_idx, - false, false, false, false, true); - inline_site_sp->line_entries.push_back(end_line_entry); + auto update_code_offset = [&](uint32_t code_delta) { + if (!code_offset_base) + code_offset_base = code_offset; + else if (!code_offset_end) + code_offset_end = *code_offset_base + code_delta; }; - auto change_line_offset = [&](int32_t line_delta) { + auto update_line_offset = [&](int32_t line_delta) { line_offset += line_delta; - if (has_base) { - LineTable::Entry line_entry( - func_base + code_offset, decl_line + line_offset, 0, decl_file_idx, - is_start_of_statement, false, is_prologue_end, false, false); - inline_site_sp->line_entries.push_back(line_entry); - } else { - // Add line entry in next call to change_code_offset. - is_new_line_offset = true; - } + if (!code_offset_base || !cur_line_offset) + cur_line_offset = line_offset; + else + next_line_offset = line_offset; + ; + }; + auto update_file_offset = [&](uint32_t offset) { + if (!code_offset_base) + file_offset = offset; + else + next_file_offset = offset; }; for (auto &annot : inline_site.annotations()) { @@ -1357,30 +1362,73 @@ void SymbolFileNativePDB::ParseInlineSite(PdbCompilandSymId id, case BinaryAnnotationsOpCode::CodeOffset: case BinaryAnnotationsOpCode::ChangeCodeOffset: case BinaryAnnotationsOpCode::ChangeCodeOffsetBase: - change_code_offset(annot.U1); + code_offset += annot.U1; + update_code_offset(annot.U1); break; case BinaryAnnotationsOpCode::ChangeLineOffset: - change_line_offset(annot.S1); + update_line_offset(annot.S1); break; case BinaryAnnotationsOpCode::ChangeCodeLength: - change_code_length(annot.U1); + update_code_offset(annot.U1); code_offset += annot.U1; + is_terminal_entry = true; break; case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: - change_code_offset(annot.U1); - change_line_offset(annot.S1); + code_offset += annot.U1; + update_code_offset(annot.U1); + update_line_offset(annot.S1); break; case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: - change_code_offset(annot.U2); - change_code_length(annot.U1); + code_offset += annot.U2; + update_code_offset(annot.U2); + update_code_offset(annot.U1); + code_offset += annot.U1; + is_terminal_entry = true; + break; + case BinaryAnnotationsOpCode::ChangeFile: + update_file_offset(annot.U1); break; default: break; } + + // Add range if current range is finished. + if (code_offset_base && code_offset_end && cur_line_offset) { + inline_site_sp->ranges.Append(RangeSourceLineVector::Entry( + *code_offset_base, *code_offset_end - *code_offset_base, + decl_line + *cur_line_offset)); + // Set base, end, file offset and line offset for next range. + if (next_file_offset) + file_offset = *next_file_offset; + if (next_line_offset) { + cur_line_offset = next_line_offset; + next_line_offset = llvm::None; + } + code_offset_base = is_terminal_entry ? llvm::None : code_offset_end; + code_offset_end = next_file_offset = llvm::None; + } + if (code_offset_base && cur_line_offset) { + if (is_terminal_entry) { + LineTable::Entry line_entry( + func_base + *code_offset_base, decl_line + *cur_line_offset, 0, + file_offset, false, false, false, false, true); + inline_site_sp->line_entries.push_back(line_entry); + } else { + LineTable::Entry line_entry(func_base + *code_offset_base, + decl_line + *cur_line_offset, 0, + file_offset, is_start_of_statement, false, + is_prologue_end, false, false); + inline_site_sp->line_entries.push_back(line_entry); + is_prologue_end = false; + is_start_of_statement = false; + } + } + if (is_terminal_entry) + is_start_of_statement = true; + is_terminal_entry = false; } inline_site_sp->ranges.Sort(); - inline_site_sp->ranges.CombineConsecutiveEntriesWithEqualData(); // Get the inlined function callsite info. std::unique_ptr<Declaration> callsite_up; @@ -1493,7 +1541,6 @@ void SymbolFileNativePDB::FindGlobalVariables( std::vector<SymbolAndOffset> results = m_index->globals().findRecordsByName( name.GetStringRef(), m_index->symrecords()); for (const SymbolAndOffset &result : results) { - VariableSP var; switch (result.second.kind()) { case SymbolKind::S_GDATA32: case SymbolKind::S_LDATA32: @@ -1501,8 +1548,8 @@ void SymbolFileNativePDB::FindGlobalVariables( case SymbolKind::S_LTHREAD32: case SymbolKind::S_CONSTANT: { PdbGlobalSymId global(result.first, false); - var = GetOrCreateGlobalVariable(global); - variables.AddVariable(var); + if (VariableSP var = GetOrCreateGlobalVariable(global)) + variables.AddVariable(var); break; } default: @@ -1655,6 +1702,7 @@ VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id, SymbolFileTypeSP sftype = std::make_shared<SymbolFileType>(*this, type_sp->GetID()); + is_param |= var_info.is_param; ValueType var_scope = is_param ? eValueTypeVariableArgument : eValueTypeVariableLocal; bool external = false; @@ -1663,7 +1711,7 @@ VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id, bool static_member = false; VariableSP var_sp = std::make_shared<Variable>( toOpaqueUid(var_id), name.c_str(), name.c_str(), sftype, var_scope, - comp_unit_sp.get(), *var_info.ranges, &decl, *var_info.location, external, + &block, *var_info.ranges, &decl, *var_info.location, external, artificial, location_is_constant_data, static_member); if (!is_param) @@ -1731,8 +1779,7 @@ size_t SymbolFileNativePDB::ParseVariablesForBlock(PdbCompilandSymId block_id) { case S_BLOCK32: break; case S_INLINESITE: - // TODO: Handle inline site case. - return 0; + break; default: lldbassert(false && "Symbol is not a block!"); return 0; @@ -1759,8 +1806,10 @@ size_t SymbolFileNativePDB::ParseVariablesForBlock(PdbCompilandSymId block_id) { PdbCompilandSymId child_sym_id(block_id.modi, record_offset); ++iter; - // If this is a block, recurse into its children and then skip it. - if (variable_cvs.kind() == S_BLOCK32) { + // If this is a block or inline site, recurse into its children and then + // skip it. + if (variable_cvs.kind() == S_BLOCK32 || + variable_cvs.kind() == S_INLINESITE) { uint32_t block_end = getScopeEndOffset(variable_cvs); count += ParseVariablesForBlock(child_sym_id); iter = syms.at(block_end); @@ -1824,7 +1873,7 @@ size_t SymbolFileNativePDB::ParseVariablesForContext(const SymbolContext &sc) { CompilerDecl SymbolFileNativePDB::GetDeclForUID(lldb::user_id_t uid) { if (auto decl = m_ast->GetOrCreateDeclForUid(uid)) - return decl.getValue(); + return *decl; else return CompilerDecl(); } @@ -1904,4 +1953,3 @@ uint64_t SymbolFileNativePDB::GetDebugInfoSize() { // PDB files are a separate file that contains all debug info. return m_index->pdb().getFileSize(); } - 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 f1b6e34ca346..187791b0fd01 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h @@ -39,7 +39,7 @@ namespace lldb_private { namespace npdb { class PdbAstBuilder; -class SymbolFileNativePDB : public SymbolFile { +class SymbolFileNativePDB : public SymbolFileCommon { friend class UdtRecordCompleter; /// LLVM RTTI support. @@ -49,7 +49,7 @@ public: /// LLVM RTTI support. /// \{ bool isA(const void *ClassID) const override { - return ClassID == &ID || SymbolFile::isA(ClassID); + return ClassID == &ID || SymbolFileCommon::isA(ClassID); } static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } /// \} @@ -272,8 +272,6 @@ private: llvm::DenseMap<lldb::user_id_t, lldb::CompUnitSP> m_compilands; llvm::DenseMap<lldb::user_id_t, lldb::TypeSP> m_types; llvm::DenseMap<lldb::user_id_t, std::shared_ptr<InlineSite>> m_inline_sites; - // A map from file id in records to file index in support files. - llvm::DenseMap<uint32_t, uint32_t> m_file_indexes; }; } // namespace npdb diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp index d0b27bc5bf79..c0308196c760 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp @@ -10,6 +10,7 @@ #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Symbol/Type.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/lldb-enumerations.h" #include "lldb/lldb-forward.h" @@ -65,11 +66,12 @@ clang::QualType UdtRecordCompleter::AddBaseClassForTypeIndex( std::unique_ptr<clang::CXXBaseSpecifier> base_spec = m_ast_builder.clang().CreateBaseClassSpecifier( qt.getAsOpaquePtr(), TranslateMemberAccess(access), - vtable_idx.hasValue(), udt_cvt.kind() == LF_CLASS); - lldbassert(base_spec); + vtable_idx.has_value(), udt_cvt.kind() == LF_CLASS); + if (!base_spec) + return {}; m_bases.push_back( - std::make_pair(vtable_idx.getValueOr(0), std::move(base_spec))); + std::make_pair(vtable_idx.value_or(0), std::move(base_spec))); return qt; } @@ -79,6 +81,8 @@ void UdtRecordCompleter::AddMethod(llvm::StringRef name, TypeIndex type_idx, MemberAttributes attrs) { clang::QualType method_qt = m_ast_builder.GetOrCreateType(PdbTypeSymId(type_idx)); + if (method_qt.isNull()) + return; m_ast_builder.CompleteType(method_qt); CompilerType method_ct = m_ast_builder.ToCompilerType(method_qt); lldb::opaque_compiler_type_t derived_opaque_ty = m_derived_ct.GetOpaqueQualType(); @@ -105,6 +109,8 @@ Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, clang::QualType base_qt = AddBaseClassForTypeIndex(base.Type, base.getAccess()); + if (base_qt.isNull()) + return llvm::Error::success(); auto decl = m_ast_builder.clang().GetAsCXXRecordDecl(base_qt.getAsOpaquePtr()); lldbassert(decl); @@ -136,8 +142,8 @@ Error UdtRecordCompleter::visitKnownMember( CVMemberRecord &cvr, StaticDataMemberRecord &static_data_member) { clang::QualType member_type = m_ast_builder.GetOrCreateType(PdbTypeSymId(static_data_member.Type)); - - m_ast_builder.CompleteType(member_type); + if (member_type.isNull()) + return llvm::Error::success(); CompilerType member_ct = m_ast_builder.ToCompilerType(member_type); @@ -148,7 +154,7 @@ Error UdtRecordCompleter::visitKnownMember( // Static constant members may be a const[expr] declaration. // Query the symbol's value as the variable initializer if valid. - if (member_ct.IsConst()) { + if (member_ct.IsConst() && member_ct.IsCompleteType()) { std::string qual_name = decl->getQualifiedNameAsString(); auto results = @@ -169,7 +175,7 @@ Error UdtRecordCompleter::visitKnownMember( TypeSystemClang::SetIntegerInitializerForVariable( decl, constant.Value.extOrTrunc(type_width)); } else { - LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST), + LLDB_LOG(GetLog(LLDBLog::AST), "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) " "which resolves to a wider constant value ({4} bits). " "Ignoring constant.", @@ -190,7 +196,7 @@ Error UdtRecordCompleter::visitKnownMember( decl->setConstexpr(true); } else { LLDB_LOG( - GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST), + GetLog(LLDBLog::AST), "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) " "which resolves to a constant value of mismatched width " "({4} bits). Ignoring constant.", @@ -236,6 +242,8 @@ Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, } clang::QualType member_qt = m_ast_builder.GetOrCreateType(PdbTypeSymId(ti)); + if (member_qt.isNull()) + return Error::success(); m_ast_builder.CompleteType(member_qt); lldb::AccessType access = TranslateMemberAccess(data_member.getAccess()); @@ -289,10 +297,7 @@ Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, void UdtRecordCompleter::complete() { // Ensure the correct order for virtual bases. - std::stable_sort(m_bases.begin(), m_bases.end(), - [](const IndexedBase &lhs, const IndexedBase &rhs) { - return lhs.first < rhs.first; - }); + llvm::stable_sort(m_bases, llvm::less_first()); std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases; bases.reserve(m_bases.size()); 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 f45287fd0fff..c3f424d06c54 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp @@ -22,13 +22,15 @@ #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/TypeMap.h" #include "lldb/Symbol/TypeSystem.h" - +#include "lldb/Utility/LLDBLog.h" +#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h" #include "llvm/DebugInfo/PDB/IPDBLineNumber.h" #include "llvm/DebugInfo/PDB/IPDBSourceFile.h" #include "llvm/DebugInfo/PDB/PDBSymbol.h" #include "llvm/DebugInfo/PDB/PDBSymbolData.h" #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h" @@ -709,7 +711,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { bytes = size; Encoding encoding = TranslateBuiltinEncoding(builtin_kind); CompilerType builtin_ast_type = GetBuiltinTypeForPDBEncodingAndBitSize( - m_ast, *builtin_type, encoding, bytes.getValueOr(0) * 8); + m_ast, *builtin_type, encoding, bytes.value_or(0) * 8); if (builtin_type->isConstType()) builtin_ast_type = builtin_ast_type.AddConstModifier(); @@ -799,7 +801,8 @@ bool PDBASTParser::CompleteTypeFromPDB( if (uid_it == m_forward_decl_to_uid.end()) return true; - auto symbol_file = static_cast<SymbolFilePDB *>(m_ast.GetSymbolFile()); + auto symbol_file = static_cast<SymbolFilePDB *>( + m_ast.GetSymbolFile()->GetBackingSymbolFile()); if (!symbol_file) return false; @@ -833,7 +836,8 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) { if (it != m_uid_to_decl.end()) return it->second; - auto symbol_file = static_cast<SymbolFilePDB *>(m_ast.GetSymbolFile()); + auto symbol_file = static_cast<SymbolFilePDB *>( + m_ast.GetSymbolFile()->GetBackingSymbolFile()); if (!symbol_file) return nullptr; @@ -999,7 +1003,8 @@ PDBASTParser::GetDeclContextForSymbol(const llvm::pdb::PDBSymbol &symbol) { return result; } - auto symbol_file = static_cast<SymbolFilePDB *>(m_ast.GetSymbolFile()); + auto symbol_file = static_cast<SymbolFilePDB *>( + m_ast.GetSymbolFile()->GetBackingSymbolFile()); if (!symbol_file) return nullptr; @@ -1039,7 +1044,8 @@ clang::DeclContext *PDBASTParser::GetDeclContextContainingSymbol( if (specs.empty()) return m_ast.GetTranslationUnitDecl(); - auto symbol_file = static_cast<SymbolFilePDB *>(m_ast.GetSymbolFile()); + auto symbol_file = static_cast<SymbolFilePDB *>( + m_ast.GetSymbolFile()->GetBackingSymbolFile()); if (!symbol_file) return m_ast.GetTranslationUnitDecl(); @@ -1092,7 +1098,8 @@ clang::DeclContext *PDBASTParser::GetDeclContextContainingSymbol( void PDBASTParser::ParseDeclsForDeclContext( const clang::DeclContext *decl_context) { - auto symbol_file = static_cast<SymbolFilePDB *>(m_ast.GetSymbolFile()); + auto symbol_file = static_cast<SymbolFilePDB *>( + m_ast.GetSymbolFile()->GetBackingSymbolFile()); if (!symbol_file) return; @@ -1298,7 +1305,7 @@ void PDBASTParser::AddRecordMembers( TypeSystemClang::SetIntegerInitializerForVariable( decl, value.toAPSInt().extOrTrunc(type_width)); } else { - LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST), + LLDB_LOG(GetLog(LLDBLog::AST), "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) " "which resolves to a wider constant value ({4} bits). " "Ignoring constant.", @@ -1316,7 +1323,7 @@ void PDBASTParser::AddRecordMembers( decl, value.toAPFloat()); decl->setConstexpr(true); } else { - LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST), + LLDB_LOG(GetLog(LLDBLog::AST), "Class '{0}' has a member '{1}' of type '{2}' ({3} " "bits) which resolves to a constant value of mismatched " "width ({4} bits). Ignoring constant.", diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp index 330188e29f00..96e9de704e41 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp @@ -25,6 +25,7 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::npdb; +using namespace lldb_private::dwarf; using namespace llvm::pdb; static std::unique_ptr<IPDBFrameData> 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 a40b6ec9a635..bd3d16aad6c2 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -24,9 +24,11 @@ #include "lldb/Symbol/TypeList.h" #include "lldb/Symbol/TypeMap.h" #include "lldb/Symbol/Variable.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegularExpression.h" +#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h" #include "llvm/DebugInfo/PDB/GenericError.h" #include "llvm/DebugInfo/PDB/IPDBDataStream.h" #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" @@ -44,7 +46,9 @@ #include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h" #include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h" #include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" @@ -53,7 +57,7 @@ #include "Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h" #if defined(_WIN32) -#include "llvm/Config/config.h" +#include "llvm/Config/llvm-config.h" #endif using namespace lldb; @@ -73,6 +77,8 @@ lldb::LanguageType TranslateLanguage(PDB_Lang lang) { return lldb::LanguageType::eLanguageTypeC; case PDB_Lang::Swift: return lldb::LanguageType::eLanguageTypeSwift; + case PDB_Lang::Rust: + return lldb::LanguageType::eLanguageTypeRust; default: return lldb::LanguageType::eLanguageTypeUnknown; } @@ -129,7 +135,7 @@ SymbolFilePDB::CreateInstance(ObjectFileSP objfile_sp) { } SymbolFilePDB::SymbolFilePDB(lldb::ObjectFileSP objfile_sp) - : SymbolFile(std::move(objfile_sp)), m_session_up(), m_global_scope_up() {} + : SymbolFileCommon(std::move(objfile_sp)), m_session_up(), m_global_scope_up() {} SymbolFilePDB::~SymbolFilePDB() = default; @@ -307,8 +313,8 @@ SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(const PDBSymbolFunc &pdb_func, LanguageType lang = ParseLanguage(comp_unit); auto type_system_or_err = GetTypeSystemForLanguage(lang); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Unable to parse PDBFunc"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Unable to parse PDBFunc"); return nullptr; } @@ -557,8 +563,8 @@ lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) { auto type_system_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Unable to ResolveTypeUID"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Unable to ResolveTypeUID"); return nullptr; } @@ -594,8 +600,8 @@ bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) { auto type_system_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Unable to get dynamic array info for UID"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Unable to get dynamic array info for UID"); return false; } @@ -616,8 +622,8 @@ lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) { auto type_system_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Unable to get decl for UID"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Unable to get decl for UID"); return CompilerDecl(); } @@ -646,8 +652,8 @@ SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid) { auto type_system_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Unable to get DeclContext for UID"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Unable to get DeclContext for UID"); return CompilerDeclContext(); } @@ -676,8 +682,8 @@ SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid) { auto type_system_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Unable to get DeclContext containing UID"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Unable to get DeclContext containing UID"); return CompilerDeclContext(); } @@ -705,8 +711,8 @@ void SymbolFilePDB::ParseDeclsForContext( auto type_system_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Unable to parse decls for context"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Unable to parse decls for context"); return; } @@ -791,7 +797,7 @@ uint32_t SymbolFilePDB::ResolveSymbolContext( 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); + const uint32_t line = src_location_spec.GetLine().value_or(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 @@ -1445,8 +1451,8 @@ void SymbolFilePDB::DumpClangAST(Stream &s) { auto type_system_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Unable to dump ClangAST"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Unable to dump ClangAST"); return; } @@ -1658,8 +1664,8 @@ PDBASTParser *SymbolFilePDB::GetPDBAstParser() { auto type_system_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Unable to get PDB AST parser"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Unable to get PDB AST parser"); return nullptr; } @@ -1678,9 +1684,8 @@ SymbolFilePDB::FindNamespace(lldb_private::ConstString name, auto type_system_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Unable to find namespace {}", - name.AsCString()); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Unable to find namespace {}", name.AsCString()); return CompilerDeclContext(); } @@ -1974,8 +1979,7 @@ bool SymbolFilePDB::DeclContextMatchesThisSymbolFile( decl_ctx_type_system->GetMinimumLanguage(nullptr)); if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR( - lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), + GetLog(LLDBLog::Symbols), std::move(err), "Unable to determine if DeclContext matches this symbol file"); return false; } 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 69f1d268edfd..5d4b51ba2e19 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -21,7 +21,7 @@ class PDBASTParser; -class SymbolFilePDB : public lldb_private::SymbolFile { +class SymbolFilePDB : public lldb_private::SymbolFileCommon { /// LLVM RTTI support. static char ID; @@ -29,7 +29,7 @@ public: /// LLVM RTTI support. /// \{ bool isA(const void *ClassID) const override { - return ClassID == &ID || SymbolFile::isA(ClassID); + return ClassID == &ID || SymbolFileCommon::isA(ClassID); } static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } /// \} diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp index d95cfea5e872..cc22eaeef779 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp @@ -51,8 +51,8 @@ void SymbolFileSymtab::GetTypes(SymbolContextScope *sc_scope, lldb_private::TypeList &type_list) {} SymbolFileSymtab::SymbolFileSymtab(ObjectFileSP objfile_sp) - : SymbolFile(std::move(objfile_sp)), m_source_indexes(), m_func_indexes(), - m_code_indexes(), m_objc_class_name_to_index() {} + : SymbolFileCommon(std::move(objfile_sp)), m_source_indexes(), + m_func_indexes(), m_code_indexes(), m_objc_class_name_to_index() {} uint32_t SymbolFileSymtab::CalculateAbilities() { uint32_t abilities = 0; diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h index 2dad12baac6f..0a9fa5fce1b0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h @@ -15,7 +15,7 @@ #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/Symtab.h" -class SymbolFileSymtab : public lldb_private::SymbolFile { +class SymbolFileSymtab : public lldb_private::SymbolFileCommon { /// LLVM RTTI support. static char ID; @@ -23,7 +23,7 @@ public: /// LLVM RTTI support. /// \{ bool isA(const void *ClassID) const override { - return ClassID == &ID || SymbolFile::isA(ClassID); + return ClassID == &ID || SymbolFileCommon::isA(ClassID); } static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } /// \} 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 0a98f5032b77..61e06cdfa02d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp @@ -74,7 +74,7 @@ SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp, FileSpec fspec = module_sp->GetSymbolFileFileSpec(); // Otherwise, try gnu_debuglink, if one exists. if (!fspec) - fspec = obj_file->GetDebugLink().getValueOr(FileSpec()); + fspec = obj_file->GetDebugLink().value_or(FileSpec()); LLDB_SCOPED_TIMERF("SymbolVendorELF::CreateInstance (module = %s)", module_sp->GetFileSpec().GetPath().c_str()); diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/PECOFF/SymbolVendorPECOFF.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/PECOFF/SymbolVendorPECOFF.cpp new file mode 100644 index 000000000000..9b651243152c --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/PECOFF/SymbolVendorPECOFF.cpp @@ -0,0 +1,137 @@ +//===-- SymbolVendorPECOFF.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 "SymbolVendorPECOFF.h" + +#include <cstring> + +#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Section.h" +#include "lldb/Host/Host.h" +#include "lldb/Symbol/LocateSymbolFile.h" +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Target/Target.h" +#include "lldb/Utility/StreamString.h" +#include "lldb/Utility/Timer.h" + +using namespace lldb; +using namespace lldb_private; + +LLDB_PLUGIN_DEFINE(SymbolVendorPECOFF) + +// SymbolVendorPECOFF constructor +SymbolVendorPECOFF::SymbolVendorPECOFF(const lldb::ModuleSP &module_sp) + : SymbolVendor(module_sp) {} + +void SymbolVendorPECOFF::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), CreateInstance); +} + +void SymbolVendorPECOFF::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +llvm::StringRef SymbolVendorPECOFF::GetPluginDescriptionStatic() { + return "Symbol vendor for PE/COFF that looks for dSYM files that match " + "executables."; +} + +// CreateInstance +// +// Platforms can register a callback to use when creating symbol vendors to +// allow for complex debug information file setups, and to also allow for +// finding separate debug information files. +SymbolVendor * +SymbolVendorPECOFF::CreateInstance(const lldb::ModuleSP &module_sp, + lldb_private::Stream *feedback_strm) { + if (!module_sp) + return nullptr; + + ObjectFilePECOFF *obj_file = + llvm::dyn_cast_or_null<ObjectFilePECOFF>(module_sp->GetObjectFile()); + if (!obj_file) + return nullptr; + + lldb_private::UUID uuid = obj_file->GetUUID(); + if (!uuid) + return nullptr; + + // If the main object file already contains debug info, then we are done. + if (obj_file->GetSectionList()->FindSectionByType( + lldb::eSectionTypeDWARFDebugInfo, true)) + return nullptr; + + // If the module specified a filespec, use that. + FileSpec fspec = module_sp->GetSymbolFileFileSpec(); + // Otherwise, try gnu_debuglink, if one exists. + if (!fspec) + fspec = obj_file->GetDebugLink().value_or(FileSpec()); + + LLDB_SCOPED_TIMERF("SymbolVendorPECOFF::CreateInstance (module = %s)", + module_sp->GetFileSpec().GetPath().c_str()); + + ModuleSpec module_spec; + + module_spec.GetFileSpec() = obj_file->GetFileSpec(); + FileSystem::Instance().Resolve(module_spec.GetFileSpec()); + module_spec.GetSymbolFileSpec() = fspec; + module_spec.GetUUID() = uuid; + FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths(); + FileSpec dsym_fspec = + Symbols::LocateExecutableSymbolFile(module_spec, search_paths); + if (!dsym_fspec) + return nullptr; + + DataBufferSP dsym_file_data_sp; + lldb::offset_t dsym_file_data_offset = 0; + ObjectFileSP dsym_objfile_sp = ObjectFile::FindPlugin( + module_sp, &dsym_fspec, 0, FileSystem::Instance().GetByteSize(dsym_fspec), + dsym_file_data_sp, dsym_file_data_offset); + if (!dsym_objfile_sp) + return nullptr; + + // This objfile is for debugging purposes. + dsym_objfile_sp->SetType(ObjectFile::eTypeDebugInfo); + + SymbolVendorPECOFF *symbol_vendor = new SymbolVendorPECOFF(module_sp); + + // Get the module unified section list and add our debug sections to + // that. + SectionList *module_section_list = module_sp->GetSectionList(); + SectionList *objfile_section_list = dsym_objfile_sp->GetSectionList(); + if (!objfile_section_list || !module_section_list) + return nullptr; + + static const SectionType g_sections[] = { + eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAranges, + eSectionTypeDWARFDebugFrame, eSectionTypeDWARFDebugInfo, + eSectionTypeDWARFDebugLine, eSectionTypeDWARFDebugLoc, + eSectionTypeDWARFDebugLocLists, eSectionTypeDWARFDebugMacInfo, + eSectionTypeDWARFDebugNames, eSectionTypeDWARFDebugPubNames, + eSectionTypeDWARFDebugPubTypes, eSectionTypeDWARFDebugRanges, + eSectionTypeDWARFDebugStr, eSectionTypeDWARFDebugTypes, + }; + for (SectionType section_type : g_sections) { + if (SectionSP section_sp = + objfile_section_list->FindSectionByType(section_type, true)) { + if (SectionSP module_section_sp = + module_section_list->FindSectionByType(section_type, true)) + module_section_list->ReplaceSection(module_section_sp->GetID(), + section_sp); + else + module_section_list->AddSection(section_sp); + } + } + + symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp); + return symbol_vendor; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/PECOFF/SymbolVendorPECOFF.h b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/PECOFF/SymbolVendorPECOFF.h new file mode 100644 index 000000000000..ff77ca5faac8 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/PECOFF/SymbolVendorPECOFF.h @@ -0,0 +1,37 @@ +//===-- SymbolVendorPECOFF.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_SYMBOLVENDOR_PECOFF_SYMBOLVENDORPECOFF_H +#define LLDB_SOURCE_PLUGINS_SYMBOLVENDOR_PECOFF_SYMBOLVENDORPECOFF_H + +#include "lldb/Symbol/SymbolVendor.h" +#include "lldb/lldb-private.h" + +class SymbolVendorPECOFF : public lldb_private::SymbolVendor { +public: + // Constructors and Destructors + SymbolVendorPECOFF(const lldb::ModuleSP &module_sp); + + // Static Functions + static void Initialize(); + + static void Terminate(); + + static llvm::StringRef GetPluginNameStatic() { return "PE-COFF"; } + + static llvm::StringRef GetPluginDescriptionStatic(); + + static lldb_private::SymbolVendor * + CreateInstance(const lldb::ModuleSP &module_sp, + lldb_private::Stream *feedback_strm); + + // PluginInterface protocol + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } +}; + +#endif // LLDB_SOURCE_PLUGINS_SYMBOLVENDOR_PECOFF_SYMBOLVENDORPECOFF_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/common/ThreadPostMortemTrace.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/common/ThreadPostMortemTrace.cpp index 45d6f3b0e098..37239b9d4c71 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/common/ThreadPostMortemTrace.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/common/ThreadPostMortemTrace.cpp @@ -16,6 +16,7 @@ using namespace lldb; using namespace lldb_private; +using namespace llvm; void ThreadPostMortemTrace::RefreshStateAfterStop() {} @@ -36,6 +37,6 @@ ThreadPostMortemTrace::CreateRegisterContextForFrame(StackFrame *frame) { bool ThreadPostMortemTrace::CalculateStopInfo() { return false; } -const FileSpec &ThreadPostMortemTrace::GetTraceFile() const { +const Optional<FileSpec> &ThreadPostMortemTrace::GetTraceFile() const { return m_trace_file; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/common/ThreadPostMortemTrace.h b/contrib/llvm-project/lldb/source/Plugins/Trace/common/ThreadPostMortemTrace.h index 9cfe754ae0e4..cdb896cff5c5 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/common/ThreadPostMortemTrace.h +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/common/ThreadPostMortemTrace.h @@ -18,8 +18,6 @@ namespace lldb_private { /// 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 ThreadPostMortemTrace : public Thread { public: /// \param[in] process @@ -32,7 +30,7 @@ public: /// The file that contains the list of instructions that were traced when /// this thread was being executed. ThreadPostMortemTrace(Process &process, lldb::tid_t tid, - const FileSpec &trace_file) + const llvm::Optional<FileSpec> &trace_file) : Thread(process, tid), m_trace_file(trace_file) {} void RefreshStateAfterStop() override; @@ -44,7 +42,7 @@ public: /// \return /// The trace file of this thread. - const FileSpec &GetTraceFile() const; + const llvm::Optional<FileSpec> &GetTraceFile() const; protected: bool CalculateStopInfo() override; @@ -52,7 +50,7 @@ protected: lldb::RegisterContextSP m_thread_reg_ctx_sp; private: - FileSpec m_trace_file; + llvm::Optional<FileSpec> m_trace_file; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceJSONStructs.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceJSONStructs.cpp deleted file mode 100644 index 1773a6003701..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceJSONStructs.cpp +++ /dev/null @@ -1,106 +0,0 @@ -//===-- TraceSessionFileStructs.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 "TraceJSONStructs.h" -#include "ThreadPostMortemTrace.h" -#include "lldb/Core/Debugger.h" -#include "lldb/Core/Module.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/Target.h" -#include <sstream> - -using namespace lldb_private; -namespace llvm { -namespace json { - -llvm::json::Value toJSON(const JSONModule &module) { - llvm::json::Object json_module; - json_module["systemPath"] = module.system_path; - if (module.file) - json_module["file"] = *module.file; - std::ostringstream oss; - oss << "0x" << std::hex << module.load_address.value; - json_module["loadAddress"] = oss.str(); - if (module.uuid) - json_module["uuid"] = *module.uuid; - return std::move(json_module); -} - -llvm::json::Value toJSON(const JSONThread &thread) { - return Value(Object{{"tid", thread.tid}, {"traceFile", thread.trace_file}}); -} - -llvm::json::Value toJSON(const JSONProcess &process) { - llvm::json::Object json_process; - json_process["pid"] = process.pid; - json_process["triple"] = process.triple; - - llvm::json::Array threads_arr; - for (JSONThread e : process.threads) - threads_arr.push_back(toJSON(e)); - - json_process["threads"] = llvm::json::Value(std::move(threads_arr)); - - llvm::json::Array modules_arr; - for (JSONModule e : process.modules) - modules_arr.push_back(toJSON(e)); - - json_process["modules"] = llvm::json::Value(std::move(modules_arr)); - - return std::move(json_process); -} - -llvm::json::Value toJSON(const JSONTraceSessionBase &session) { - llvm::json::Array arr; - for (JSONProcess e : session.processes) - arr.push_back(toJSON(e)); - - return std::move(arr); -} - -bool fromJSON(const Value &value, JSONAddress &address, Path path) { - Optional<StringRef> s = value.getAsString(); - if (s.hasValue() && !s->getAsInteger(0, address.value)) - return true; - - path.report("expected numeric string"); - return false; -} - -bool fromJSON(const Value &value, JSONModule &module, Path path) { - ObjectMapper o(value, path); - return o && o.map("systemPath", module.system_path) && - o.map("file", module.file) && - o.map("loadAddress", module.load_address) && - o.map("uuid", module.uuid); -} - -bool fromJSON(const Value &value, JSONThread &thread, Path path) { - ObjectMapper o(value, path); - return o && o.map("tid", thread.tid) && o.map("traceFile", thread.trace_file); -} - -bool fromJSON(const Value &value, JSONProcess &process, Path path) { - ObjectMapper o(value, path); - return o && o.map("pid", process.pid) && o.map("triple", process.triple) && - o.map("threads", process.threads) && o.map("modules", process.modules); -} - -bool fromJSON(const Value &value, JSONTracePluginSettings &plugin_settings, - Path path) { - ObjectMapper o(value, path); - return o && o.map("type", plugin_settings.type); -} - -bool fromJSON(const Value &value, JSONTraceSessionBase &session, Path path) { - ObjectMapper o(value, path); - return o && o.map("processes", session.processes); -} - -} // namespace json -} // namespace llvm diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceJSONStructs.h b/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceJSONStructs.h deleted file mode 100644 index e01c33bf0d6a..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceJSONStructs.h +++ /dev/null @@ -1,98 +0,0 @@ -//===-- TraceJSONStruct.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_TRACEJSONSTRUCTS_H -#define LLDB_TARGET_TRACEJSONSTRUCTS_H - -#include "lldb/lldb-types.h" -#include "llvm/Support/JSON.h" - -namespace lldb_private { - -struct JSONAddress { - lldb::addr_t value; -}; - -struct JSONModule { - std::string system_path; - llvm::Optional<std::string> file; - JSONAddress load_address; - llvm::Optional<std::string> uuid; -}; - -struct JSONThread { - int64_t tid; - std::string trace_file; -}; - -struct JSONProcess { - int64_t pid; - std::string triple; - std::vector<JSONThread> threads; - std::vector<JSONModule> modules; -}; - -struct JSONTracePluginSettings { - std::string type; -}; - -struct JSONTraceSessionBase { - std::vector<JSONProcess> processes; -}; - -/// The trace plug-in implementation should provide its own TPluginSettings, -/// which corresponds to the "trace" section of the schema. -template <class TPluginSettings> -struct JSONTraceSession : JSONTraceSessionBase { - TPluginSettings trace; -}; - -} // namespace lldb_private - -namespace llvm { -namespace json { - -llvm::json::Value toJSON(const lldb_private::JSONModule &module); - -llvm::json::Value toJSON(const lldb_private::JSONThread &thread); - -llvm::json::Value toJSON(const lldb_private::JSONProcess &process); - -llvm::json::Value -toJSON(const lldb_private::JSONTraceSessionBase &session_base); - -bool fromJSON(const Value &value, lldb_private::JSONAddress &address, - Path path); - -bool fromJSON(const Value &value, lldb_private::JSONModule &module, Path path); - -bool fromJSON(const Value &value, lldb_private::JSONThread &thread, Path path); - -bool fromJSON(const Value &value, lldb_private::JSONProcess &process, - Path path); - -bool fromJSON(const Value &value, - lldb_private::JSONTracePluginSettings &plugin_settings, - Path path); - -bool fromJSON(const Value &value, lldb_private::JSONTraceSessionBase &session, - Path path); - -template <class TPluginSettings> -bool fromJSON(const Value &value, - lldb_private::JSONTraceSession<TPluginSettings> &session, - Path path) { - ObjectMapper o(value, path); - return o && o.map("trace", session.trace) && - fromJSON(value, (lldb_private::JSONTraceSessionBase &)session, path); -} - -} // namespace json -} // namespace llvm - -#endif // LLDB_TARGET_TRACEJSONSTRUCTS_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.cpp deleted file mode 100644 index b26704ca34be..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.cpp +++ /dev/null @@ -1,172 +0,0 @@ -//===-- TraceSessionFileParser.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 "TraceSessionFileParser.h" -#include "ThreadPostMortemTrace.h" - -#include <sstream> - -#include "lldb/Core/Debugger.h" -#include "lldb/Core/Module.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/Target.h" - -using namespace lldb; -using namespace lldb_private; -using namespace llvm; - -void TraceSessionFileParser::NormalizePath(lldb_private::FileSpec &file_spec) { - if (file_spec.IsRelative()) - file_spec.PrependPathComponent(m_session_file_dir); -} - -Error TraceSessionFileParser::ParseModule(lldb::TargetSP &target_sp, - const JSONModule &module) { - FileSpec system_file_spec(module.system_path); - NormalizePath(system_file_spec); - - FileSpec local_file_spec(module.file.hasValue() ? *module.file - : module.system_path); - NormalizePath(local_file_spec); - - ModuleSpec module_spec; - module_spec.GetFileSpec() = local_file_spec; - module_spec.GetPlatformFileSpec() = system_file_spec; - - if (module.uuid.hasValue()) - module_spec.GetUUID().SetFromStringRef(*module.uuid); - - Status error; - ModuleSP module_sp = - target_sp->GetOrCreateModule(module_spec, /*notify*/ false, &error); - - if (error.Fail()) - return error.ToError(); - - bool load_addr_changed = false; - module_sp->SetLoadAddress(*target_sp, module.load_address.value, false, - load_addr_changed); - return llvm::Error::success(); -} - -Error TraceSessionFileParser::CreateJSONError(json::Path::Root &root, - const json::Value &value) { - std::string err; - raw_string_ostream os(err); - root.printErrorContext(value, os); - return createStringError( - std::errc::invalid_argument, "%s\n\nContext:\n%s\n\nSchema:\n%s", - toString(root.getError()).c_str(), os.str().c_str(), m_schema.data()); -} - -std::string TraceSessionFileParser::BuildSchema(StringRef plugin_schema) { - std::ostringstream schema_builder; - schema_builder << "{\n \"trace\": "; - schema_builder << plugin_schema.data() << ","; - schema_builder << R"( - "processes": [ - { - "pid": integer, - "triple": string, // llvm-triple - "threads": [ - { - "tid": integer, - "traceFile": string - } - ], - "modules": [ - { - "systemPath": string, // original path of the module at runtime - "file"?: string, // copy of the file if not available at "systemPath" - "loadAddress": string, // string address in hex or decimal form - "uuid"?: string, - } - ] - } - ] - // Notes: - // All paths are either absolute or relative to the session file. -} -)"; - return schema_builder.str(); -} - -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); - - ThreadPostMortemTraceSP thread_sp = - std::make_shared<ThreadPostMortemTrace>(*process_sp, tid, trace_file); - process_sp->GetThreadList().AddThread(thread_sp); - return thread_sp; -} - -Expected<TraceSessionFileParser::ParsedProcess> -TraceSessionFileParser::ParseProcess(const JSONProcess &process) { - TargetSP target_sp; - Status error = m_debugger.GetTargetList().CreateTarget( - m_debugger, /*user_exe_path*/ StringRef(), process.triple, - eLoadDependentsNo, - /*platform_options*/ nullptr, target_sp); - - if (!target_sp) - return error.ToError(); - - ParsedProcess parsed_process; - parsed_process.target_sp = target_sp; - - ProcessSP process_sp = target_sp->CreateProcess( - /*listener*/ nullptr, "trace", - /*crash_file*/ nullptr, - /*can_connect*/ false); - - process_sp->SetID(static_cast<lldb::pid_t>(process.pid)); - - for (const JSONThread &thread : process.threads) - parsed_process.threads.push_back(ParseThread(process_sp, thread)); - - for (const JSONModule &module : process.modules) - if (Error err = ParseModule(target_sp, module)) - return std::move(err); - - if (!process.threads.empty()) - process_sp->GetThreadList().SetSelectedThreadByIndexID(0); - - // We invoke DidAttach to create a correct stopped state for the process and - // its threads. - ArchSpec process_arch; - process_sp->DidAttach(process_arch); - - return parsed_process; -} - -Expected<std::vector<TraceSessionFileParser::ParsedProcess>> -TraceSessionFileParser::ParseCommonSessionFile( - const JSONTraceSessionBase &session) { - std::vector<ParsedProcess> parsed_processes; - - auto onError = [&]() { - // Delete all targets that were created so far in case of failures - for (ParsedProcess &parsed_process : parsed_processes) - m_debugger.GetTargetList().DeleteTarget(parsed_process.target_sp); - }; - - for (const JSONProcess &process : session.processes) { - if (Expected<ParsedProcess> parsed_process = ParseProcess(process)) - parsed_processes.push_back(std::move(*parsed_process)); - else { - onError(); - return parsed_process.takeError(); - } - } - return parsed_processes; -} diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.h b/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.h deleted file mode 100644 index 19cc2f59ded7..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.h +++ /dev/null @@ -1,93 +0,0 @@ -//===-- TraceSessionFileParser.h --------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_TARGET_TRACESESSIONPARSER_H -#define LLDB_TARGET_TRACESESSIONPARSER_H - -#include "ThreadPostMortemTrace.h" -#include "TraceJSONStructs.h" - -namespace lldb_private { - -/// \class TraceSessionFileParser TraceSessionFileParser.h -/// -/// Base class for parsing the common information of JSON trace session files. -/// Contains the basic C++ structs that represent the JSON data, which include -/// \a JSONTraceSession as the root object. -/// -/// See \a Trace::FindPlugin for more information regarding these JSON files. -class TraceSessionFileParser { -public: - - /// Helper struct holding the objects created when parsing a process - struct ParsedProcess { - lldb::TargetSP target_sp; - std::vector<lldb::ThreadPostMortemTraceSP> threads; - }; - - TraceSessionFileParser(Debugger &debugger, llvm::StringRef session_file_dir, - llvm::StringRef schema) - : m_debugger(debugger), m_session_file_dir(session_file_dir), - m_schema(schema) {} - - /// Build the full schema for a Trace plug-in. - /// - /// \param[in] plugin_schema - /// The subschema that corresponds to the "trace" section of the schema. - /// - /// \return - /// The full schema containing the common attributes and the plug-in - /// specific attributes. - static std::string BuildSchema(llvm::StringRef plugin_schema); - - /// Parse the fields common to all trace session schemas. - /// - /// \param[in] session - /// The session json objects already deserialized. - /// - /// \return - /// A list of \a ParsedProcess containing all threads and targets created - /// during the parsing, or an error in case of failures. In case of - /// errors, no side effects are produced. - llvm::Expected<std::vector<ParsedProcess>> - ParseCommonSessionFile(const JSONTraceSessionBase &session); - -protected: - /// Resolve non-absolute paths relative to the session file folder. It - /// modifies the given file_spec. - void NormalizePath(lldb_private::FileSpec &file_spec); - - lldb::ThreadPostMortemTraceSP ParseThread(lldb::ProcessSP &process_sp, - const JSONThread &thread); - - llvm::Expected<ParsedProcess> ParseProcess(const JSONProcess &process); - - llvm::Error ParseModule(lldb::TargetSP &target_sp, const JSONModule &module); - - /// Create a user-friendly error message upon a JSON-parsing failure using the - /// \a json::ObjectMapper functionality. - /// - /// \param[in] root - /// The \a llvm::json::Path::Root used to parse the JSON \a value. - /// - /// \param[in] value - /// The json value that failed to parse. - /// - /// \return - /// An \a llvm::Error containing the user-friendly error message. - llvm::Error CreateJSONError(llvm::json::Path::Root &root, - const llvm::json::Value &value); - - Debugger &m_debugger; - std::string m_session_file_dir; - llvm::StringRef m_schema; -}; -} // namespace lldb_private - - -#endif // LLDB_TARGET_TRACESESSIONPARSER_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionSaver.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionSaver.cpp deleted file mode 100644 index 8c20a3b158cd..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionSaver.cpp +++ /dev/null @@ -1,149 +0,0 @@ -//===-- TraceSessionSaver.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 "TraceSessionSaver.h" - -#include "lldb/Core/Module.h" -#include "lldb/Core/Value.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/SectionLoadList.h" -#include "lldb/Target/Target.h" -#include "lldb/lldb-types.h" -#include "llvm/Support/Error.h" -#include "llvm/Support/JSON.h" - -#include <fstream> - -using namespace lldb; -using namespace lldb_private; -using namespace llvm; - -llvm::Error TraceSessionSaver::WriteSessionToFile( - const llvm::json::Value &trace_session_description, FileSpec directory) { - - FileSpec trace_path = directory; - trace_path.AppendPathComponent("trace.json"); - std::ofstream os(trace_path.GetPath()); - os << std::string(formatv("{0:2}", trace_session_description)); - os.close(); - if (!os) - return createStringError(inconvertibleErrorCode(), - formatv("couldn't write to the file {0}", - trace_path.GetPath().c_str())); - return Error::success(); -} - -llvm::Expected<JSONTraceSessionBase> TraceSessionSaver::BuildProcessesSection( - Process &live_process, - std::function< - llvm::Expected<llvm::Optional<std::vector<uint8_t>>>(lldb::tid_t tid)> - raw_trace_fetcher, - FileSpec directory) { - - JSONTraceSessionBase json_session_description; - Expected<std::vector<JSONThread>> json_threads = - BuildThreadsSection(live_process, raw_trace_fetcher, directory); - if (!json_threads) - return json_threads.takeError(); - - Expected<std::vector<JSONModule>> json_modules = - BuildModulesSection(live_process, directory); - if (!json_modules) - return json_modules.takeError(); - - json_session_description.processes.push_back(JSONProcess{ - static_cast<int64_t>(live_process.GetID()), - live_process.GetTarget().GetArchitecture().GetTriple().getTriple(), - json_threads.get(), json_modules.get()}); - return json_session_description; -} - -llvm::Expected<std::vector<JSONThread>> TraceSessionSaver::BuildThreadsSection( - Process &live_process, - std::function< - llvm::Expected<llvm::Optional<std::vector<uint8_t>>>(lldb::tid_t tid)> - raw_trace_fetcher, - FileSpec directory) { - std::vector<JSONThread> json_threads; - for (ThreadSP thread_sp : live_process.Threads()) { - // resolve the directory just in case - FileSystem::Instance().Resolve(directory); - FileSpec raw_trace_path = directory; - raw_trace_path.AppendPathComponent(std::to_string(thread_sp->GetID()) + - ".trace"); - json_threads.push_back(JSONThread{static_cast<int64_t>(thread_sp->GetID()), - raw_trace_path.GetPath().c_str()}); - - llvm::Expected<llvm::Optional<std::vector<uint8_t>>> raw_trace = - raw_trace_fetcher(thread_sp->GetID()); - - if (!raw_trace) - return raw_trace.takeError(); - if (!raw_trace.get()) - continue; - - std::basic_fstream<char> raw_trace_fs = std::fstream( - raw_trace_path.GetPath().c_str(), std::ios::out | std::ios::binary); - raw_trace_fs.write(reinterpret_cast<const char *>(&raw_trace.get()->at(0)), - raw_trace.get()->size() * sizeof(uint8_t)); - raw_trace_fs.close(); - if (!raw_trace_fs) { - return createStringError(inconvertibleErrorCode(), - formatv("couldn't write to the file {0}", - raw_trace_path.GetPath().c_str())); - } - } - return json_threads; -} - -llvm::Expected<std::vector<JSONModule>> -TraceSessionSaver::BuildModulesSection(Process &live_process, - FileSpec directory) { - std::vector<JSONModule> json_modules; - ModuleList module_list = live_process.GetTarget().GetImages(); - for (size_t i = 0; i < module_list.GetSize(); ++i) { - ModuleSP module_sp(module_list.GetModuleAtIndex(i)); - if (!module_sp) - continue; - std::string system_path = module_sp->GetPlatformFileSpec().GetPath(); - // TODO: support memory-only libraries like [vdso] - if (!module_sp->GetFileSpec().IsAbsolute()) - continue; - - std::string file = module_sp->GetFileSpec().GetPath(); - ObjectFile *objfile = module_sp->GetObjectFile(); - if (objfile == nullptr) - continue; - - lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; - Address base_addr(objfile->GetBaseAddress()); - if (base_addr.IsValid() && - !live_process.GetTarget().GetSectionLoadList().IsEmpty()) - load_addr = base_addr.GetLoadAddress(&live_process.GetTarget()); - - if (load_addr == LLDB_INVALID_ADDRESS) - continue; - - FileSystem::Instance().Resolve(directory); - FileSpec path_to_copy_module = directory; - path_to_copy_module.AppendPathComponent("modules"); - path_to_copy_module.AppendPathComponent(system_path); - sys::fs::create_directories(path_to_copy_module.GetDirectory().AsCString()); - - if (std::error_code ec = llvm::sys::fs::copy_file( - system_path, path_to_copy_module.GetPath())) - return createStringError( - inconvertibleErrorCode(), - formatv("couldn't write to the file. {0}", ec.message())); - - json_modules.push_back( - JSONModule{system_path, path_to_copy_module.GetPath(), - JSONAddress{load_addr}, module_sp->GetUUID().GetAsString()}); - } - return json_modules; -} diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionSaver.h b/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionSaver.h deleted file mode 100644 index 9a1a75c167dc..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionSaver.h +++ /dev/null @@ -1,112 +0,0 @@ -//===-- SessionSaver.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_TRACESESSIONSAVER_H -#define LLDB_TARGET_TRACESESSIONSAVER_H - -#include "TraceJSONStructs.h" - -namespace lldb_private { - -class TraceSessionSaver { - -public: - /// Save the trace session description JSON object inside the given directory - /// as a file named \a trace.json. - /// - /// \param[in] trace_session_description - /// The trace's session, as JSON Object. - /// - /// \param[in] directory - /// The directory where the JSON file will be saved. - /// - /// \return - /// \a llvm::success if the operation was successful, or an \a llvm::Error - /// otherwise. - static llvm::Error - WriteSessionToFile(const llvm::json::Value &trace_session_description, - FileSpec directory); - - /// Build the processes section of the trace session description file. Besides - /// returning the processes information, this method saves to disk all modules - /// and raw traces corresponding to the traced threads of the given process. - /// - /// \param[in] live_process - /// The process being traced. - /// - /// \param[in] raw_trace_fetcher - /// Callback function that receives a thread ID and returns its raw trace. - /// This callback should return \a None if the thread is not being traced. - /// Otherwise, it should return the raw trace in bytes or an - /// \a llvm::Error in case of failures. - /// - /// \param[in] directory - /// The directory where files will be saved when building the processes - /// section. - /// - /// \return - /// The processes section or \a llvm::Error in case of failures. - static llvm::Expected<JSONTraceSessionBase> BuildProcessesSection( - Process &live_process, - std::function< - llvm::Expected<llvm::Optional<std::vector<uint8_t>>>(lldb::tid_t tid)> - raw_trace_fetcher, - FileSpec directory); - - /// Build the threads sub-section of the trace session description file. - /// For each traced thread, its raw trace is also written to the file - /// \a thread_id_.trace inside of the given directory. - /// - /// \param[in] live_process - /// The process being traced. - /// - /// \param[in] raw_trace_fetcher - /// Callback function that receives a thread ID and returns its raw trace. - /// This callback should return \a None if the thread is not being traced. - /// Otherwise, it should return the raw trace in bytes or an - /// \a llvm::Error in case of failures. - /// - /// \param[in] directory - /// The directory where files will be saved when building the threads - /// section. - /// - /// \return - /// The threads section or \a llvm::Error in case of failures. - static llvm::Expected<std::vector<JSONThread>> BuildThreadsSection( - Process &live_process, - std::function< - llvm::Expected<llvm::Optional<std::vector<uint8_t>>>(lldb::tid_t tid)> - raw_trace_fetcher, - FileSpec directory); - - /// Build modules sub-section of the trace's session. The original modules - /// will be copied over to the \a <directory/modules> folder. Invalid modules - /// are skipped. - /// Copying the modules has the benefit of making these trace session - /// directories self-contained, as the raw traces and modules are part of the - /// output directory and can be sent to another machine, where lldb can load - /// them and replicate exactly the same trace session. - /// - /// \param[in] live_process - /// The process being traced. - /// - /// \param[in] directory - /// The directory where the modules files will be saved when building - /// the modules section. - /// Example: If a module \a libbar.so exists in the path - /// \a /usr/lib/foo/libbar.so, then it will be copied to - /// \a <directory>/modules/usr/lib/foo/libbar.so. - /// - /// \return - /// The modules section or \a llvm::Error in case of failures. - static llvm::Expected<std::vector<JSONModule>> - BuildModulesSection(Process &live_process, FileSpec directory); -}; -} // namespace lldb_private - -#endif // LLDB_TARGET_TRACESESSIONSAVER_H 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 5650af657c5e..6c386f6a83fa 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 @@ -32,13 +32,13 @@ Status CommandObjectThreadTraceStartIntelPT::CommandOptions::SetOptionValue( 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) + int64_t ipt_trace_size; + if (option_arg.empty() || option_arg.getAsInteger(0, ipt_trace_size) || + ipt_trace_size < 0) error.SetErrorStringWithFormat("invalid integer value for option '%s'", option_arg.str().c_str()); else - m_thread_buffer_size = thread_buffer_size; + m_ipt_trace_size = ipt_trace_size; break; } case 't': { @@ -63,7 +63,7 @@ Status CommandObjectThreadTraceStartIntelPT::CommandOptions::SetOptionValue( void CommandObjectThreadTraceStartIntelPT::CommandOptions:: OptionParsingStarting(ExecutionContext *execution_context) { - m_thread_buffer_size = kDefaultThreadBufferSize; + m_ipt_trace_size = kDefaultIptTraceSize; m_enable_tsc = kDefaultEnableTscValue; m_psb_period = kDefaultPsbPeriod; } @@ -76,7 +76,7 @@ CommandObjectThreadTraceStartIntelPT::CommandOptions::GetDefinitions() { 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, + if (Error err = m_trace.Start(tids, m_options.m_ipt_trace_size, m_options.m_enable_tsc, m_options.m_psb_period)) result.SetError(Status(std::move(err))); else @@ -98,13 +98,13 @@ Status CommandObjectProcessTraceStartIntelPT::CommandOptions::SetOptionValue( 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) + int64_t ipt_trace_size; + if (option_arg.empty() || option_arg.getAsInteger(0, ipt_trace_size) || + ipt_trace_size < 0) error.SetErrorStringWithFormat("invalid integer value for option '%s'", option_arg.str().c_str()); else - m_thread_buffer_size = thread_buffer_size; + m_ipt_trace_size = ipt_trace_size; break; } case 'l': { @@ -122,6 +122,10 @@ Status CommandObjectProcessTraceStartIntelPT::CommandOptions::SetOptionValue( m_enable_tsc = true; break; } + case 'c': { + m_per_cpu_tracing = true; + break; + } case 'p': { int64_t psb_period; if (option_arg.empty() || option_arg.getAsInteger(0, psb_period) || @@ -140,10 +144,11 @@ Status CommandObjectProcessTraceStartIntelPT::CommandOptions::SetOptionValue( void CommandObjectProcessTraceStartIntelPT::CommandOptions:: OptionParsingStarting(ExecutionContext *execution_context) { - m_thread_buffer_size = kDefaultThreadBufferSize; + m_ipt_trace_size = kDefaultIptTraceSize; m_process_buffer_size_limit = kDefaultProcessBufferSizeLimit; m_enable_tsc = kDefaultEnableTscValue; m_psb_period = kDefaultPsbPeriod; + m_per_cpu_tracing = kDefaultPerCpuTracing; } llvm::ArrayRef<OptionDefinition> @@ -153,9 +158,10 @@ CommandObjectProcessTraceStartIntelPT::CommandOptions::GetDefinitions() { bool CommandObjectProcessTraceStartIntelPT::DoExecute( Args &command, CommandReturnObject &result) { - if (Error err = m_trace.Start(m_options.m_thread_buffer_size, + if (Error err = m_trace.Start(m_options.m_ipt_trace_size, m_options.m_process_buffer_size_limit, - m_options.m_enable_tsc, m_options.m_psb_period)) + m_options.m_enable_tsc, m_options.m_psb_period, + m_options.m_per_cpu_tracing)) result.SetError(Status(std::move(err))); else result.SetStatus(eReturnStatusSuccessFinishResult); 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 2f3d53a86406..b5d6a0f24043 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 @@ -31,9 +31,9 @@ public: llvm::ArrayRef<OptionDefinition> GetDefinitions() override; - size_t m_thread_buffer_size; + uint64_t m_ipt_trace_size; bool m_enable_tsc; - llvm::Optional<size_t> m_psb_period; + llvm::Optional<uint64_t> m_psb_period; }; CommandObjectThreadTraceStartIntelPT(TraceIntelPT &trace, @@ -74,10 +74,11 @@ public: llvm::ArrayRef<OptionDefinition> GetDefinitions() override; - size_t m_thread_buffer_size; - size_t m_process_buffer_size_limit; + uint64_t m_ipt_trace_size; + uint64_t m_process_buffer_size_limit; bool m_enable_tsc; - llvm::Optional<size_t> m_psb_period; + llvm::Optional<uint64_t> m_psb_period; + bool m_per_cpu_tracing; }; CommandObjectProcessTraceStartIntelPT(TraceIntelPT &trace, @@ -85,10 +86,14 @@ public: : CommandObjectParsed( interpreter, "process trace start", "Start tracing this process with intel-pt, including future " - "threads. " - "This is implemented by tracing each thread independently. " + "threads. If --per-cpu-tracing is not provided, this traces each " + "thread independently, thus using a trace buffer per thread. " "Threads traced with the \"thread trace start\" command are left " - "unaffected ant not retraced.", + "unaffected ant not retraced. This is the recommended option " + "unless the number of threads is huge. If --per-cpu-tracing is " + "passed, each cpu core is traced instead of each thread, which " + "uses a fixed number of trace buffers, but might result in less " + "data available for less frequent threads.", "process trace start [<intel-pt-options>]", lldb::eCommandRequiresProcess | lldb::eCommandTryTargetAPILock | lldb::eCommandProcessMustBeLaunched | 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 4822a786c68c..578828ff1633 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 @@ -9,16 +9,28 @@ #include "DecodedThread.h" #include <intel-pt.h> -#include <memory> #include "TraceCursorIntelPT.h" -#include "lldb/Utility/StreamString.h" + +#include <memory> using namespace lldb; using namespace lldb_private; using namespace lldb_private::trace_intel_pt; using namespace llvm; +bool lldb_private::trace_intel_pt::IsLibiptError(int libipt_status) { + return libipt_status < 0; +} + +bool lldb_private::trace_intel_pt::IsEndOfStream(int libipt_status) { + return libipt_status == -pte_eos; +} + +bool lldb_private::trace_intel_pt::IsTscUnavailable(int libipt_status) { + return libipt_status == -pte_no_time; +} + char IntelPTError::ID; IntelPTError::IntelPTError(int libipt_error_code, lldb::addr_t address) @@ -27,92 +39,167 @@ IntelPTError::IntelPTError(int libipt_error_code, lldb::addr_t address) } void IntelPTError::log(llvm::raw_ostream &OS) const { - const char *libipt_error_message = pt_errstr(pt_errcode(m_libipt_error_code)); - if (m_address != LLDB_INVALID_ADDRESS && m_address > 0) { - write_hex(OS, m_address, HexPrintStyle::PrefixLower, 18); - OS << " "; - } - 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; } - -lldb::addr_t IntelPTInstruction::GetLoadAddress() const { return m_pt_insn.ip; } - -Optional<uint64_t> IntelPTInstruction::GetTimestampCounter() const { - return m_timestamp; -} - -Error IntelPTInstruction::ToError() const { - if (!IsError()) - return Error::success(); - - if (m_error->isA<IntelPTError>()) - return make_error<IntelPTError>(static_cast<IntelPTError &>(*m_error)); - 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; - - 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; + OS << pt_errstr(pt_errcode(m_libipt_error_code)); + if (m_address != LLDB_INVALID_ADDRESS && m_address > 0) + OS << formatv(": {0:x+16}", m_address); +} + +int64_t DecodedThread::GetItemsCount() const { + return static_cast<int64_t>(m_item_kinds.size()); +} + +lldb::addr_t DecodedThread::GetInstructionLoadAddress(size_t item_index) const { + return m_item_data[item_index].load_address; +} + +ThreadSP DecodedThread::GetThread() { return m_thread_sp; } + +DecodedThread::TraceItemStorage & +DecodedThread::CreateNewTraceItem(lldb::TraceItemKind kind) { + m_item_kinds.push_back(kind); + m_item_data.emplace_back(); + return m_item_data.back(); +} + +void DecodedThread::NotifyTsc(uint64_t tsc) { + if (!m_last_tsc || *m_last_tsc != tsc) { + m_instruction_timestamps.emplace(m_item_kinds.size(), tsc); + m_last_tsc = tsc; } +} + +void DecodedThread::AppendEvent(lldb::TraceEvent event) { + CreateNewTraceItem(lldb::eTraceItemKindEvent).event = event; + m_events_stats.RecordEvent(event); +} + +void DecodedThread::AppendInstruction(const pt_insn &insn) { + CreateNewTraceItem(lldb::eTraceItemKindInstruction).load_address = insn.ip; +} + +void DecodedThread::AppendError(const IntelPTError &error) { + // End of stream shouldn't be a public error + if (IsEndOfStream(error.GetLibiptErrorCode())) + return; + CreateNewTraceItem(lldb::eTraceItemKindError).error = + ConstString(error.message()).AsCString(); +} + +void DecodedThread::AppendCustomError(StringRef err) { + CreateNewTraceItem(lldb::eTraceItemKindError).error = + ConstString(err).AsCString(); +} - return mask; +lldb::TraceEvent DecodedThread::GetEventByIndex(int item_index) const { + return m_item_data[item_index].event; } -ArrayRef<IntelPTInstruction> DecodedThread::GetInstructions() const { - return makeArrayRef(m_instructions); +void DecodedThread::LibiptErrorsStats::RecordError(int libipt_error_code) { + libipt_errors_counts[pt_errstr(pt_errcode(libipt_error_code))]++; + total_count++; } -DecodedThread::DecodedThread(ThreadSP thread_sp, Error error) - : m_thread_sp(thread_sp) { - m_instructions.emplace_back(std::move(error)); +void DecodedThread::RecordTscError(int libipt_error_code) { + m_tsc_errors_stats.RecordError(libipt_error_code); } -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")); +const DecodedThread::LibiptErrorsStats & +DecodedThread::GetTscErrorsStats() const { + return m_tsc_errors_stats; } -lldb::TraceCursorUP DecodedThread::GetCursor() { +const DecodedThread::EventsStats &DecodedThread::GetEventsStats() const { + return m_events_stats; +} + +void DecodedThread::EventsStats::RecordEvent(lldb::TraceEvent event) { + events_counts[event]++; + total_count++; +} + +Optional<DecodedThread::TscRange> DecodedThread::CalculateTscRange( + size_t insn_index, + const Optional<DecodedThread::TscRange> &hint_range) const { + // We first try to check the given hint range in case we are traversing the + // trace in short jumps. If that fails, then we do the more expensive + // arbitrary lookup. + if (hint_range) { + Optional<TscRange> candidate_range; + if (insn_index < hint_range->GetStartInstructionIndex()) + candidate_range = hint_range->Prev(); + else if (insn_index > hint_range->GetEndInstructionIndex()) + candidate_range = hint_range->Next(); + else + candidate_range = hint_range; + + if (candidate_range && candidate_range->InRange(insn_index)) + return candidate_range; + } + // Now we do a more expensive lookup + auto it = m_instruction_timestamps.upper_bound(insn_index); + if (it == m_instruction_timestamps.begin()) + return None; + + return TscRange(--it, *this); +} + +lldb::TraceItemKind DecodedThread::GetItemKindByIndex(size_t item_index) const { + return static_cast<lldb::TraceItemKind>(m_item_kinds[item_index]); +} + +const char *DecodedThread::GetErrorByIndex(size_t item_index) const { + return m_item_data[item_index].error; +} + +DecodedThread::DecodedThread(ThreadSP thread_sp) : m_thread_sp(thread_sp) {} + +lldb::TraceCursorUP DecodedThread::CreateNewCursor() { return std::make_unique<TraceCursorIntelPT>(m_thread_sp, shared_from_this()); } + +size_t DecodedThread::CalculateApproximateMemoryUsage() const { + return sizeof(TraceItemStorage) * m_item_data.size() + + sizeof(uint8_t) * m_item_kinds.size() + + (sizeof(size_t) + sizeof(uint64_t)) * m_instruction_timestamps.size(); +} + +DecodedThread::TscRange::TscRange(std::map<size_t, uint64_t>::const_iterator it, + const DecodedThread &decoded_thread) + : m_it(it), m_decoded_thread(&decoded_thread) { + auto next_it = m_it; + ++next_it; + m_end_index = (next_it == m_decoded_thread->m_instruction_timestamps.end()) + ? std::numeric_limits<uint64_t>::max() + : next_it->first - 1; +} + +size_t DecodedThread::TscRange::GetTsc() const { return m_it->second; } + +size_t DecodedThread::TscRange::GetStartInstructionIndex() const { + return m_it->first; +} + +size_t DecodedThread::TscRange::GetEndInstructionIndex() const { + return m_end_index; +} + +bool DecodedThread::TscRange::InRange(size_t insn_index) const { + return GetStartInstructionIndex() <= insn_index && + insn_index <= GetEndInstructionIndex(); +} + +Optional<DecodedThread::TscRange> DecodedThread::TscRange::Next() const { + auto next_it = m_it; + ++next_it; + if (next_it == m_decoded_thread->m_instruction_timestamps.end()) + return None; + return TscRange(next_it, *m_decoded_thread); +} + +Optional<DecodedThread::TscRange> DecodedThread::TscRange::Prev() const { + if (m_it == m_decoded_thread->m_instruction_timestamps.begin()) + return None; + auto prev_it = m_it; + --prev_it; + return TscRange(prev_it, *m_decoded_thread); +} 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 592c402cd0e5..b17e927fafe4 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 @@ -9,6 +9,7 @@ #ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_DECODEDTHREAD_H #define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_DECODEDTHREAD_H +#include <utility> #include <vector> #include "llvm/Support/Errc.h" @@ -22,6 +23,15 @@ namespace lldb_private { namespace trace_intel_pt { +/// libipt status utils +/// \{ +bool IsLibiptError(int libipt_status); + +bool IsEndOfStream(int libipt_status); + +bool IsTscUnavailable(int libipt_status); +/// \} + /// Class for representing a libipt decoding error. class IntelPTError : public llvm::ErrorInfo<IntelPTError> { public: @@ -43,6 +53,8 @@ public: return llvm::errc::not_supported; } + int GetLibiptErrorCode() const { return m_libipt_error_code; } + void log(llvm::raw_ostream &OS) const override; private: @@ -50,110 +62,208 @@ private: lldb::addr_t m_address; }; -/// \class IntelPTInstruction -/// An instruction obtained from decoding a trace. It is either an actual -/// instruction or an error indicating a gap in the trace. +/// \class DecodedThread +/// Class holding the instructions and function call hierarchy obtained from +/// decoding a trace, as well as a position cursor used when reverse debugging +/// the trace. /// -/// Gaps in the trace can come in a few flavors: -/// - tracing gaps (e.g. tracing was paused and then resumed) -/// - tracing errors (e.g. buffer overflow) -/// - decoding errors (e.g. some memory region couldn't be decoded) -/// As mentioned, any gap is represented as an error in this class. -class IntelPTInstruction { +/// Each decoded thread contains a cursor to the current position the user is +/// stopped at. See \a Trace::GetCursorPosition for more information. +class DecodedThread : public std::enable_shared_from_this<DecodedThread> { public: - IntelPTInstruction(const pt_insn &pt_insn, uint64_t timestamp) - : m_pt_insn(pt_insn), m_timestamp(timestamp) {} + /// \class TscRange + /// Class that represents the trace range associated with a given TSC. + /// It provides efficient iteration to the previous or next TSC range in the + /// decoded trace. + /// + /// TSC timestamps are emitted by the decoder infrequently, which means + /// that each TSC covers a range of instruction indices, which can be used to + /// speed up TSC lookups. + class TscRange { + public: + /// Check if this TSC range includes the given instruction index. + bool InRange(size_t insn_index) const; - IntelPTInstruction(const pt_insn &pt_insn) : m_pt_insn(pt_insn) {} + /// Get the next range chronologically. + llvm::Optional<TscRange> Next() const; - /// Error constructor - /// - /// libipt errors should use the underlying \a IntelPTError class. - IntelPTInstruction(llvm::Error err); + /// Get the previous range chronologically. + llvm::Optional<TscRange> Prev() const; + + /// Get the TSC value. + size_t GetTsc() const; + /// Get the smallest instruction index that has this TSC. + size_t GetStartInstructionIndex() const; + /// Get the largest instruction index that has this TSC. + size_t GetEndInstructionIndex() const; + + private: + friend class DecodedThread; - /// Check if this object represents an error (i.e. a gap). + TscRange(std::map<size_t, uint64_t>::const_iterator it, + const DecodedThread &decoded_thread); + + /// The iterator pointing to the beginning of the range. + std::map<size_t, uint64_t>::const_iterator m_it; + /// The largest instruction index that has this TSC. + size_t m_end_index; + + const DecodedThread *m_decoded_thread; + }; + + // Struct holding counts for libipts errors; + struct LibiptErrorsStats { + // libipt error -> count + llvm::DenseMap<const char *, int> libipt_errors_counts; + size_t total_count = 0; + + void RecordError(int libipt_error_code); + }; + + // Struct holding counts for events; + struct EventsStats { + /// A count for each individual event kind. We use an unordered map instead + /// of a DenseMap because DenseMap can't understand enums. + std::unordered_map<lldb::TraceEvent, size_t> events_counts; + size_t total_count = 0; + + void RecordEvent(lldb::TraceEvent event); + }; + + DecodedThread(lldb::ThreadSP thread_sp); + + /// Utility constructor that initializes the trace with a provided error. + DecodedThread(lldb::ThreadSP thread_sp, llvm::Error &&err); + + /// Get the total number of instruction, errors and events from the decoded + /// trace. + int64_t GetItemsCount() const; + + /// Construct the TSC range that covers the given instruction index. + /// This operation is O(logn) and should be used sparingly. + /// If the trace was collected with TSC support, all the instructions of + /// the trace will have associated TSCs. This means that this method will + /// only return \b llvm::None if there are no TSCs whatsoever in the trace. + /// + /// \param[in] insn_index + /// The instruction index in question. /// + /// \param[in] hint_range + /// An optional range that might include the given index or might be a + /// neighbor of it. It might help speed it traversals of the trace with + /// short jumps. + llvm::Optional<TscRange> CalculateTscRange( + size_t insn_index, + const llvm::Optional<DecodedThread::TscRange> &hint_range) const; + /// \return - /// Whether this object represents an error. - bool IsError() const; + /// The error associated with a given trace item. + const char *GetErrorByIndex(size_t item_index) const; /// \return - /// The instruction pointer address, or \a LLDB_INVALID_ADDRESS if it is - /// an error. - lldb::addr_t GetLoadAddress() const; + /// The trace item kind given an item index. + lldb::TraceItemKind GetItemKindByIndex(size_t item_index) 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; + /// The underlying event type for the given trace item index. + lldb::TraceEvent GetEventByIndex(int item_index) 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; + /// The load address of the instruction at the given index. + lldb::addr_t GetInstructionLoadAddress(size_t item_index) const; + + /// Get a new cursor for the decoded thread. + lldb::TraceCursorUP CreateNewCursor(); - /// Get the \a lldb::TraceInstructionControlFlowType categories of the - /// instruction. + /// Return an object with statistics of the TSC decoding errors that happened. + /// A TSC error is not a fatal error and doesn't create gaps in the trace. + /// Instead we only keep track of them as statistics. /// - /// \param[in] next_load_address - /// The address of the next instruction in the trace or \b - /// LLDB_INVALID_ADDRESS if not available. + /// \return + /// An object with the statistics of TSC decoding errors. + const LibiptErrorsStats &GetTscErrorsStats() const; + + /// Return an object with statistics of the trace events that happened. /// /// \return - /// The control flow categories, or \b 0 if the instruction is an error. - lldb::TraceInstructionControlFlowType - GetControlFlowType(lldb::addr_t next_load_address) const; + /// The stats object of all the events. + const EventsStats &GetEventsStats() const; + + /// Record an error decoding a TSC timestamp. + /// + /// See \a GetTscErrors() for more documentation. + /// + /// \param[in] libipt_error_code + /// An error returned by the libipt library. + void RecordTscError(int libipt_error_code); + + /// The approximate size in bytes used by this instance, + /// including all the already decoded instructions. + size_t CalculateApproximateMemoryUsage() const; - IntelPTInstruction(IntelPTInstruction &&other) = default; + lldb::ThreadSP GetThread(); + + /// Notify this object that a new tsc has been seen. + void NotifyTsc(uint64_t tsc); + + /// Append a decoding error. + void AppendError(const IntelPTError &error); + + /// Append a custom decoding. + void AppendCustomError(llvm::StringRef error); + + /// Append an event. + void AppendEvent(lldb::TraceEvent); + + /// Append an instruction. + void AppendInstruction(const pt_insn &insn); private: - IntelPTInstruction(const IntelPTInstruction &other) = delete; - const IntelPTInstruction &operator=(const IntelPTInstruction &other) = delete; + /// When adding new members to this class, make sure + /// to update \a CalculateApproximateMemoryUsage() accordingly. + lldb::ThreadSP m_thread_sp; - pt_insn m_pt_insn; - llvm::Optional<uint64_t> m_timestamp; - std::unique_ptr<llvm::ErrorInfoBase> m_error; -}; + /// We use a union to optimize the memory usage for the different kinds of + /// trace items. + union TraceItemStorage { + /// The load addresses of this item if it's an instruction. + uint64_t load_address; -/// \class DecodedThread -/// Class holding the instructions and function call hierarchy obtained from -/// decoding a trace, as well as a position cursor used when reverse debugging -/// the trace. -/// -/// Each decoded thread contains a cursor to the current position the user is -/// stopped at. See \a Trace::GetCursorPosition for more information. -class DecodedThread : public std::enable_shared_from_this<DecodedThread> { -public: - DecodedThread(lldb::ThreadSP thread_sp, - std::vector<IntelPTInstruction> &&instructions, - size_t raw_trace_size); + /// The event kind of this item if it's an event + lldb::TraceEvent event; - /// Constructor with a single error signaling a complete failure of the - /// decoding process. - DecodedThread(lldb::ThreadSP thread_sp, llvm::Error error); + /// The string message of this item if it's an error + const char *error; + }; - /// Get the instructions from the decoded trace. Some of them might indicate - /// errors (i.e. gaps) in the trace. + /// Create a new trace item. /// /// \return - /// The instructions of the trace. - llvm::ArrayRef<IntelPTInstruction> GetInstructions() const; + /// The index of the new item. + DecodedThread::TraceItemStorage &CreateNewTraceItem(lldb::TraceItemKind kind); - /// Get a new cursor for the decoded thread. - lldb::TraceCursorUP GetCursor(); + /// Most of the trace data is stored here. + std::vector<TraceItemStorage> m_item_data; + /// The TraceItemKind for each trace item encoded as uint8_t. We don't include + /// it in TraceItemStorage to avoid padding. + std::vector<uint8_t> m_item_kinds; - /// Get the size in bytes of the corresponding Intel PT raw trace - /// - /// \return - /// The size of the trace. - size_t GetRawTraceSize() const; + /// This map contains the TSCs of the decoded instructions. It maps + /// `instruction index -> TSC`, where `instruction index` is the first index + /// at which the mapped TSC appears. We use this representation because TSCs + /// are sporadic and we can think of them as ranges. If TSCs are present in + /// the trace, all instructions will have an associated TSC, including the + /// first one. Otherwise, this map will be empty. + std::map<uint64_t, uint64_t> m_instruction_timestamps; + /// This is the chronologically last TSC that has been added. + llvm::Optional<uint64_t> m_last_tsc = llvm::None; -private: - lldb::ThreadSP m_thread_sp; - std::vector<IntelPTInstruction> m_instructions; - size_t m_raw_trace_size; + /// Statistics of all tracing events. + EventsStats m_events_stats; + /// Statistics of libipt errors when decoding TSCs. + LibiptErrorsStats m_tsc_errors_stats; + /// Total amount of time spent decoding. + std::chrono::milliseconds m_total_decoding_time{0}; }; using DecodedThreadSP = std::shared_ptr<DecodedThread>; 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 deleted file mode 100644 index 3827881454c7..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp +++ /dev/null @@ -1,279 +0,0 @@ -//===-- 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 -// -//===----------------------------------------------------------------------===// - -#include "IntelPTDecoder.h" - -#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/Utility/StringExtractor.h" - -using namespace lldb; -using namespace lldb_private; -using namespace lldb_private::trace_intel_pt; -using namespace llvm; - -/// Move the decoder forward to the next synchronization point (i.e. next PSB -/// packet). -/// -/// Once the decoder is at that sync. point, it can start decoding instructions. -/// -/// \return -/// A negative number with the libipt error if we couldn't synchronize. -/// Otherwise, a positive number with the synchronization status will be -/// returned. -static int FindNextSynchronizationPoint(pt_insn_decoder &decoder) { - // Try to sync the decoder. If it fails, then get - // the decoder_offset and try to sync again from - // the next synchronization point. If the - // new_decoder_offset is same as decoder_offset - // then we can't move to the next synchronization - // point. Otherwise, keep resyncing until either - // end of trace stream (eos) is reached or - // pt_insn_sync_forward() passes. - int errcode = pt_insn_sync_forward(&decoder); - - if (errcode != -pte_eos && errcode < 0) { - uint64_t decoder_offset = 0; - int errcode_off = pt_insn_get_offset(&decoder, &decoder_offset); - if (errcode_off >= 0) { // we could get the offset - while (true) { - errcode = pt_insn_sync_forward(&decoder); - if (errcode >= 0 || errcode == -pte_eos) - break; - - uint64_t new_decoder_offset = 0; - errcode_off = pt_insn_get_offset(&decoder, &new_decoder_offset); - if (errcode_off < 0) - break; // We can't further synchronize. - else if (new_decoder_offset <= decoder_offset) { - // We tried resyncing the decoder and - // decoder didn't make any progress because - // the offset didn't change. We will not - // make any progress further. Hence, - // stopping in this situation. - break; - } - // We'll try again starting from a new offset. - decoder_offset = new_decoder_offset; - } - } - } - - return errcode; -} - -/// Before querying instructions, we need to query the events associated that -/// instruction e.g. timing events like ptev_tick, or paging events like -/// ptev_paging. -/// -/// \return -/// 0 if there were no errors processing the events, or a negative libipt -/// error code in case of errors. -static int ProcessPTEvents(pt_insn_decoder &decoder, int errcode) { - while (errcode & pts_event_pending) { - pt_event event; - errcode = pt_insn_event(&decoder, &event, sizeof(event)); - if (errcode < 0) - return errcode; - } - return 0; -} - -/// Decode all the instructions from a configured decoder. -/// The decoding flow is based on -/// https://github.com/intel/libipt/blob/master/doc/howto_libipt.md#the-instruction-flow-decode-loop -/// but with some relaxation to allow for gaps in the trace. -/// -/// Error codes returned by libipt while decoding are: -/// - negative: actual errors -/// - positive or zero: not an error, but a list of bits signaling the status of -/// the decoder -/// -/// \param[in] decoder -/// A configured libipt \a pt_insn_decoder. -/// -/// \return -/// The decoded instructions. -static std::vector<IntelPTInstruction> -DecodeInstructions(pt_insn_decoder &decoder) { - std::vector<IntelPTInstruction> instructions; - - while (true) { - int errcode = FindNextSynchronizationPoint(decoder); - if (errcode == -pte_eos) - break; - - if (errcode < 0) { - instructions.emplace_back(make_error<IntelPTError>(errcode)); - break; - } - - // We have synchronized, so we can start decoding - // instructions and events. - while (true) { - errcode = ProcessPTEvents(decoder, errcode); - if (errcode < 0) { - instructions.emplace_back(make_error<IntelPTError>(errcode)); - break; - } - pt_insn insn; - - errcode = pt_insn_next(&decoder, &insn, sizeof(insn)); - if (errcode == -pte_eos) - break; - - if (errcode < 0) { - instructions.emplace_back(make_error<IntelPTError>(errcode, insn.ip)); - break; - } - - 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); - } - } - } - - return instructions; -} - -/// Callback used by libipt for reading the process memory. -/// -/// More information can be found in -/// https://github.com/intel/libipt/blob/master/doc/man/pt_image_set_callback.3.md -static int ReadProcessMemory(uint8_t *buffer, size_t size, - const pt_asid * /* unused */, uint64_t pc, - void *context) { - Process *process = static_cast<Process *>(context); - - Status error; - int bytes_read = process->ReadMemory(pc, buffer, size, error); - if (error.Fail()) - return -pte_nomap; - return bytes_read; -} - -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 = *cpu_info; - - if (int errcode = pt_cpu_errata(&config.errata, &config.cpu)) - return make_error<IntelPTError>(errcode); - - config.begin = buffer.data(); - config.end = buffer.data() + buffer.size(); - - pt_insn_decoder *decoder = pt_insn_alloc_decoder(&config); - if (!decoder) - return make_error<IntelPTError>(-pte_nomem); - - pt_image *image = pt_insn_get_image(decoder); - - int errcode = pt_image_set_callback(image, ReadProcessMemory, &process); - assert(errcode == 0); - (void)errcode; - - std::vector<IntelPTInstruction> instructions = DecodeInstructions(*decoder); - - pt_insn_free_decoder(decoder); - return instructions; -} - -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 deleted file mode 100644 index e969db579e52..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.h +++ /dev/null @@ -1,87 +0,0 @@ -//===-- IntelPTDecoder.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_DECODER_H -#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_DECODER_H - -#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 { - -/// Base class that handles the decoding of a thread and caches the result. -class ThreadDecoder { -public: - virtual ~ThreadDecoder() = default; - - ThreadDecoder() = default; - - /// Decode the thread and store the result internally, to avoid - /// recomputations. - /// - /// \return - /// A \a DecodedThread instance. - DecodedThreadSP Decode(); - - ThreadDecoder(const ThreadDecoder &other) = delete; - ThreadDecoder &operator=(const ThreadDecoder &other) = delete; - -protected: - /// Decode the thread. - /// - /// \return - /// A \a DecodedThread instance. - 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: - DecodedThreadSP DoDecode() override; - - lldb::ThreadSP m_thread_sp; - TraceIntelPT &m_trace; -}; - -} // namespace trace_intel_pt -} // namespace lldb_private - -#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_DECODER_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/LibiptDecoder.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/LibiptDecoder.cpp new file mode 100644 index 000000000000..dd34467e38b5 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/LibiptDecoder.cpp @@ -0,0 +1,380 @@ +//===-- LibiptDecoder.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 "LibiptDecoder.h" + +#include "TraceIntelPT.h" + +#include "lldb/Target/Process.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::trace_intel_pt; +using namespace llvm; + +/// Class that decodes a raw buffer for a single thread using the low level +/// libipt library. +/// +/// Throughout this code, the status of the decoder will be used to identify +/// events needed to be processed or errors in the decoder. The values can be +/// - negative: actual errors +/// - positive or zero: not an error, but a list of bits signaling the status +/// of the decoder, e.g. whether there are events that need to be decoded or +/// not. +class LibiptDecoder { +public: + /// \param[in] decoder + /// A well configured decoder. Using the current state of that decoder, + /// decoding will start at its next valid PSB. It's not assumed that the + /// decoder is already pointing at a valid PSB. + /// + /// \param[in] decoded_thread + /// A \a DecodedThread object where the decoded instructions will be + /// appended to. It might have already some instructions. + LibiptDecoder(pt_insn_decoder &decoder, DecodedThread &decoded_thread) + : m_decoder(decoder), m_decoded_thread(decoded_thread) {} + + /// Decode all the instructions until the end of the trace. + /// The decoding flow is based on + /// https://github.com/intel/libipt/blob/master/doc/howto_libipt.md#the-instruction-flow-decode-loop. + void DecodeUntilEndOfTrace() { + // Multiple loops indicate gaps in the trace, which are found by the inner + // call to DecodeInstructionsAndEvents. + while (true) { + int status = pt_insn_sync_forward(&m_decoder); + + if (IsLibiptError(status)) { + m_decoded_thread.AppendError(IntelPTError(status)); + break; + } + + DecodeInstructionsAndEvents(status); + } + } + + /// Decode all the instructions that belong to the same PSB packet given its + /// offset. + void DecodePSB(uint64_t psb_offset) { + int status = pt_insn_sync_set(&m_decoder, psb_offset); + if (IsLibiptError(status)) { + m_decoded_thread.AppendError(IntelPTError(status)); + return; + } + DecodeInstructionsAndEvents(status, /*stop_on_psb_change=*/true); + } + +private: + /// Decode all the instructions and events until an error is found, the end + /// of the trace is reached, or optionally a new PSB is reached. + /// + /// \param[in] status + /// The status that was result of synchronizing to the most recent PSB. + /// + /// \param[in] stop_on_psb_change + /// If \b true, decoding stops if a different PSB is reached. + void DecodeInstructionsAndEvents(int status, + bool stop_on_psb_change = false) { + uint64_t psb_offset; + pt_insn_get_sync_offset(&m_decoder, + &psb_offset); // this can't fail because we got here + + while (ProcessPTEvents(status)) { + if (stop_on_psb_change) { + uint64_t cur_psb_offset; + // this can't fail because we got here + pt_insn_get_sync_offset(&m_decoder, &cur_psb_offset); + if (cur_psb_offset != psb_offset) + break; + } + + // The status returned by pt_insn_next will need to be processed + // by ProcessPTEvents in the next loop if it is not an error. + pt_insn insn; + std::memset(&insn, 0, sizeof insn); + if (IsLibiptError(status = + pt_insn_next(&m_decoder, &insn, sizeof(insn)))) { + m_decoded_thread.AppendError(IntelPTError(status, insn.ip)); + break; + } + m_decoded_thread.AppendInstruction(insn); + } + } + + /// Move the decoder forward to the next synchronization point (i.e. next PSB + /// packet). + /// + /// Once the decoder is at that synchronization point, it can start decoding + /// instructions. + /// + /// If errors are found, they will be appended to the trace. + /// + /// \return + /// The libipt decoder status after moving to the next PSB. Negative if + /// no PSB was found. + int FindNextSynchronizationPoint() { + // Try to sync the decoder. If it fails, then get the decoder_offset and + // try to sync again from the next synchronization point. If the + // new_decoder_offset is same as decoder_offset then we can't move to the + // next synchronization point. Otherwise, keep resyncing until either end + // of trace stream (eos) is reached or pt_insn_sync_forward() passes. + int status = pt_insn_sync_forward(&m_decoder); + + // We make this call to record any synchronization errors. + if (IsLibiptError(status)) + m_decoded_thread.AppendError(IntelPTError(status)); + + return status; + } + + /// Before querying instructions, we need to query the events associated that + /// instruction e.g. timing events like ptev_tick, or paging events like + /// ptev_paging. + /// + /// \param[in] status + /// The status gotten from the previous instruction decoding or PSB + /// synchronization. + /// + /// \return + /// \b true if no errors were found processing the events. + bool ProcessPTEvents(int status) { + while (status & pts_event_pending) { + pt_event event; + status = pt_insn_event(&m_decoder, &event, sizeof(event)); + if (IsLibiptError(status)) { + m_decoded_thread.AppendError(IntelPTError(status)); + return false; + } + + if (event.has_tsc) + m_decoded_thread.NotifyTsc(event.tsc); + + switch (event.type) { + case ptev_enabled: + // The kernel started or resumed tracing the program. + break; + case ptev_disabled: + // The CPU paused tracing the program, e.g. due to ip filtering. + m_decoded_thread.AppendEvent(lldb::eTraceEventDisabledHW); + break; + case ptev_async_disabled: + // The kernel or user code paused tracing the program, e.g. + // a breakpoint or a ioctl invocation pausing the trace, or a + // context switch happened. + m_decoded_thread.AppendEvent(lldb::eTraceEventDisabledSW); + break; + case ptev_overflow: + // The CPU internal buffer had an overflow error and some instructions + // were lost. + m_decoded_thread.AppendError(IntelPTError(-pte_overflow)); + break; + default: + break; + } + } + + return true; + } + +private: + pt_insn_decoder &m_decoder; + DecodedThread &m_decoded_thread; +}; + +/// Callback used by libipt for reading the process memory. +/// +/// More information can be found in +/// https://github.com/intel/libipt/blob/master/doc/man/pt_image_set_callback.3.md +static int ReadProcessMemory(uint8_t *buffer, size_t size, + const pt_asid * /* unused */, uint64_t pc, + void *context) { + Process *process = static_cast<Process *>(context); + + Status error; + int bytes_read = process->ReadMemory(pc, buffer, size, error); + if (error.Fail()) + return -pte_nomap; + return bytes_read; +} + +// RAII deleter for libipt's decoder +auto DecoderDeleter = [](pt_insn_decoder *decoder) { + pt_insn_free_decoder(decoder); +}; + +using PtInsnDecoderUP = + std::unique_ptr<pt_insn_decoder, decltype(DecoderDeleter)>; + +static Expected<PtInsnDecoderUP> +CreateInstructionDecoder(TraceIntelPT &trace_intel_pt, + ArrayRef<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 = *cpu_info; + int status = pte_ok; + + if (IsLibiptError(status = pt_cpu_errata(&config.errata, &config.cpu))) + return make_error<IntelPTError>(status); + + // The libipt library does not modify the trace buffer, hence the + // following casts are safe. + config.begin = const_cast<uint8_t *>(buffer.data()); + config.end = const_cast<uint8_t *>(buffer.data() + buffer.size()); + + pt_insn_decoder *decoder_ptr = pt_insn_alloc_decoder(&config); + if (!decoder_ptr) + return make_error<IntelPTError>(-pte_nomem); + + return PtInsnDecoderUP(decoder_ptr, DecoderDeleter); +} + +static Error SetupMemoryImage(PtInsnDecoderUP &decoder_up, Process &process) { + pt_image *image = pt_insn_get_image(decoder_up.get()); + + int status = pte_ok; + if (IsLibiptError( + status = pt_image_set_callback(image, ReadProcessMemory, &process))) + return make_error<IntelPTError>(status); + return Error::success(); +} + +Error lldb_private::trace_intel_pt::DecodeSingleTraceForThread( + DecodedThread &decoded_thread, TraceIntelPT &trace_intel_pt, + ArrayRef<uint8_t> buffer) { + Expected<PtInsnDecoderUP> decoder_up = + CreateInstructionDecoder(trace_intel_pt, buffer); + if (!decoder_up) + return decoder_up.takeError(); + + if (Error err = SetupMemoryImage(*decoder_up, + *decoded_thread.GetThread()->GetProcess())) + return err; + + LibiptDecoder libipt_decoder(*decoder_up.get(), decoded_thread); + libipt_decoder.DecodeUntilEndOfTrace(); + return Error::success(); +} + +Error lldb_private::trace_intel_pt::DecodeSystemWideTraceForThread( + DecodedThread &decoded_thread, TraceIntelPT &trace_intel_pt, + const DenseMap<lldb::cpu_id_t, llvm::ArrayRef<uint8_t>> &buffers, + const std::vector<IntelPTThreadContinousExecution> &executions) { + DenseMap<lldb::cpu_id_t, LibiptDecoder> decoders; + for (auto &cpu_id_buffer : buffers) { + Expected<PtInsnDecoderUP> decoder_up = + CreateInstructionDecoder(trace_intel_pt, cpu_id_buffer.second); + if (!decoder_up) + return decoder_up.takeError(); + + if (Error err = SetupMemoryImage(*decoder_up, + *decoded_thread.GetThread()->GetProcess())) + return err; + + decoders.try_emplace(cpu_id_buffer.first, + LibiptDecoder(*decoder_up->release(), decoded_thread)); + } + + bool has_seen_psbs = false; + for (size_t i = 0; i < executions.size(); i++) { + const IntelPTThreadContinousExecution &execution = executions[i]; + + auto variant = execution.thread_execution.variant; + // If we haven't seen a PSB yet, then it's fine not to show errors + if (has_seen_psbs) { + if (execution.intelpt_subtraces.empty()) { + decoded_thread.AppendCustomError( + formatv("Unable to find intel pt data for thread " + "execution on cpu id = {0}", + execution.thread_execution.cpu_id) + .str()); + } + + // If the first execution is incomplete because it doesn't have a previous + // context switch in its cpu, all good. + if (variant == ThreadContinuousExecution::Variant::OnlyEnd || + variant == ThreadContinuousExecution::Variant::HintedStart) { + decoded_thread.AppendCustomError( + formatv("Thread execution starting on cpu id = {0} doesn't " + "have a matching context switch in.", + execution.thread_execution.cpu_id) + .str()); + } + } + + LibiptDecoder &decoder = + decoders.find(execution.thread_execution.cpu_id)->second; + for (const IntelPTThreadSubtrace &intel_pt_execution : + execution.intelpt_subtraces) { + has_seen_psbs = true; + decoder.DecodePSB(intel_pt_execution.psb_offset); + } + + // If we haven't seen a PSB yet, then it's fine not to show errors + if (has_seen_psbs) { + // If the last execution is incomplete because it doesn't have a following + // context switch in its cpu, all good. + if ((variant == ThreadContinuousExecution::Variant::OnlyStart && + i + 1 != executions.size()) || + variant == ThreadContinuousExecution::Variant::HintedEnd) { + decoded_thread.AppendCustomError( + formatv("Thread execution on cpu id = {0} doesn't have a " + "matching context switch out", + execution.thread_execution.cpu_id) + .str()); + } + } + } + return Error::success(); +} + +bool IntelPTThreadContinousExecution::operator<( + const IntelPTThreadContinousExecution &o) const { + // As the context switch might be incomplete, we look first for the first real + // PSB packet, which is a valid TSC. Otherwise, We query the thread execution + // itself for some tsc. + auto get_tsc = [](const IntelPTThreadContinousExecution &exec) { + return exec.intelpt_subtraces.empty() + ? exec.thread_execution.GetLowestKnownTSC() + : exec.intelpt_subtraces.front().tsc; + }; + + return get_tsc(*this) < get_tsc(o); +} + +Expected<std::vector<IntelPTThreadSubtrace>> +lldb_private::trace_intel_pt::SplitTraceInContinuousExecutions( + TraceIntelPT &trace_intel_pt, llvm::ArrayRef<uint8_t> buffer) { + Expected<PtInsnDecoderUP> decoder_up = + CreateInstructionDecoder(trace_intel_pt, buffer); + if (!decoder_up) + return decoder_up.takeError(); + + pt_insn_decoder *decoder = decoder_up.get().get(); + + std::vector<IntelPTThreadSubtrace> executions; + + int status = pte_ok; + while (!IsLibiptError(status = pt_insn_sync_forward(decoder))) { + uint64_t tsc; + if (IsLibiptError(pt_insn_time(decoder, &tsc, nullptr, nullptr))) + return createStringError(inconvertibleErrorCode(), + "intel pt trace doesn't have TSC timestamps"); + + uint64_t psb_offset; + pt_insn_get_sync_offset(decoder, + &psb_offset); // this can't fail because we got here + + executions.push_back({ + psb_offset, + tsc, + }); + } + return executions; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/LibiptDecoder.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/LibiptDecoder.h new file mode 100644 index 000000000000..cad4d39fcf24 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/LibiptDecoder.h @@ -0,0 +1,100 @@ +//===-- LibiptDecoder.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_LIBIPT_DECODER_H +#define LLDB_SOURCE_PLUGINS_TRACE_LIBIPT_DECODER_H + +#include "DecodedThread.h" +#include "PerfContextSwitchDecoder.h" +#include "forward-declarations.h" + +#include "intel-pt.h" + +namespace lldb_private { +namespace trace_intel_pt { + +/// This struct represents a point in the intel pt trace that the decoder can start decoding from without errors. +struct IntelPTThreadSubtrace { + /// The memory offset of a PSB packet that is a synchronization point for the decoder. A decoder normally looks first + /// for a PSB packet and then it starts decoding. + uint64_t psb_offset; + /// The timestamp associated with the PSB packet above. + uint64_t tsc; +}; + +/// This struct represents a continuous execution of a thread in a cpu, +/// delimited by a context switch in and out, and a list of Intel PT subtraces +/// that belong to this execution. +struct IntelPTThreadContinousExecution { + ThreadContinuousExecution thread_execution; + std::vector<IntelPTThreadSubtrace> intelpt_subtraces; + + IntelPTThreadContinousExecution( + const ThreadContinuousExecution &thread_execution) + : thread_execution(thread_execution) {} + + /// Comparator by time + bool operator<(const IntelPTThreadContinousExecution &o) const; +}; + +/// Decode a raw Intel PT trace for a single thread given in \p buffer and +/// append the decoded instructions and errors in \p decoded_thread. It uses the +/// low level libipt library underneath. +/// +/// \return +/// An \a llvm::Error if the decoder couldn't be properly set up. +llvm::Error DecodeSingleTraceForThread(DecodedThread &decoded_thread, + TraceIntelPT &trace_intel_pt, + llvm::ArrayRef<uint8_t> buffer); + +/// Decode a raw Intel PT trace for a single thread that was collected in a per +/// cpu core basis. +/// +/// \param[out] decoded_thread +/// All decoded instructions, errors and events will be appended to this +/// object. +/// +/// \param[in] trace_intel_pt +/// The main Trace object that contains all the information related to the +/// trace session. +/// +/// \param[in] buffers +/// A map from cpu core id to raw intel pt buffers. +/// +/// \param[in] executions +/// A list of chunks of timed executions of the same given thread. It is used +/// to identify if some executions have missing intel pt data and also to +/// determine in which core a certain part of the execution ocurred. +/// +/// \return +/// An \a llvm::Error if the decoder couldn't be properly set up, i.e. no +/// instructions were attempted to be decoded. +llvm::Error DecodeSystemWideTraceForThread( + DecodedThread &decoded_thread, TraceIntelPT &trace_intel_pt, + const llvm::DenseMap<lldb::cpu_id_t, llvm::ArrayRef<uint8_t>> &buffers, + const std::vector<IntelPTThreadContinousExecution> &executions); + +/// Given an intel pt trace, split it in chunks delimited by PSB packets. Each of these chunks +/// is guaranteed to have been executed continuously. +/// +/// \param[in] trace_intel_pt +/// The main Trace object that contains all the information related to the trace session. +/// +/// \param[in] buffer +/// The intel pt buffer that belongs to a single thread or to a single cpu core. +/// +/// \return +/// A list of continuous executions sorted by time, or an \a llvm::Error in case of failures. +llvm::Expected<std::vector<IntelPTThreadSubtrace>> +SplitTraceInContinuousExecutions(TraceIntelPT &trace_intel_pt, + llvm::ArrayRef<uint8_t> buffer); + +} // namespace trace_intel_pt +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_TRACE_LIBIPT_DECODER_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/PerfContextSwitchDecoder.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/PerfContextSwitchDecoder.cpp new file mode 100644 index 000000000000..6b4251a0fcd9 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/PerfContextSwitchDecoder.cpp @@ -0,0 +1,288 @@ +//===-- PerfContextSwitchDecoder.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 "PerfContextSwitchDecoder.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::trace_intel_pt; +using namespace llvm; + +/// Copied from <linux/perf_event.h> to avoid depending on perf_event.h on +/// non-linux platforms. +/// \{ +#define PERF_RECORD_MISC_SWITCH_OUT (1 << 13) +#define PERF_RECORD_MAX 19 +#define PERF_RECORD_SWITCH_CPU_WIDE 15 + +struct perf_event_header { + uint32_t type; + uint16_t misc; + uint16_t size; + + /// \return + /// An \a llvm::Error if the record looks obviously wrong, or \a + /// llvm::Error::success() otherwise. + Error SanityCheck() const { + // The following checks are based on visual inspection of the records and + // enums in + // https://elixir.bootlin.com/linux/v4.8/source/include/uapi/linux/perf_event.h + // See PERF_RECORD_MAX, PERF_RECORD_SWITCH and the data similar records + // hold. + + // A record of too many uint64_t's or more should mean that the data is + // wrong + const uint64_t max_valid_size_bytes = 8000; + if (size == 0 || size > max_valid_size_bytes) + return createStringError( + inconvertibleErrorCode(), + formatv("A record of {0} bytes was found.", size)); + + // We add some numbers to PERF_RECORD_MAX because some systems might have + // custom records. In any case, we are looking only for abnormal data. + if (type >= PERF_RECORD_MAX + 100) + return createStringError( + inconvertibleErrorCode(), + formatv("Invalid record type {0} was found.", type)); + return Error::success(); + } + + bool IsContextSwitchRecord() const { + return type == PERF_RECORD_SWITCH_CPU_WIDE; + } +}; +/// \} + +/// Record found in the perf_event context switch traces. It might contain +/// additional fields in memory, but header.size should have the actual size +/// of the record. +struct PerfContextSwitchRecord { + struct perf_event_header header; + uint32_t next_prev_pid; + uint32_t next_prev_tid; + uint32_t pid, tid; + uint64_t time_in_nanos; + + bool IsOut() const { return header.misc & PERF_RECORD_MISC_SWITCH_OUT; } +}; + +/// Record produced after parsing the raw context switch trace produce by +/// perf_event. A major difference between this struct and +/// PerfContextSwitchRecord is that this one uses tsc instead of nanos. +struct ContextSwitchRecord { + uint64_t tsc; + /// Whether the switch is in or out + bool is_out; + /// pid = 0 and tid = 0 indicate the swapper or idle process, which normally + /// runs after a context switch out of a normal user thread. + lldb::pid_t pid; + lldb::tid_t tid; + + bool IsOut() const { return is_out; } + + bool IsIn() const { return !is_out; } +}; + +uint64_t ThreadContinuousExecution::GetLowestKnownTSC() const { + switch (variant) { + case Variant::Complete: + return tscs.complete.start; + case Variant::OnlyStart: + return tscs.only_start.start; + case Variant::OnlyEnd: + return tscs.only_end.end; + case Variant::HintedEnd: + return tscs.hinted_end.start; + case Variant::HintedStart: + return tscs.hinted_start.end; + } +} + +uint64_t ThreadContinuousExecution::GetStartTSC() const { + switch (variant) { + case Variant::Complete: + return tscs.complete.start; + case Variant::OnlyStart: + return tscs.only_start.start; + case Variant::OnlyEnd: + return 0; + case Variant::HintedEnd: + return tscs.hinted_end.start; + case Variant::HintedStart: + return tscs.hinted_start.hinted_start; + } +} + +uint64_t ThreadContinuousExecution::GetEndTSC() const { + switch (variant) { + case Variant::Complete: + return tscs.complete.end; + case Variant::OnlyStart: + return std::numeric_limits<uint64_t>::max(); + case Variant::OnlyEnd: + return tscs.only_end.end; + case Variant::HintedEnd: + return tscs.hinted_end.hinted_end; + case Variant::HintedStart: + return tscs.hinted_start.end; + } +} + +ThreadContinuousExecution ThreadContinuousExecution::CreateCompleteExecution( + lldb::cpu_id_t cpu_id, lldb::tid_t tid, lldb::pid_t pid, uint64_t start, + uint64_t end) { + ThreadContinuousExecution o(cpu_id, tid, pid); + o.variant = Variant::Complete; + o.tscs.complete.start = start; + o.tscs.complete.end = end; + return o; +} + +ThreadContinuousExecution ThreadContinuousExecution::CreateHintedStartExecution( + lldb::cpu_id_t cpu_id, lldb::tid_t tid, lldb::pid_t pid, + uint64_t hinted_start, uint64_t end) { + ThreadContinuousExecution o(cpu_id, tid, pid); + o.variant = Variant::HintedStart; + o.tscs.hinted_start.hinted_start = hinted_start; + o.tscs.hinted_start.end = end; + return o; +} + +ThreadContinuousExecution ThreadContinuousExecution::CreateHintedEndExecution( + lldb::cpu_id_t cpu_id, lldb::tid_t tid, lldb::pid_t pid, uint64_t start, + uint64_t hinted_end) { + ThreadContinuousExecution o(cpu_id, tid, pid); + o.variant = Variant::HintedEnd; + o.tscs.hinted_end.start = start; + o.tscs.hinted_end.hinted_end = hinted_end; + return o; +} + +ThreadContinuousExecution ThreadContinuousExecution::CreateOnlyEndExecution( + lldb::cpu_id_t cpu_id, lldb::tid_t tid, lldb::pid_t pid, uint64_t end) { + ThreadContinuousExecution o(cpu_id, tid, pid); + o.variant = Variant::OnlyEnd; + o.tscs.only_end.end = end; + return o; +} + +ThreadContinuousExecution ThreadContinuousExecution::CreateOnlyStartExecution( + lldb::cpu_id_t cpu_id, lldb::tid_t tid, lldb::pid_t pid, uint64_t start) { + ThreadContinuousExecution o(cpu_id, tid, pid); + o.variant = Variant::OnlyStart; + o.tscs.only_start.start = start; + return o; +} + +static Error RecoverExecutionsFromConsecutiveRecords( + cpu_id_t cpu_id, const LinuxPerfZeroTscConversion &tsc_conversion, + const ContextSwitchRecord ¤t_record, + const Optional<ContextSwitchRecord> &prev_record, + std::function<void(const ThreadContinuousExecution &execution)> + on_new_execution) { + if (!prev_record) { + if (current_record.IsOut()) { + on_new_execution(ThreadContinuousExecution::CreateOnlyEndExecution( + cpu_id, current_record.tid, current_record.pid, current_record.tsc)); + } + // The 'in' case will be handled later when we try to look for its end + return Error::success(); + } + + const ContextSwitchRecord &prev = *prev_record; + if (prev.tsc >= current_record.tsc) + return createStringError( + inconvertibleErrorCode(), + formatv("A context switch record doesn't happen after the previous " + "record. Previous TSC= {0}, current TSC = {1}.", + prev.tsc, current_record.tsc)); + + if (current_record.IsIn() && prev.IsIn()) { + // We found two consecutive ins, which means that we didn't capture + // the end of the previous execution. + on_new_execution(ThreadContinuousExecution::CreateHintedEndExecution( + cpu_id, prev.tid, prev.pid, prev.tsc, current_record.tsc - 1)); + } else if (current_record.IsOut() && prev.IsOut()) { + // We found two consecutive outs, that means that we didn't capture + // the beginning of the current execution. + on_new_execution(ThreadContinuousExecution::CreateHintedStartExecution( + cpu_id, current_record.tid, current_record.pid, prev.tsc + 1, + current_record.tsc)); + } else if (current_record.IsOut() && prev.IsIn()) { + if (current_record.pid == prev.pid && current_record.tid == prev.tid) { + /// A complete execution + on_new_execution(ThreadContinuousExecution::CreateCompleteExecution( + cpu_id, current_record.tid, current_record.pid, prev.tsc, + current_record.tsc)); + } else { + // An out after the in of a different thread. The first one doesn't + // have an end, and the second one doesn't have a start. + on_new_execution(ThreadContinuousExecution::CreateHintedEndExecution( + cpu_id, prev.tid, prev.pid, prev.tsc, current_record.tsc - 1)); + on_new_execution(ThreadContinuousExecution::CreateHintedStartExecution( + cpu_id, current_record.tid, current_record.pid, prev.tsc + 1, + current_record.tsc)); + } + } + return Error::success(); +} + +Expected<std::vector<ThreadContinuousExecution>> +lldb_private::trace_intel_pt::DecodePerfContextSwitchTrace( + ArrayRef<uint8_t> data, cpu_id_t cpu_id, + const LinuxPerfZeroTscConversion &tsc_conversion) { + + std::vector<ThreadContinuousExecution> executions; + + // This offset is used to create the error message in case of failures. + size_t offset = 0; + + auto do_decode = [&]() -> Error { + Optional<ContextSwitchRecord> prev_record; + while (offset < data.size()) { + const perf_event_header &perf_record = + *reinterpret_cast<const perf_event_header *>(data.data() + offset); + if (Error err = perf_record.SanityCheck()) + return err; + + if (perf_record.IsContextSwitchRecord()) { + const PerfContextSwitchRecord &context_switch_record = + *reinterpret_cast<const PerfContextSwitchRecord *>(data.data() + + offset); + ContextSwitchRecord record{ + tsc_conversion.ToTSC(context_switch_record.time_in_nanos), + context_switch_record.IsOut(), + static_cast<lldb::pid_t>(context_switch_record.pid), + static_cast<lldb::tid_t>(context_switch_record.tid)}; + + if (Error err = RecoverExecutionsFromConsecutiveRecords( + cpu_id, tsc_conversion, record, prev_record, + [&](const ThreadContinuousExecution &execution) { + executions.push_back(execution); + })) + return err; + + prev_record = record; + } + offset += perf_record.size; + } + + // We might have an incomplete last record + if (prev_record && prev_record->IsIn()) + executions.push_back(ThreadContinuousExecution::CreateOnlyStartExecution( + cpu_id, prev_record->tid, prev_record->pid, prev_record->tsc)); + return Error::success(); + }; + + if (Error err = do_decode()) + return createStringError(inconvertibleErrorCode(), + formatv("Malformed perf context switch trace for " + "cpu {0} at offset {1}. {2}", + cpu_id, offset, toString(std::move(err)))); + + return executions; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/PerfContextSwitchDecoder.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/PerfContextSwitchDecoder.h new file mode 100644 index 000000000000..721aa1d77481 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/PerfContextSwitchDecoder.h @@ -0,0 +1,145 @@ +//===-- PerfContextSwitchDecoder.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_PERFCONTEXTSWITCHDECODER_H +#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_PERFCONTEXTSWITCHDECODER_H + +#include "lldb/Utility/TraceIntelPTGDBRemotePackets.h" +#include "lldb/lldb-types.h" + +#include "llvm/Support/Error.h" + +#include <vector> + +namespace lldb_private { +namespace trace_intel_pt { + +/// This class indicates the time interval in which a thread was running +/// continuously on a cpu core. +struct ThreadContinuousExecution { + + /// In most cases both the start and end of a continuous execution can be + /// accurately recovered from the context switch trace, but in some cases one + /// of these endpoints might be guessed or not known at all, due to contention + /// problems in the trace or because tracing was interrupted, e.g. with ioctl + /// calls, which causes gaps in the trace. Because of that, we identify which + /// situation we fall into with the following variants. + enum class Variant { + /// Both endpoints are known. + Complete, + /// The end is known and we have a lower bound for the start, i.e. the + /// previous execution in the same cpu happens strictly before the hinted + /// start. + HintedStart, + /// The start is known and we have an upper bound for the end, i.e. the next + /// execution in the same cpu happens strictly after the hinted end. + HintedEnd, + /// We only know the start. This might be the last entry of a cpu trace. + OnlyStart, + /// We only know the end. This might be the first entry or a cpu trace. + OnlyEnd, + } variant; + + /// \return + /// The lowest tsc that we are sure of, i.e. not hinted. + uint64_t GetLowestKnownTSC() const; + + /// \return + /// The known or hinted start tsc, or 0 if the variant is \a OnlyEnd. + uint64_t GetStartTSC() const; + + /// \return + /// The known or hinted end tsc, or max \a uint64_t if the variant is \a + /// OnlyStart. + uint64_t GetEndTSC() const; + + /// Constructors for the different variants of this object + /// + /// \{ + static ThreadContinuousExecution + CreateCompleteExecution(lldb::cpu_id_t cpu_id, lldb::tid_t tid, + lldb::pid_t pid, uint64_t start, uint64_t end); + + static ThreadContinuousExecution + CreateHintedStartExecution(lldb::cpu_id_t cpu_id, lldb::tid_t tid, + lldb::pid_t pid, uint64_t hinted_start, + uint64_t end); + + static ThreadContinuousExecution + CreateHintedEndExecution(lldb::cpu_id_t cpu_id, lldb::tid_t tid, + lldb::pid_t pid, uint64_t start, + uint64_t hinted_end); + + static ThreadContinuousExecution CreateOnlyEndExecution(lldb::cpu_id_t cpu_id, + lldb::tid_t tid, + lldb::pid_t pid, + uint64_t end); + + static ThreadContinuousExecution + CreateOnlyStartExecution(lldb::cpu_id_t cpu_id, lldb::tid_t tid, + lldb::pid_t pid, uint64_t start); + /// \} + + union { + struct { + uint64_t start; + uint64_t end; + } complete; + struct { + uint64_t start; + } only_start; + struct { + uint64_t end; + } only_end; + /// The following 'hinted' structures are useful when there are contention + /// problems in the trace + struct { + uint64_t hinted_start; + uint64_t end; + } hinted_start; + struct { + uint64_t start; + uint64_t hinted_end; + } hinted_end; + } tscs; + + lldb::cpu_id_t cpu_id; + lldb::tid_t tid; + lldb::pid_t pid; + +private: + /// We keep this constructor private to force the usage of the static named + /// constructors. + ThreadContinuousExecution(lldb::cpu_id_t cpu_id, lldb::tid_t tid, + lldb::pid_t pid) + : cpu_id(cpu_id), tid(tid), pid(pid) {} +}; + +/// Decodes a context switch trace collected with perf_event_open. +/// +/// \param[in] data +/// The context switch trace in binary format. +/// +/// \param[i] cpu_id +/// The cpu_id where the trace were gotten from. +/// +/// \param[in] tsc_conversion +/// The conversion values used to confert nanoseconds to TSC. +/// +/// \return +/// A list of continuous executions recovered from the raw trace sorted by +/// time, or an \a llvm::Error if the data is malformed. +llvm::Expected<std::vector<ThreadContinuousExecution>> +DecodePerfContextSwitchTrace(llvm::ArrayRef<uint8_t> data, + lldb::cpu_id_t cpu_id, + const LinuxPerfZeroTscConversion &tsc_conversion); + +} // namespace trace_intel_pt +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_PERFCONTEXTSWITCHDECODER_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TaskTimer.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TaskTimer.cpp new file mode 100644 index 000000000000..9603b25fc81c --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TaskTimer.cpp @@ -0,0 +1,24 @@ +#include "TaskTimer.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::trace_intel_pt; +using namespace llvm; + +void ScopedTaskTimer::ForEachTimedTask( + std::function<void(const std::string &event, + std::chrono::milliseconds duration)> + callback) { + for (const auto &kv : m_timed_tasks) { + callback(kv.first, kv.second); + } +} + +ScopedTaskTimer &TaskTimer::ForThread(lldb::tid_t tid) { + auto it = m_thread_timers.find(tid); + if (it == m_thread_timers.end()) + it = m_thread_timers.try_emplace(tid, ScopedTaskTimer{}).first; + return it->second; +} + +ScopedTaskTimer &TaskTimer::ForGlobal() { return m_global_timer; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TaskTimer.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TaskTimer.h new file mode 100644 index 000000000000..92b563257437 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TaskTimer.h @@ -0,0 +1,80 @@ +//===-- TaskTimer.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_TASKTIMER_H +#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TASKTIMER_H + +#include "lldb/lldb-types.h" + +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/StringRef.h" + +#include <chrono> +#include <functional> +#include <unordered_map> + +namespace lldb_private { +namespace trace_intel_pt { + +/// Class used to track the duration of long running tasks related to a single +/// scope for reporting. +class ScopedTaskTimer { +public: + /// Execute the given \p task and record its duration. + /// + /// \param[in] name + /// The name used to identify this task for reporting. + /// + /// \param[in] task + /// The task function. + /// + /// \return + /// The return value of the task. + template <class R> R TimeTask(llvm::StringRef name, std::function<R()> task) { + auto start = std::chrono::steady_clock::now(); + R result = task(); + auto end = std::chrono::steady_clock::now(); + std::chrono::milliseconds duration = + std::chrono::duration_cast<std::chrono::milliseconds>(end - start); + m_timed_tasks.insert({name.str(), duration}); + return result; + } + + /// Executive the given \p callback on each recorded task. + /// + /// \param[in] callback + /// The first parameter of the callback is the name of the recorded task, + /// and the second parameter is the duration of that task. + void ForEachTimedTask(std::function<void(const std::string &name, + std::chrono::milliseconds duration)> + callback); + +private: + std::unordered_map<std::string, std::chrono::milliseconds> m_timed_tasks; +}; + +/// Class used to track the duration of long running tasks for reporting. +class TaskTimer { +public: + /// \return + /// The timer object for the given thread. + ScopedTaskTimer &ForThread(lldb::tid_t tid); + + /// \return + /// The timer object for global tasks. + ScopedTaskTimer &ForGlobal(); + +private: + llvm::DenseMap<lldb::tid_t, ScopedTaskTimer> m_thread_timers; + ScopedTaskTimer m_global_timer; +}; + +} // namespace trace_intel_pt +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TASKTIMER_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/ThreadDecoder.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/ThreadDecoder.cpp new file mode 100644 index 000000000000..8b90afb219af --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/ThreadDecoder.cpp @@ -0,0 +1,55 @@ +//===-- ThreadDecoder.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 "ThreadDecoder.h" + +#include "llvm/Support/MemoryBuffer.h" + +#include "../common/ThreadPostMortemTrace.h" +#include "LibiptDecoder.h" +#include "TraceIntelPT.h" + +#include <utility> + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::trace_intel_pt; +using namespace llvm; + +ThreadDecoder::ThreadDecoder(const ThreadSP &thread_sp, TraceIntelPT &trace) + : m_thread_sp(thread_sp), m_trace(trace) {} + +Expected<DecodedThreadSP> ThreadDecoder::Decode() { + if (!m_decoded_thread.hasValue()) { + if (Expected<DecodedThreadSP> decoded_thread = DoDecode()) { + m_decoded_thread = *decoded_thread; + } else { + return decoded_thread.takeError(); + } + } + return *m_decoded_thread; +} + +llvm::Expected<DecodedThreadSP> ThreadDecoder::DoDecode() { + return m_trace.GetTimer() + .ForThread(m_thread_sp->GetID()) + .TimeTask<Expected<DecodedThreadSP>>( + "Decoding instructions", [&]() -> Expected<DecodedThreadSP> { + DecodedThreadSP decoded_thread_sp = + std::make_shared<DecodedThread>(m_thread_sp); + + Error err = m_trace.OnThreadBufferRead( + m_thread_sp->GetID(), [&](llvm::ArrayRef<uint8_t> data) { + return DecodeSingleTraceForThread(*decoded_thread_sp, m_trace, + data); + }); + + if (err) + return std::move(err); + return decoded_thread_sp; + }); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/ThreadDecoder.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/ThreadDecoder.h new file mode 100644 index 000000000000..5c77ad93d27a --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/ThreadDecoder.h @@ -0,0 +1,53 @@ +//===-- ThreadDecoder.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_THREAD_DECODER_H +#define LLDB_SOURCE_PLUGINS_TRACE_THREAD_DECODER_H + +#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 { + +/// Class that handles the decoding of a thread and caches the result. +class ThreadDecoder { +public: + /// \param[in] thread_sp + /// The thread whose intel pt trace buffer will be decoded. + /// + /// \param[in] trace + /// The main Trace object who owns this decoder and its data. + ThreadDecoder(const lldb::ThreadSP &thread_sp, TraceIntelPT &trace); + + /// Decode the thread and store the result internally, to avoid + /// recomputations. + /// + /// \return + /// A \a DecodedThread instance. + llvm::Expected<DecodedThreadSP> Decode(); + + ThreadDecoder(const ThreadDecoder &other) = delete; + ThreadDecoder &operator=(const ThreadDecoder &other) = delete; + +private: + llvm::Expected<DecodedThreadSP> DoDecode(); + + lldb::ThreadSP m_thread_sp; + TraceIntelPT &m_trace; + llvm::Optional<DecodedThreadSP> m_decoded_thread; +}; + +} // namespace trace_intel_pt +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_TRACE_THREAD_DECODER_H 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 index edefdd0d3486..da91ba7c13d8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.cpp @@ -20,81 +20,85 @@ 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; + Seek(0, SeekType::End); } -size_t TraceCursorIntelPT::GetInternalInstructionSize() { - return m_decoded_thread_sp->GetInstructions().size(); +void TraceCursorIntelPT::CalculateTscRange() { + // If we failed, then we look for the exact range + if (!m_tsc_range || !m_tsc_range->InRange(m_pos)) + m_tsc_range = m_decoded_thread_sp->CalculateTscRange( + m_pos, /*hit_range=*/m_tsc_range); } -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; -} +void TraceCursorIntelPT::Next() { + m_pos += IsForwards() ? 1 : -1; -size_t TraceCursorIntelPT::Seek(int64_t offset, SeekType origin) { - int64_t last_index = GetInternalInstructionSize() - 1; + // We try to go to a neighbor tsc range that might contain the current pos + if (m_tsc_range && !m_tsc_range->InRange(m_pos)) + m_tsc_range = IsForwards() ? m_tsc_range->Next() : m_tsc_range->Prev(); - auto fitPosToBounds = [&](int64_t raw_pos) -> int64_t { - return std::min(std::max((int64_t)0, raw_pos), last_index); - }; + // If we failed, this call will fix it + CalculateTscRange(); +} +bool TraceCursorIntelPT::Seek(int64_t offset, SeekType origin) { switch (origin) { - case TraceCursor::SeekType::Set: - m_pos = fitPosToBounds(offset); - return m_pos; + case TraceCursor::SeekType::Beginning: + m_pos = offset; + break; case TraceCursor::SeekType::End: - m_pos = fitPosToBounds(offset + last_index); - return last_index - m_pos; + m_pos = m_decoded_thread_sp->GetItemsCount() - 1 + offset; + break; 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); + m_pos += offset; } + CalculateTscRange(); + + return HasValue(); +} + +bool TraceCursorIntelPT::HasValue() const { + return m_pos >= 0 && m_pos < m_decoded_thread_sp->GetItemsCount(); } -bool TraceCursorIntelPT::IsError() { - return m_decoded_thread_sp->GetInstructions()[m_pos].IsError(); +lldb::TraceItemKind TraceCursorIntelPT::GetItemKind() const { + return m_decoded_thread_sp->GetItemKindByIndex(m_pos); } -Error TraceCursorIntelPT::GetError() { - return m_decoded_thread_sp->GetInstructions()[m_pos].ToError(); +const char *TraceCursorIntelPT::GetError() const { + return m_decoded_thread_sp->GetErrorByIndex(m_pos); } -lldb::addr_t TraceCursorIntelPT::GetLoadAddress() { - return m_decoded_thread_sp->GetInstructions()[m_pos].GetLoadAddress(); +lldb::addr_t TraceCursorIntelPT::GetLoadAddress() const { + return m_decoded_thread_sp->GetInstructionLoadAddress(m_pos); } -Optional<uint64_t> TraceCursorIntelPT::GetTimestampCounter() { - return m_decoded_thread_sp->GetInstructions()[m_pos].GetTimestampCounter(); +Optional<uint64_t> +TraceCursorIntelPT::GetCounter(lldb::TraceCounter counter_type) const { + switch (counter_type) { + case lldb::eTraceCounterTSC: + if (m_tsc_range) + return m_tsc_range->GetTsc(); + else + return llvm::None; + } +} + +lldb::TraceEvent TraceCursorIntelPT::GetEventType() const { + return m_decoded_thread_sp->GetEventByIndex(m_pos); } -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); +bool TraceCursorIntelPT::GoToId(user_id_t id) { + if (!HasId(id)) + return false; + m_pos = id; + m_tsc_range = m_decoded_thread_sp->CalculateTscRange(m_pos, m_tsc_range); + + return true; } + +bool TraceCursorIntelPT::HasId(lldb::user_id_t id) const { + return static_cast<int64_t>(id) < m_decoded_thread_sp->GetItemsCount(); +} + +user_id_t TraceCursorIntelPT::GetId() const { return m_pos; } 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 index 29d3792bb489..c90431de3bbc 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.h +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.h @@ -9,8 +9,7 @@ #ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACECURSORINTELPT_H #define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACECURSORINTELPT_H -#include "IntelPTDecoder.h" -#include "TraceIntelPTSessionFileParser.h" +#include "ThreadDecoder.h" namespace lldb_private { namespace trace_intel_pt { @@ -20,28 +19,39 @@ public: TraceCursorIntelPT(lldb::ThreadSP thread_sp, DecodedThreadSP decoded_thread_sp); - size_t Seek(int64_t offset, SeekType origin) override; + bool Seek(int64_t offset, SeekType origin) override; - virtual bool Next() override; + void Next() override; - llvm::Error GetError() override; + bool HasValue() const override; - lldb::addr_t GetLoadAddress() override; + const char *GetError() const override; - llvm::Optional<uint64_t> GetTimestampCounter() override; + lldb::addr_t GetLoadAddress() const override; - lldb::TraceInstructionControlFlowType - GetInstructionControlFlowType() override; + llvm::Optional<uint64_t> + GetCounter(lldb::TraceCounter counter_type) const override; - bool IsError() override; + lldb::TraceEvent GetEventType() const override; + + lldb::TraceItemKind GetItemKind() const override; + + bool GoToId(lldb::user_id_t id) override; + + lldb::user_id_t GetId() const override; + + bool HasId(lldb::user_id_t id) const override; private: - size_t GetInternalInstructionSize(); + /// Calculate the tsc range for the current position if needed. + void CalculateTscRange(); /// Storage of the actual instructions DecodedThreadSP m_decoded_thread_sp; /// Internal instruction index currently pointing at. - size_t m_pos; + int64_t m_pos; + /// Tsc range covering the current instruction. + llvm::Optional<DecodedThread::TscRange> m_tsc_range; }; } // namespace trace_intel_pt 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 6ec957771e47..fc7a103fbe15 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 @@ -12,8 +12,8 @@ #include "CommandObjectTraceStartIntelPT.h" #include "DecodedThread.h" #include "TraceIntelPTConstants.h" -#include "TraceIntelPTSessionFileParser.h" -#include "TraceIntelPTSessionSaver.h" +#include "TraceIntelPTBundleLoader.h" +#include "TraceIntelPTBundleSaver.h" #include "lldb/Core/PluginManager.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" @@ -40,32 +40,32 @@ TraceIntelPT::GetThreadTraceStartCommand(CommandInterpreter &interpreter) { void TraceIntelPT::Initialize() { PluginManager::RegisterPlugin(GetPluginNameStatic(), "Intel Processor Trace", - CreateInstanceForSessionFile, + CreateInstanceForTraceBundle, CreateInstanceForLiveProcess, - TraceIntelPTSessionFileParser::GetSchema()); + TraceIntelPTBundleLoader::GetSchema()); } void TraceIntelPT::Terminate() { - PluginManager::UnregisterPlugin(CreateInstanceForSessionFile); + PluginManager::UnregisterPlugin(CreateInstanceForTraceBundle); } StringRef TraceIntelPT::GetSchema() { - return TraceIntelPTSessionFileParser::GetSchema(); + return TraceIntelPTBundleLoader::GetSchema(); } void TraceIntelPT::Dump(Stream *s) const {} llvm::Error TraceIntelPT::SaveLiveTraceToDisk(FileSpec directory) { RefreshLiveProcessState(); - return TraceIntelPTSessionSaver().SaveToDisk(*this, directory); + return TraceIntelPTBundleSaver().SaveToDisk(*this, directory); } -Expected<TraceSP> TraceIntelPT::CreateInstanceForSessionFile( - const json::Value &trace_session_file, StringRef session_file_dir, +Expected<TraceSP> TraceIntelPT::CreateInstanceForTraceBundle( + const json::Value &bundle_description, StringRef bundle_dir, Debugger &debugger) { - return TraceIntelPTSessionFileParser(debugger, trace_session_file, - session_file_dir) - .Parse(); + return TraceIntelPTBundleLoader(debugger, bundle_description, + bundle_dir) + .Load(); } Expected<TraceSP> TraceIntelPT::CreateInstanceForLiveProcess(Process &process) { @@ -74,55 +74,197 @@ Expected<TraceSP> TraceIntelPT::CreateInstanceForLiveProcess(Process &process) { return instance; } -TraceIntelPT::TraceIntelPT( - 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->GetID(), - std::make_unique<PostMortemThreadDecoder>(thread, *this)); +TraceIntelPTSP TraceIntelPT::GetSharedPtr() { + return std::static_pointer_cast<TraceIntelPT>(shared_from_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.GetID()); - if (it == m_thread_decoders.end()) - return std::make_shared<DecodedThread>( - thread.shared_from_this(), - createStringError(inconvertibleErrorCode(), "thread not traced")); +TraceIntelPTSP TraceIntelPT::CreateInstanceForPostmortemTrace( + JSONTraceBundleDescription &bundle_description, ArrayRef<ProcessSP> traced_processes, + ArrayRef<ThreadPostMortemTraceSP> traced_threads) { + TraceIntelPTSP trace_sp(new TraceIntelPT(bundle_description, traced_processes)); + trace_sp->m_storage.tsc_conversion = bundle_description.tsc_perf_zero_conversion; + + if (bundle_description.cpus) { + std::vector<cpu_id_t> cpus; + + for (const JSONCpu &cpu : *bundle_description.cpus) { + trace_sp->SetPostMortemCpuDataFile(cpu.id, IntelPTDataKinds::kIptTrace, + FileSpec(cpu.ipt_trace)); + + trace_sp->SetPostMortemCpuDataFile( + cpu.id, IntelPTDataKinds::kPerfContextSwitchTrace, + FileSpec(cpu.context_switch_trace)); + cpus.push_back(cpu.id); + } + + std::vector<tid_t> tids; + for (const JSONProcess &process : bundle_description.processes) + for (const JSONThread &thread : process.threads) + tids.push_back(thread.tid); + + trace_sp->m_storage.multicpu_decoder.emplace(trace_sp); + } else { + for (const ThreadPostMortemTraceSP &thread : traced_threads) { + trace_sp->m_storage.thread_decoders.try_emplace( + thread->GetID(), std::make_unique<ThreadDecoder>(thread, *trace_sp)); + if (const Optional<FileSpec> &trace_file = thread->GetTraceFile()) { + trace_sp->SetPostMortemThreadDataFile( + thread->GetID(), IntelPTDataKinds::kIptTrace, *trace_file); + } + } + } + + for (const ProcessSP &process_sp : traced_processes) + process_sp->GetTarget().SetTrace(trace_sp); + return trace_sp; +} + +TraceIntelPT::TraceIntelPT(JSONTraceBundleDescription &bundle_description, + ArrayRef<ProcessSP> traced_processes) + : Trace(traced_processes, bundle_description.GetCpuIds()), + m_cpu_info(bundle_description.cpu_info) {} + +Expected<DecodedThreadSP> TraceIntelPT::Decode(Thread &thread) { + if (const char *error = RefreshLiveProcessState()) + return createStringError(inconvertibleErrorCode(), error); + + Storage &storage = GetUpdatedStorage(); + if (storage.multicpu_decoder) + return storage.multicpu_decoder->Decode(thread); + + auto it = storage.thread_decoders.find(thread.GetID()); + if (it == storage.thread_decoders.end()) + return createStringError(inconvertibleErrorCode(), "thread not traced"); return it->second->Decode(); } -lldb::TraceCursorUP TraceIntelPT::GetCursor(Thread &thread) { - return Decode(thread)->GetCursor(); +llvm::Expected<lldb::TraceCursorUP> +TraceIntelPT::CreateNewCursor(Thread &thread) { + if (Expected<DecodedThreadSP> decoded_thread = Decode(thread)) + return decoded_thread.get()->CreateNewCursor(); + else + return decoded_thread.takeError(); } 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"); + Storage &storage = GetUpdatedStorage(); + + lldb::tid_t tid = thread.GetID(); + s.Format("\nthread #{0}: tid = {1}", thread.GetIndexID(), thread.GetID()); + if (!IsTraced(tid)) { + s << ", not traced\n"; + return; + } + s << "\n"; + + Expected<DecodedThreadSP> decoded_thread_sp_or_err = Decode(thread); + if (!decoded_thread_sp_or_err) { + s << toString(decoded_thread_sp_or_err.takeError()) << "\n"; + return; + } + + DecodedThreadSP &decoded_thread_sp = *decoded_thread_sp_or_err; + + Expected<Optional<uint64_t>> raw_size_or_error = GetRawTraceSize(thread); + if (!raw_size_or_error) { + s.Format(" {0}\n", toString(raw_size_or_error.takeError())); return; } - s.Printf("\n Raw trace size: %zu bytes\n", *raw_size); - return; + Optional<uint64_t> raw_size = *raw_size_or_error; + + /// Instruction stats + { + uint64_t items_count = decoded_thread_sp->GetItemsCount(); + uint64_t mem_used = decoded_thread_sp->CalculateApproximateMemoryUsage(); + + s.Format(" Total number of trace items: {0}\n", items_count); + + s << "\n Memory usage:\n"; + if (raw_size) + s.Format(" Raw trace size: {0} KiB\n", *raw_size / 1024); + + s.Format( + " Total approximate memory usage (excluding raw trace): {0:2} KiB\n", + (double)mem_used / 1024); + if (items_count != 0) + s.Format(" Average memory usage per item (excluding raw trace): " + "{0:2} bytes\n", + (double)mem_used / items_count); + } + + // Timing + { + s << "\n Timing for this thread:\n"; + auto print_duration = [&](const std::string &name, + std::chrono::milliseconds duration) { + s.Format(" {0}: {1:2}s\n", name, duration.count() / 1000.0); + }; + GetTimer().ForThread(tid).ForEachTimedTask(print_duration); + + s << "\n Timing for global tasks:\n"; + GetTimer().ForGlobal().ForEachTimedTask(print_duration); + } + + // Instruction events stats + { + const DecodedThread::EventsStats &events_stats = + decoded_thread_sp->GetEventsStats(); + s << "\n Events:\n"; + s.Format(" Number of individual events: {0}\n", + events_stats.total_count); + for (const auto &event_to_count : events_stats.events_counts) { + s.Format(" {0}: {1}\n", + TraceCursor::EventKindToString(event_to_count.first), + event_to_count.second); + } + } + + if (storage.multicpu_decoder) { + s << "\n Multi-cpu decoding:\n"; + s.Format(" Total number of continuous executions found: {0}\n", + storage.multicpu_decoder->GetTotalContinuousExecutionsCount()); + s.Format( + " Number of continuous executions for this thread: {0}\n", + storage.multicpu_decoder->GetNumContinuousExecutionsForThread(tid)); + } + + // Errors + { + s << "\n Errors:\n"; + const DecodedThread::LibiptErrorsStats &tsc_errors_stats = + decoded_thread_sp->GetTscErrorsStats(); + s.Format(" Number of TSC decoding errors: {0}\n", + tsc_errors_stats.total_count); + for (const auto &error_message_to_count : + tsc_errors_stats.libipt_errors_counts) { + s.Format(" {0}: {1}\n", error_message_to_count.first, + error_message_to_count.second); + } + } } -Optional<size_t> TraceIntelPT::GetRawTraceSize(Thread &thread) { - if (IsTraced(thread.GetID())) - return Decode(thread)->GetRawTraceSize(); - else - return None; +llvm::Expected<Optional<uint64_t>> +TraceIntelPT::GetRawTraceSize(Thread &thread) { + if (GetUpdatedStorage().multicpu_decoder) + return None; // TODO: calculate the amount of intel pt raw trace associated + // with the given thread. + if (GetLiveProcess()) + return GetLiveThreadBinaryDataSize(thread.GetID(), + IntelPTDataKinds::kIptTrace); + uint64_t size; + auto callback = [&](llvm::ArrayRef<uint8_t> data) { + size = data.size(); + return Error::success(); + }; + if (Error err = OnThreadBufferRead(thread.GetID(), callback)) + return std::move(err); + + return size; } Expected<pt_cpu> TraceIntelPT::GetCPUInfoForLiveProcess() { - Expected<std::vector<uint8_t>> cpu_info = GetLiveProcessBinaryData("cpuInfo"); + Expected<std::vector<uint8_t>> cpu_info = + GetLiveProcessBinaryData(IntelPTDataKinds::kProcFsCpuInfo); if (!cpu_info) return cpu_info.takeError(); @@ -183,28 +325,62 @@ Expected<pt_cpu> TraceIntelPT::GetCPUInfo() { return *m_cpu_info; } -Process *TraceIntelPT::GetLiveProcess() { return m_live_process; } +llvm::Optional<LinuxPerfZeroTscConversion> +TraceIntelPT::GetPerfZeroTscConversion() { + return GetUpdatedStorage().tsc_conversion; +} -void TraceIntelPT::DoRefreshLiveProcessState( - Expected<TraceGetStateResponse> state) { - m_thread_decoders.clear(); +TraceIntelPT::Storage &TraceIntelPT::GetUpdatedStorage() { + RefreshLiveProcessState(); + return m_storage; +} - if (!state) { - m_live_refresh_error = toString(state.takeError()); - return; +Error TraceIntelPT::DoRefreshLiveProcessState(TraceGetStateResponse state, + StringRef json_response) { + m_storage = Storage(); + + Expected<TraceIntelPTGetStateResponse> intelpt_state = + json::parse<TraceIntelPTGetStateResponse>(json_response, + "TraceIntelPTGetStateResponse"); + if (!intelpt_state) + return intelpt_state.takeError(); + + m_storage.tsc_conversion = intelpt_state->tsc_perf_zero_conversion; + + if (!intelpt_state->cpus) { + for (const TraceThreadState &thread_state : state.traced_threads) { + ThreadSP thread_sp = + GetLiveProcess()->GetThreadList().FindThreadByID(thread_state.tid); + m_storage.thread_decoders.try_emplace( + thread_state.tid, std::make_unique<ThreadDecoder>(thread_sp, *this)); + } + } else { + std::vector<cpu_id_t> cpus; + for (const TraceCpuState &cpu : *intelpt_state->cpus) + cpus.push_back(cpu.id); + + std::vector<tid_t> tids; + for (const TraceThreadState &thread : intelpt_state->traced_threads) + tids.push_back(thread.tid); + + if (!intelpt_state->tsc_perf_zero_conversion) + return createStringError(inconvertibleErrorCode(), + "Missing perf time_zero conversion values"); + m_storage.multicpu_decoder.emplace(GetSharedPtr()); } - for (const TraceThreadState &thread_state : state->tracedThreads) { - Thread &thread = - *m_live_process->GetThreadList().FindThreadByID(thread_state.tid); - m_thread_decoders.emplace( - thread_state.tid, std::make_unique<LiveThreadDecoder>(thread, *this)); + if (m_storage.tsc_conversion) { + Log *log = GetLog(LLDBLog::Target); + LLDB_LOG(log, "TraceIntelPT found TSC conversion information"); } + return Error::success(); } bool TraceIntelPT::IsTraced(lldb::tid_t tid) { - RefreshLiveProcessState(); - return m_thread_decoders.count(tid); + Storage &storage = GetUpdatedStorage(); + if (storage.multicpu_decoder) + return storage.multicpu_decoder->TracesThread(tid); + return storage.thread_decoders.count(tid); } // The information here should match the description of the intel-pt section @@ -212,101 +388,79 @@ bool TraceIntelPT::IsTraced(lldb::tid_t tid) { // documentation file. Similarly, it should match the CLI help messages of the // TraceIntelPTOptions.td file. const char *TraceIntelPT::GetStartConfigurationHelp() { - return R"(Parameters: + static Optional<std::string> message; + if (!message) { + message.emplace(formatv(R"(Parameters: - Note: If a parameter is not specified, a default value will be used. + See the jLLDBTraceStart section in lldb/docs/lldb-gdb-remote.txt for a + description of each parameter below. - - int threadBufferSize (defaults to 4096 bytes): + - int iptTraceSize (defaults to {0} 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): + - boolean enableTsc (default to {1}): [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): + - int psbPeriod (defaults to {2}): [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): + - boolean perCpuTracing (default to {3}): [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.)"; + + - int processBufferSizeLimit (defaults to {4} MiB): + [process tracing only])", + kDefaultIptTraceSize, kDefaultEnableTscValue, + kDefaultPsbPeriod, kDefaultPerCpuTracing, + kDefaultProcessBufferSizeLimit / 1024 / 1024)); + } + return message->c_str(); } -Error TraceIntelPT::Start(size_t thread_buffer_size, - size_t total_buffer_size_limit, bool enable_tsc, - Optional<size_t> psb_period) { +Error TraceIntelPT::Start(uint64_t ipt_trace_size, + uint64_t total_buffer_size_limit, bool enable_tsc, + Optional<uint64_t> psb_period, bool per_cpu_tracing) { 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.ipt_trace_size = ipt_trace_size; + request.process_buffer_size_limit = total_buffer_size_limit; + request.enable_tsc = enable_tsc; + request.psb_period = psb_period; request.type = GetPluginName().str(); + request.per_cpu_tracing = per_cpu_tracing; return Trace::Start(toJSON(request)); } Error TraceIntelPT::Start(StructuredData::ObjectSP configuration) { - size_t thread_buffer_size = kDefaultThreadBufferSize; - size_t process_buffer_size_limit = kDefaultProcessBufferSizeLimit; + uint64_t ipt_trace_size = kDefaultIptTraceSize; + uint64_t process_buffer_size_limit = kDefaultProcessBufferSizeLimit; bool enable_tsc = kDefaultEnableTscValue; - Optional<size_t> psb_period = kDefaultPsbPeriod; + Optional<uint64_t> psb_period = kDefaultPsbPeriod; + bool per_cpu_tracing = kDefaultPerCpuTracing; if (configuration) { if (StructuredData::Dictionary *dict = configuration->GetAsDictionary()) { - dict->GetValueForKeyAsInteger("threadBufferSize", thread_buffer_size); + dict->GetValueForKeyAsInteger("iptTraceSize", ipt_trace_size); dict->GetValueForKeyAsInteger("processBufferSizeLimit", process_buffer_size_limit); dict->GetValueForKeyAsBoolean("enableTsc", enable_tsc); dict->GetValueForKeyAsInteger("psbPeriod", psb_period); + dict->GetValueForKeyAsBoolean("perCpuTracing", per_cpu_tracing); } else { return createStringError(inconvertibleErrorCode(), "configuration object is not a dictionary"); } } - return Start(thread_buffer_size, process_buffer_size_limit, enable_tsc, - psb_period); + return Start(ipt_trace_size, process_buffer_size_limit, enable_tsc, + psb_period, per_cpu_tracing); } llvm::Error TraceIntelPT::Start(llvm::ArrayRef<lldb::tid_t> tids, - size_t thread_buffer_size, bool enable_tsc, - Optional<size_t> psb_period) { + uint64_t ipt_trace_size, bool enable_tsc, + Optional<uint64_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.ipt_trace_size = ipt_trace_size; + request.enable_tsc = enable_tsc; + request.psb_period = psb_period; request.type = GetPluginName().str(); request.tids.emplace(); for (lldb::tid_t tid : tids) @@ -316,13 +470,13 @@ llvm::Error TraceIntelPT::Start(llvm::ArrayRef<lldb::tid_t> tids, Error TraceIntelPT::Start(llvm::ArrayRef<lldb::tid_t> tids, StructuredData::ObjectSP configuration) { - size_t thread_buffer_size = kDefaultThreadBufferSize; + uint64_t ipt_trace_size = kDefaultIptTraceSize; bool enable_tsc = kDefaultEnableTscValue; - Optional<size_t> psb_period = kDefaultPsbPeriod; + Optional<uint64_t> psb_period = kDefaultPsbPeriod; if (configuration) { if (StructuredData::Dictionary *dict = configuration->GetAsDictionary()) { - dict->GetValueForKeyAsInteger("threadBufferSize", thread_buffer_size); + dict->GetValueForKeyAsInteger("iptTraceSize", ipt_trace_size); dict->GetValueForKeyAsBoolean("enableTsc", enable_tsc); dict->GetValueForKeyAsInteger("psbPeriod", psb_period); } else { @@ -331,10 +485,12 @@ Error TraceIntelPT::Start(llvm::ArrayRef<lldb::tid_t> tids, } } - return Start(tids, thread_buffer_size, enable_tsc, psb_period); + return Start(tids, ipt_trace_size, enable_tsc, psb_period); } -Expected<std::vector<uint8_t>> -TraceIntelPT::GetLiveThreadBuffer(lldb::tid_t tid) { - return Trace::GetLiveThreadBinaryData(tid, "threadTraceBuffer"); +Error TraceIntelPT::OnThreadBufferRead(lldb::tid_t tid, + OnBinaryDataReadCallback callback) { + return OnThreadBinaryDataRead(tid, IntelPTDataKinds::kIptTrace, callback); } + +TaskTimer &TraceIntelPT::GetTimer() { return GetUpdatedStorage().task_timer; } 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 a6ecf6f906b2..09ecbe7da61a 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 @@ -9,8 +9,11 @@ #ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPT_H #define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPT_H -#include "IntelPTDecoder.h" -#include "TraceIntelPTSessionFileParser.h" +#include "TaskTimer.h" +#include "ThreadDecoder.h" +#include "TraceIntelPTMultiCpuDecoder.h" +#include "TraceIntelPTBundleLoader.h" + #include "lldb/Utility/FileSpec.h" #include "lldb/lldb-types.h" #include "llvm/Support/raw_ostream.h" @@ -34,14 +37,13 @@ public: static void Terminate(); - /// Create an instance of this class. + /// Create an instance of this class from a trace bundle. /// - /// \param[in] trace_session_file - /// The contents of the trace session file. See \a Trace::FindPlugin. + /// \param[in] trace_bundle_description + /// The description of the trace bundle. See \a Trace::FindPlugin. /// - /// \param[in] session_file_dir - /// The path to the directory that contains the session file. It's used to - /// resolved relative paths in the session file. + /// \param[in] bundle_dir + /// The path to the directory that contains the trace bundle. /// /// \param[in] debugger /// The debugger instance where new Targets will be created as part of the @@ -50,8 +52,8 @@ public: /// \return /// A trace instance or an error in case of failures. static llvm::Expected<lldb::TraceSP> - CreateInstanceForSessionFile(const llvm::json::Value &trace_session_file, - llvm::StringRef session_file_dir, + CreateInstanceForTraceBundle(const llvm::json::Value &trace_bundle_description, + llvm::StringRef bundle_dir, Debugger &debugger); static llvm::Expected<lldb::TraceSP> @@ -68,14 +70,14 @@ public: llvm::StringRef GetSchema() override; - lldb::TraceCursorUP GetCursor(Thread &thread) override; + llvm::Expected<lldb::TraceCursorUP> CreateNewCursor(Thread &thread) override; void DumpTraceInfo(Thread &thread, Stream &s, bool verbose) override; - llvm::Optional<size_t> GetRawTraceSize(Thread &thread); + llvm::Expected<llvm::Optional<uint64_t>> GetRawTraceSize(Thread &thread); - void DoRefreshLiveProcessState( - llvm::Expected<TraceGetStateResponse> state) override; + llvm::Error DoRefreshLiveProcessState(TraceGetStateResponse state, + llvm::StringRef json_response) override; bool IsTraced(lldb::tid_t tid) override; @@ -83,27 +85,31 @@ public: /// Start tracing a live process. /// - /// \param[in] thread_buffer_size + /// More information on the parameters below can be found in the + /// jLLDBTraceStart section in lldb/docs/lldb-gdb-remote.txt. + /// + /// \param[in] ipt_trace_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(); + /// + /// \param[in] per_cpu_tracing + /// This value defines whether to have an intel pt trace buffer per thread + /// or per cpu core. /// /// \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); + llvm::Error Start(uint64_t ipt_trace_size, uint64_t total_buffer_size_limit, + bool enable_tsc, llvm::Optional<uint64_t> psb_period, + bool m_per_cpu_tracing); /// \copydoc Trace::Start llvm::Error Start(StructuredData::ObjectSP configuration = @@ -111,59 +117,81 @@ public: /// Start tracing live threads. /// + /// More information on the parameters below can be found in the + /// jLLDBTraceStart section in lldb/docs/lldb-gdb-remote.txt. + /// /// \param[in] tids /// Threads to trace. /// - /// \param[in] thread_buffer_size - /// Trace size per thread in bytes. + /// \param[in] ipt_trace_size + /// Trace size per thread or per cpu core 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); + llvm::Error Start(llvm::ArrayRef<lldb::tid_t> tids, uint64_t ipt_trace_size, + bool enable_tsc, llvm::Optional<uint64_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); + /// See \a Trace::OnThreadBinaryDataRead(). + llvm::Error OnThreadBufferRead(lldb::tid_t tid, + OnBinaryDataReadCallback callback); + /// Get or fetch the cpu information from, for example, /proc/cpuinfo. llvm::Expected<pt_cpu> GetCPUInfo(); - /// Get the current traced live process. - /// + /// Get or fetch the values used to convert to and from TSCs and nanos. + llvm::Optional<LinuxPerfZeroTscConversion> GetPerfZeroTscConversion(); + /// \return - /// The current traced live process. If it's not a live process, - /// return \a nullptr. - Process *GetLiveProcess(); + /// The timer object for this trace. + TaskTimer &GetTimer(); + + TraceIntelPTSP GetSharedPtr(); private: - friend class TraceIntelPTSessionFileParser; + friend class TraceIntelPTBundleLoader; llvm::Expected<pt_cpu> GetCPUInfoForLiveProcess(); + /// Postmortem trace constructor + /// + /// \param[in] bundle_description + /// The definition file for the postmortem bundle. + /// + /// \param[in] traced_processes + /// The processes traced in the live session. + /// /// \param[in] trace_threads - /// ThreadTrace instances, which are not live-processes and whose trace - /// files are fixed. - TraceIntelPT( - const pt_cpu &cpu_info, - const std::vector<lldb::ThreadPostMortemTraceSP> &traced_threads); + /// The threads traced in the live session. They must belong to the + /// processes mentioned above. + /// + /// \return + /// A TraceIntelPT shared pointer instance. + /// \{ + static TraceIntelPTSP CreateInstanceForPostmortemTrace( + JSONTraceBundleDescription &bundle_description, + llvm::ArrayRef<lldb::ProcessSP> traced_processes, + llvm::ArrayRef<lldb::ThreadPostMortemTraceSP> traced_threads); + + /// This constructor is used by CreateInstanceForPostmortemTrace to get the + /// instance ready before using shared pointers, which is a limitation of C++. + TraceIntelPT(JSONTraceBundleDescription &bundle_description, + llvm::ArrayRef<lldb::ProcessSP> traced_processes); + /// \} /// Constructor for live processes - TraceIntelPT(Process &live_process) - : Trace(live_process), m_thread_decoders(){}; + TraceIntelPT(Process &live_process) : Trace(live_process){}; /// Decode the trace of the given thread that, i.e. recontruct the traced /// instructions. @@ -174,15 +202,32 @@ private: /// /// \return /// 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. + /// errors are embedded in the instruction list. An \a llvm::Error is + /// returned if the decoder couldn't be properly set up. + llvm::Expected<DecodedThreadSP> Decode(Thread &thread); + + /// We package all the data that can change upon process stops to make sure + /// this contract is very visible. + /// This variable should only be accessed directly by constructores or live + /// process data refreshers. + struct Storage { + llvm::Optional<TraceIntelPTMultiCpuDecoder> multicpu_decoder; + /// These decoders are used for the non-per-cpu case + llvm::DenseMap<lldb::tid_t, std::unique_ptr<ThreadDecoder>> thread_decoders; + /// Helper variable used to track long running operations for telemetry. + TaskTimer task_timer; + /// It is provided by either a trace bundle or a live process to convert TSC + /// counters to and from nanos. It might not be available on all hosts. + llvm::Optional<LinuxPerfZeroTscConversion> tsc_conversion; + } m_storage; + + /// It is provided by either a trace bundle or a live process' "cpuInfo" + /// binary data. We don't put it in the Storage because this variable doesn't + /// change. llvm::Optional<pt_cpu> m_cpu_info; - std::map<lldb::tid_t, 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; + + /// Get the storage after refreshing the data in the case of a live process. + Storage &GetUpdatedStorage(); }; } // namespace trace_intel_pt diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTBundleLoader.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTBundleLoader.cpp new file mode 100644 index 000000000000..3715e46c659c --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTBundleLoader.cpp @@ -0,0 +1,333 @@ +//===-- TraceIntelPTBundleLoader.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 "TraceIntelPTBundleLoader.h" + +#include "../common/ThreadPostMortemTrace.h" +#include "TraceIntelPT.h" +#include "TraceIntelPTJSONStructs.h" + +#include "lldb/Core/Debugger.h" +#include "lldb/Core/Module.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::trace_intel_pt; +using namespace llvm; + +FileSpec TraceIntelPTBundleLoader::NormalizePath(const std::string &path) { + FileSpec file_spec(path); + if (file_spec.IsRelative()) + file_spec.PrependPathComponent(m_bundle_dir); + return file_spec; +} + +Error TraceIntelPTBundleLoader::ParseModule(Target &target, + const JSONModule &module) { + auto do_parse = [&]() -> Error { + FileSpec system_file_spec(module.system_path); + + FileSpec local_file_spec(module.file.hasValue() ? *module.file + : module.system_path); + + ModuleSpec module_spec; + module_spec.GetFileSpec() = local_file_spec; + module_spec.GetPlatformFileSpec() = system_file_spec; + + if (module.uuid.hasValue()) + module_spec.GetUUID().SetFromStringRef(*module.uuid); + + Status error; + ModuleSP module_sp = + target.GetOrCreateModule(module_spec, /*notify*/ false, &error); + + if (error.Fail()) + return error.ToError(); + + bool load_addr_changed = false; + module_sp->SetLoadAddress(target, module.load_address.value, false, + load_addr_changed); + return Error::success(); + }; + if (Error err = do_parse()) + return createStringError( + inconvertibleErrorCode(), "Error when parsing module %s. %s", + module.system_path.c_str(), toString(std::move(err)).c_str()); + return Error::success(); +} + +Error TraceIntelPTBundleLoader::CreateJSONError(json::Path::Root &root, + const json::Value &value) { + std::string err; + raw_string_ostream os(err); + root.printErrorContext(value, os); + return createStringError( + std::errc::invalid_argument, "%s\n\nContext:\n%s\n\nSchema:\n%s", + toString(root.getError()).c_str(), os.str().c_str(), GetSchema().data()); +} + +ThreadPostMortemTraceSP +TraceIntelPTBundleLoader::ParseThread(Process &process, + const JSONThread &thread) { + lldb::tid_t tid = static_cast<lldb::tid_t>(thread.tid); + + Optional<FileSpec> trace_file; + if (thread.ipt_trace) + trace_file = FileSpec(*thread.ipt_trace); + + ThreadPostMortemTraceSP thread_sp = + std::make_shared<ThreadPostMortemTrace>(process, tid, trace_file); + process.GetThreadList().AddThread(thread_sp); + return thread_sp; +} + +Expected<TraceIntelPTBundleLoader::ParsedProcess> +TraceIntelPTBundleLoader::ParseProcess(const JSONProcess &process) { + TargetSP target_sp; + Status error = m_debugger.GetTargetList().CreateTarget( + m_debugger, /*user_exe_path*/ StringRef(), process.triple.value_or(""), + eLoadDependentsNo, + /*platform_options*/ nullptr, target_sp); + + if (!target_sp) + return error.ToError(); + + ParsedProcess parsed_process; + parsed_process.target_sp = target_sp; + + ProcessSP process_sp = target_sp->CreateProcess( + /*listener*/ nullptr, "trace", + /*crash_file*/ nullptr, + /*can_connect*/ false); + + process_sp->SetID(static_cast<lldb::pid_t>(process.pid)); + + for (const JSONThread &thread : process.threads) + parsed_process.threads.push_back(ParseThread(*process_sp, thread)); + + for (const JSONModule &module : process.modules) + if (Error err = ParseModule(*target_sp, module)) + return std::move(err); + + if (!process.threads.empty()) + process_sp->GetThreadList().SetSelectedThreadByIndexID(0); + + // We invoke DidAttach to create a correct stopped state for the process and + // its threads. + ArchSpec process_arch; + process_sp->DidAttach(process_arch); + + return parsed_process; +} + +Expected<std::vector<TraceIntelPTBundleLoader::ParsedProcess>> +TraceIntelPTBundleLoader::LoadBundle( + const JSONTraceBundleDescription &bundle_description) { + std::vector<ParsedProcess> parsed_processes; + + auto HandleError = [&](Error &&err) { + // Delete all targets that were created so far in case of failures + for (ParsedProcess &parsed_process : parsed_processes) + m_debugger.GetTargetList().DeleteTarget(parsed_process.target_sp); + return std::move(err); + }; + + for (const JSONProcess &process : bundle_description.processes) { + if (Expected<ParsedProcess> parsed_process = ParseProcess(process)) + parsed_processes.push_back(std::move(*parsed_process)); + else + return HandleError(parsed_process.takeError()); + } + + return parsed_processes; +} + +StringRef TraceIntelPTBundleLoader::GetSchema() { + static std::string schema; + if (schema.empty()) { + schema = R"({ + "type": "intel-pt", + "cpuInfo": { + // CPU information gotten from, for example, /proc/cpuinfo. + + "vendor": "GenuineIntel" | "unknown", + "family": integer, + "model": integer, + "stepping": integer + }, + "processes": [ + { + "pid": integer, + "triple"?: string, + // Optional clang/llvm target triple. + "threads": [ + // A list of known threads for the given process. When context switch + // data is provided, LLDB will automatically create threads for the + // this process whenever it finds new threads when traversing the + // context switches, so passing values to this list in this case is + // optional. + { + "tid": integer, + "iptTrace"?: string + // Path to the raw Intel PT buffer file for this thread. + } + ], + "modules": [ + { + "systemPath": string, + // Original path of the module at runtime. + "file"?: string, + // Path to a copy of the file if not available at "systemPath". + "loadAddress": integer | string decimal | hex string, + // Lowest address of the sections of the module loaded on memory. + "uuid"?: string, + // Build UUID for the file for sanity checks. + } + ] + } + ], + "cpus"?: [ + { + "id": integer, + // Id of this CPU core. + "iptTrace": string, + // Path to the raw Intel PT buffer for this cpu core. + "contextSwitchTrace": string, + // Path to the raw perf_event_open context switch trace file for this cpu core. + // The perf_event must have been configured with PERF_SAMPLE_TID and + // PERF_SAMPLE_TIME, as well as sample_id_all = 1. + } + ], + "tscPerfZeroConversion"?: { + // Values used to convert between TSCs and nanoseconds. See the time_zero + // section in https://man7.org/linux/man-pages/man2/perf_event_open.2.html + // for for information. + + "timeMult": integer, + "timeShift": integer, + "timeZero": integer | string decimal | hex string, + } +} + +Notes: + +- All paths are either absolute or relative to folder containing the bundle description file. +- "cpus" is provided if and only if processes[].threads[].iptTrace is not provided. +- "tscPerfZeroConversion" must be provided if "cpus" is provided. + })"; + } + return schema; +} + +Error TraceIntelPTBundleLoader::AugmentThreadsFromContextSwitches( + JSONTraceBundleDescription &bundle_description) { + if (!bundle_description.cpus) + return Error::success(); + + if (!bundle_description.tsc_perf_zero_conversion) + return createStringError(inconvertibleErrorCode(), + "TSC to nanos conversion values are needed when " + "context switch information is provided."); + + DenseMap<lldb::pid_t, JSONProcess *> indexed_processes; + DenseMap<JSONProcess *, DenseSet<tid_t>> indexed_threads; + + for (JSONProcess &process : bundle_description.processes) { + indexed_processes[process.pid] = &process; + for (JSONThread &thread : process.threads) + indexed_threads[&process].insert(thread.tid); + } + + auto on_thread_seen = [&](lldb::pid_t pid, tid_t tid) { + auto proc = indexed_processes.find(pid); + if (proc == indexed_processes.end()) + return; + if (indexed_threads[proc->second].count(tid)) + return; + indexed_threads[proc->second].insert(tid); + proc->second->threads.push_back({tid, /*ipt_trace=*/None}); + }; + + for (const JSONCpu &cpu : *bundle_description.cpus) { + Error err = Trace::OnDataFileRead( + FileSpec(cpu.context_switch_trace), + [&](ArrayRef<uint8_t> data) -> Error { + Expected<std::vector<ThreadContinuousExecution>> executions = + DecodePerfContextSwitchTrace(data, cpu.id, + *bundle_description.tsc_perf_zero_conversion); + if (!executions) + return executions.takeError(); + for (const ThreadContinuousExecution &execution : *executions) + on_thread_seen(execution.pid, execution.tid); + return Error::success(); + }); + if (err) + return err; + } + return Error::success(); +} + +Expected<TraceSP> TraceIntelPTBundleLoader::CreateTraceIntelPTInstance( + JSONTraceBundleDescription &bundle_description, std::vector<ParsedProcess> &parsed_processes) { + std::vector<ThreadPostMortemTraceSP> threads; + std::vector<ProcessSP> processes; + for (const ParsedProcess &parsed_process : parsed_processes) { + processes.push_back(parsed_process.target_sp->GetProcessSP()); + threads.insert(threads.end(), parsed_process.threads.begin(), + parsed_process.threads.end()); + } + + TraceSP trace_instance = TraceIntelPT::CreateInstanceForPostmortemTrace( + bundle_description, processes, threads); + for (const ParsedProcess &parsed_process : parsed_processes) + parsed_process.target_sp->SetTrace(trace_instance); + + return trace_instance; +} + +void TraceIntelPTBundleLoader::NormalizeAllPaths( + JSONTraceBundleDescription &bundle_description) { + for (JSONProcess &process : bundle_description.processes) { + for (JSONModule &module : process.modules) { + module.system_path = NormalizePath(module.system_path).GetPath(); + if (module.file) + module.file = NormalizePath(*module.file).GetPath(); + } + for (JSONThread &thread : process.threads) { + if (thread.ipt_trace) + thread.ipt_trace = NormalizePath(*thread.ipt_trace).GetPath(); + } + } + if (bundle_description.cpus) { + for (JSONCpu &cpu : *bundle_description.cpus) { + cpu.context_switch_trace = + NormalizePath(cpu.context_switch_trace).GetPath(); + cpu.ipt_trace = NormalizePath(cpu.ipt_trace).GetPath(); + } + } +} + +Expected<TraceSP> TraceIntelPTBundleLoader::Load() { + json::Path::Root root("traceBundle"); + JSONTraceBundleDescription bundle_description; + if (!fromJSON(m_bundle_description, bundle_description, root)) + return CreateJSONError(root, m_bundle_description); + + NormalizeAllPaths(bundle_description); + + if (Error err = AugmentThreadsFromContextSwitches(bundle_description)) + return std::move(err); + + if (Expected<std::vector<ParsedProcess>> parsed_processes = + LoadBundle(bundle_description)) + return CreateTraceIntelPTInstance(bundle_description, *parsed_processes); + else + return parsed_processes.takeError(); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTBundleLoader.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTBundleLoader.h new file mode 100644 index 000000000000..b0b926e1b7d4 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTBundleLoader.h @@ -0,0 +1,120 @@ +//===-- TraceIntelPTBundleLoader.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_TRACEINTELPTBUNDLELOADER_H +#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTBUNDLELOADER_H + +#include "../common/ThreadPostMortemTrace.h" +#include "TraceIntelPTJSONStructs.h" + +namespace lldb_private { +namespace trace_intel_pt { + +class TraceIntelPT; + +class TraceIntelPTBundleLoader { +public: + /// Helper struct holding the objects created when parsing a process + struct ParsedProcess { + lldb::TargetSP target_sp; + std::vector<lldb::ThreadPostMortemTraceSP> threads; + }; + + /// \param[in] debugger + /// The debugger that will own the targets to create. + /// + /// \param[in] bundle_description + /// The JSON description of a trace bundle that follows the schema of the intel pt trace plug-in. + /// + /// \param[in] bundle_dir + /// The folder where the trace bundle is located. + TraceIntelPTBundleLoader(Debugger &debugger, + const llvm::json::Value &bundle_description, + llvm::StringRef bundle_dir) + : m_debugger(debugger), m_bundle_description(bundle_description), + m_bundle_dir(bundle_dir) {} + + /// \return + /// The JSON schema for the bundle description. + static llvm::StringRef GetSchema(); + + /// Parse the trace bundle description and create the corresponding \a + /// Target objects. In case of an error, no targets are created. + /// + /// \return + /// A \a lldb::TraceSP instance created according to the trace bundle information. In case of + /// errors, return a null pointer. + llvm::Expected<lldb::TraceSP> Load(); + +private: + /// Resolve non-absolute paths relative to the bundle folder. + FileSpec NormalizePath(const std::string &path); + + /// Create a post-mortem thread associated with the given \p process + /// using the definition from \p thread. + lldb::ThreadPostMortemTraceSP ParseThread(Process &process, + const JSONThread &thread); + + /// Given a bundle description and a list of fully parsed processes, + /// create an actual Trace instance that "traces" these processes. + llvm::Expected<lldb::TraceSP> + CreateTraceIntelPTInstance(JSONTraceBundleDescription &bundle_description, + std::vector<ParsedProcess> &parsed_processes); + + /// Create the corresponding Threads and Process objects given the JSON + /// process definition. + /// + /// \param[in] process + /// The JSON process definition + llvm::Expected<ParsedProcess> ParseProcess(const JSONProcess &process); + + /// Create a module associated with the given \p target using the definition from \p module. + llvm::Error ParseModule(Target &target, const JSONModule &module); + + /// Create a user-friendly error message upon a JSON-parsing failure using the + /// \a json::ObjectMapper functionality. + /// + /// \param[in] root + /// The \a llvm::json::Path::Root used to parse the JSON \a value. + /// + /// \param[in] value + /// The json value that failed to parse. + /// + /// \return + /// An \a llvm::Error containing the user-friendly error message. + llvm::Error CreateJSONError(llvm::json::Path::Root &root, + const llvm::json::Value &value); + + /// Create the corresponding Process, Thread and Module objects given this + /// bundle description. + llvm::Expected<std::vector<ParsedProcess>> + LoadBundle(const JSONTraceBundleDescription &bundle_description); + + /// When applicable, augment the list of threads in the trace bundle by + /// inspecting the context switch trace. This only applies for threads of + /// processes already specified in this bundle description. + /// + /// \return + /// An \a llvm::Error in case if failures, or \a llvm::Error::success + /// otherwise. + llvm::Error AugmentThreadsFromContextSwitches(JSONTraceBundleDescription &bundle_description); + + /// Modifiy the bundle description by normalizing all the paths relative to the + /// session file directory. + void NormalizeAllPaths(JSONTraceBundleDescription &bundle_description); + + Debugger &m_debugger; + const llvm::json::Value &m_bundle_description; + const std::string m_bundle_dir; +}; + +} // namespace trace_intel_pt +} // namespace lldb_private + + +#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTBUNDLELOADER_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTBundleSaver.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTBundleSaver.cpp new file mode 100644 index 000000000000..b2ebaee732b8 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTBundleSaver.cpp @@ -0,0 +1,311 @@ +//===-- TraceIntelPTBundleSaver.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 "TraceIntelPTBundleSaver.h" +#include "TraceIntelPT.h" +#include "TraceIntelPTJSONStructs.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleList.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/SectionLoadList.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/ThreadList.h" +#include "lldb/lldb-types.h" +#include "llvm/ADT/None.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/JSON.h" + +#include <fstream> +#include <iostream> +#include <sstream> +#include <string> + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::trace_intel_pt; +using namespace llvm; + +/// Write a stream of bytes from \p data to the given output file. +/// It creates or overwrites the output file, but not append. +static llvm::Error WriteBytesToDisk(FileSpec &output_file, + ArrayRef<uint8_t> data) { + std::basic_fstream<char> out_fs = std::fstream( + output_file.GetPath().c_str(), std::ios::out | std::ios::binary); + if (!data.empty()) + out_fs.write(reinterpret_cast<const char *>(&data[0]), data.size()); + + out_fs.close(); + if (!out_fs) + return createStringError(inconvertibleErrorCode(), + formatv("couldn't write to the file {0}", + output_file.GetPath().c_str())); + return Error::success(); +} + +/// Save the trace bundle description JSON object inside the given directory +/// as a file named \a trace.json. +/// +/// \param[in] trace_bundle_description +/// The trace bundle description as JSON Object. +/// +/// \param[in] directory +/// The directory where the JSON file will be saved. +/// +/// \return +/// \a llvm::Success if the operation was successful, or an \a llvm::Error +/// otherwise. +static llvm::Error +SaveTraceBundleDescription(const llvm::json::Value &trace_bundle_description, + const FileSpec &directory) { + FileSpec trace_path = directory; + trace_path.AppendPathComponent("trace.json"); + std::ofstream os(trace_path.GetPath()); + os << formatv("{0:2}", trace_bundle_description).str(); + os.close(); + if (!os) + return createStringError(inconvertibleErrorCode(), + formatv("couldn't write to the file {0}", + trace_path.GetPath().c_str())); + return Error::success(); +} + +/// Build the threads sub-section of the trace bundle description file. +/// Any associated binary files are created inside the given directory. +/// +/// \param[in] process +/// The process being traced. +/// +/// \param[in] directory +/// The directory where files will be saved when building the threads +/// section. +/// +/// \return +/// The threads section or \a llvm::Error in case of failures. +static llvm::Expected<std::vector<JSONThread>> +BuildThreadsSection(Process &process, FileSpec directory) { + std::vector<JSONThread> json_threads; + TraceSP trace_sp = process.GetTarget().GetTrace(); + + FileSpec threads_dir = directory; + threads_dir.AppendPathComponent("threads"); + sys::fs::create_directories(threads_dir.GetCString()); + + for (ThreadSP thread_sp : process.Threads()) { + lldb::tid_t tid = thread_sp->GetID(); + if (!trace_sp->IsTraced(tid)) + continue; + + JSONThread json_thread; + json_thread.tid = tid; + + if (trace_sp->GetTracedCpus().empty()) { + FileSpec output_file = threads_dir; + output_file.AppendPathComponent(std::to_string(tid) + ".intelpt_trace"); + json_thread.ipt_trace = output_file.GetPath(); + + llvm::Error err = process.GetTarget().GetTrace()->OnThreadBinaryDataRead( + tid, IntelPTDataKinds::kIptTrace, + [&](llvm::ArrayRef<uint8_t> data) -> llvm::Error { + return WriteBytesToDisk(output_file, data); + }); + if (err) + return std::move(err); + } + + json_threads.push_back(std::move(json_thread)); + } + return json_threads; +} + +static llvm::Expected<llvm::Optional<std::vector<JSONCpu>>> +BuildCpusSection(TraceIntelPT &trace_ipt, FileSpec directory) { + if (trace_ipt.GetTracedCpus().empty()) + return None; + + std::vector<JSONCpu> json_cpus; + FileSpec cpus_dir = directory; + cpus_dir.AppendPathComponent("cpus"); + sys::fs::create_directories(cpus_dir.GetCString()); + + for (lldb::cpu_id_t cpu_id : trace_ipt.GetTracedCpus()) { + JSONCpu json_cpu; + json_cpu.id = cpu_id; + + { + FileSpec output_trace = cpus_dir; + output_trace.AppendPathComponent(std::to_string(cpu_id) + + ".intelpt_trace"); + json_cpu.ipt_trace = output_trace.GetPath(); + + llvm::Error err = trace_ipt.OnCpuBinaryDataRead( + cpu_id, IntelPTDataKinds::kIptTrace, + [&](llvm::ArrayRef<uint8_t> data) -> llvm::Error { + return WriteBytesToDisk(output_trace, data); + }); + if (err) + return std::move(err); + } + + { + FileSpec output_context_switch_trace = cpus_dir; + output_context_switch_trace.AppendPathComponent( + std::to_string(cpu_id) + ".perf_context_switch_trace"); + json_cpu.context_switch_trace = output_context_switch_trace.GetPath(); + + llvm::Error err = trace_ipt.OnCpuBinaryDataRead( + cpu_id, IntelPTDataKinds::kPerfContextSwitchTrace, + [&](llvm::ArrayRef<uint8_t> data) -> llvm::Error { + return WriteBytesToDisk(output_context_switch_trace, data); + }); + if (err) + return std::move(err); + } + json_cpus.push_back(std::move(json_cpu)); + } + return json_cpus; +} + +/// Build modules sub-section of the trace bundle. The original modules +/// will be copied over to the \a <directory/modules> folder. Invalid modules +/// are skipped. +/// Copying the modules has the benefit of making these +/// directories self-contained, as the raw traces and modules are part of the +/// output directory and can be sent to another machine, where lldb can load +/// them and replicate exactly the same trace session. +/// +/// \param[in] process +/// The process being traced. +/// +/// \param[in] directory +/// The directory where the modules files will be saved when building +/// the modules section. +/// Example: If a module \a libbar.so exists in the path +/// \a /usr/lib/foo/libbar.so, then it will be copied to +/// \a <directory>/modules/usr/lib/foo/libbar.so. +/// +/// \return +/// The modules section or \a llvm::Error in case of failures. +static llvm::Expected<std::vector<JSONModule>> +BuildModulesSection(Process &process, FileSpec directory) { + std::vector<JSONModule> json_modules; + ModuleList module_list = process.GetTarget().GetImages(); + for (size_t i = 0; i < module_list.GetSize(); ++i) { + ModuleSP module_sp(module_list.GetModuleAtIndex(i)); + if (!module_sp) + continue; + std::string system_path = module_sp->GetPlatformFileSpec().GetPath(); + // TODO: support memory-only libraries like [vdso] + if (!module_sp->GetFileSpec().IsAbsolute()) + continue; + + std::string file = module_sp->GetFileSpec().GetPath(); + ObjectFile *objfile = module_sp->GetObjectFile(); + if (objfile == nullptr) + continue; + + lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; + Address base_addr(objfile->GetBaseAddress()); + if (base_addr.IsValid() && + !process.GetTarget().GetSectionLoadList().IsEmpty()) + load_addr = base_addr.GetLoadAddress(&process.GetTarget()); + + if (load_addr == LLDB_INVALID_ADDRESS) + continue; + + FileSpec path_to_copy_module = directory; + path_to_copy_module.AppendPathComponent("modules"); + path_to_copy_module.AppendPathComponent(system_path); + sys::fs::create_directories(path_to_copy_module.GetDirectory().AsCString()); + + if (std::error_code ec = llvm::sys::fs::copy_file( + system_path, path_to_copy_module.GetPath())) + return createStringError( + inconvertibleErrorCode(), + formatv("couldn't write to the file. {0}", ec.message())); + + json_modules.push_back( + JSONModule{system_path, path_to_copy_module.GetPath(), + JSONUINT64{load_addr}, module_sp->GetUUID().GetAsString()}); + } + return json_modules; +} + +/// Build the processes section of the trace bundle description object. Besides +/// returning the processes information, this method saves to disk all modules +/// and raw traces corresponding to the traced threads of the given process. +/// +/// \param[in] process +/// The process being traced. +/// +/// \param[in] directory +/// The directory where files will be saved when building the processes +/// section. +/// +/// \return +/// The processes section or \a llvm::Error in case of failures. +static llvm::Expected<JSONProcess> +BuildProcessSection(Process &process, const FileSpec &directory) { + Expected<std::vector<JSONThread>> json_threads = + BuildThreadsSection(process, directory); + if (!json_threads) + return json_threads.takeError(); + + Expected<std::vector<JSONModule>> json_modules = + BuildModulesSection(process, directory); + if (!json_modules) + return json_modules.takeError(); + + return JSONProcess{ + process.GetID(), + process.GetTarget().GetArchitecture().GetTriple().getTriple(), + json_threads.get(), json_modules.get()}; +} + +/// See BuildProcessSection() +static llvm::Expected<std::vector<JSONProcess>> +BuildProcessesSection(TraceIntelPT &trace_ipt, const FileSpec &directory) { + std::vector<JSONProcess> processes; + for (Process *process : trace_ipt.GetAllProcesses()) { + if (llvm::Expected<JSONProcess> json_process = + BuildProcessSection(*process, directory)) + processes.push_back(std::move(*json_process)); + else + return json_process.takeError(); + } + return processes; +} + +Error TraceIntelPTBundleSaver::SaveToDisk(TraceIntelPT &trace_ipt, + FileSpec directory) { + if (std::error_code ec = + sys::fs::create_directories(directory.GetPath().c_str())) + return llvm::errorCodeToError(ec); + + Expected<pt_cpu> cpu_info = trace_ipt.GetCPUInfo(); + if (!cpu_info) + return cpu_info.takeError(); + + FileSystem::Instance().Resolve(directory); + + Expected<std::vector<JSONProcess>> json_processes = + BuildProcessesSection(trace_ipt, directory); + + if (!json_processes) + return json_processes.takeError(); + + Expected<Optional<std::vector<JSONCpu>>> json_cpus = + BuildCpusSection(trace_ipt, directory); + if (!json_cpus) + return json_cpus.takeError(); + + JSONTraceBundleDescription json_intel_pt_bundle_desc{"intel-pt", *cpu_info, *json_processes, + *json_cpus, + trace_ipt.GetPerfZeroTscConversion()}; + + return SaveTraceBundleDescription(toJSON(json_intel_pt_bundle_desc), directory); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionSaver.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTBundleSaver.h index 943519f959e9..c36677e1c00d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionSaver.h +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTBundleSaver.h @@ -1,4 +1,4 @@ -//===-- TraceIntelPTSessionSaver.h ---------------------------*- C++ //-*-===// +//===-- TraceIntelPTBundleSaver.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,25 +6,22 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONSAVER_H -#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONSAVER_H +#ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTBUNDLESAVER_H +#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTBUNDLESAVER_H #include "TraceIntelPT.h" -#include "../common/TraceJSONStructs.h" +#include "TraceIntelPTJSONStructs.h" namespace lldb_private { namespace trace_intel_pt { -class TraceIntelPT; - -class TraceIntelPTSessionSaver { - +class TraceIntelPTBundleSaver { public: /// Save the Intel PT trace of a live process to the specified directory, /// which will be created if needed. This will also create a file - /// \a <directory>/trace.json with the main properties of the trace - /// session, along with others files which contain the actual trace data. + /// \a <directory>/trace.json with the description of the trace + /// bundle, along with others files which contain the actual trace data. /// The trace.json file can be used later as input for the "trace load" /// command to load the trace in LLDB. /// @@ -32,26 +29,15 @@ public: /// The Intel PT trace to be saved to disk. /// /// \param[in] directory - /// The directory where the trace files will be saved. + /// The directory where the trace bundle will be created. /// /// \return /// \a llvm::success if the operation was successful, or an \a llvm::Error /// otherwise. llvm::Error SaveToDisk(TraceIntelPT &trace_ipt, FileSpec directory); - -private: - /// Build trace section of the intel-pt trace session description file. - /// - /// \param[in] trace_ipt - /// The Intel PT trace. - /// - /// \return - /// The trace section an \a llvm::Error in case of failures. - llvm::Expected<JSONTraceIntelPTTrace> - BuildTraceSection(TraceIntelPT &trace_ipt); }; } // namespace trace_intel_pt } // namespace lldb_private -#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONSAVER_H +#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTBUNDLESAVER_H 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 index c2bc1b57b2bd..61fdb4574d54 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTConstants.h +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTConstants.h @@ -16,10 +16,11 @@ namespace lldb_private { namespace trace_intel_pt { -const size_t kDefaultThreadBufferSize = 4 * 1024; // 4KB +const size_t kDefaultIptTraceSize = 4 * 1024; // 4KB const size_t kDefaultProcessBufferSizeLimit = 5 * 1024 * 1024; // 500MB const bool kDefaultEnableTscValue = false; const llvm::Optional<size_t> kDefaultPsbPeriod = llvm::None; +const bool kDefaultPerCpuTracing = false; } // namespace trace_intel_pt } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTJSONStructs.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTJSONStructs.cpp index e36751e235dc..ca9813652d7a 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTJSONStructs.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTJSONStructs.cpp @@ -15,45 +15,135 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::trace_intel_pt; using namespace llvm; +using namespace llvm::json; -namespace llvm { -namespace json { +namespace lldb_private { +namespace trace_intel_pt { -bool fromJSON(const Value &value, JSONTraceIntelPTSettings &plugin_settings, - Path path) { +Optional<std::vector<lldb::cpu_id_t>> JSONTraceBundleDescription::GetCpuIds() { + if (!cpus) + return None; + std::vector<lldb::cpu_id_t> cpu_ids; + for (const JSONCpu &cpu : *cpus) + cpu_ids.push_back(cpu.id); + return cpu_ids; +} + +json::Value toJSON(const JSONModule &module) { + json::Object json_module; + json_module["systemPath"] = module.system_path; + if (module.file) + json_module["file"] = *module.file; + json_module["loadAddress"] = toJSON(module.load_address, true); + if (module.uuid) + json_module["uuid"] = *module.uuid; + return std::move(json_module); +} + +bool fromJSON(const json::Value &value, JSONModule &module, Path path) { + ObjectMapper o(value, path); + return o && o.map("systemPath", module.system_path) && + o.map("file", module.file) && + o.map("loadAddress", module.load_address) && + o.map("uuid", module.uuid); +} + +json::Value toJSON(const JSONThread &thread) { + json::Object obj{{"tid", thread.tid}}; + if (thread.ipt_trace) + obj["iptTrace"] = *thread.ipt_trace; + return obj; +} + +bool fromJSON(const json::Value &value, JSONThread &thread, Path path) { + ObjectMapper o(value, path); + return o && o.map("tid", thread.tid) && o.map("iptTrace", thread.ipt_trace); +} + +json::Value toJSON(const JSONProcess &process) { + return Object{ + {"pid", process.pid}, + {"triple", process.triple}, + {"threads", process.threads}, + {"modules", process.modules}, + }; +} + +bool fromJSON(const json::Value &value, JSONProcess &process, Path path) { ObjectMapper o(value, path); - return o && o.map("cpuInfo", plugin_settings.cpuInfo) && - fromJSON(value, (JSONTracePluginSettings &)plugin_settings, path); + return o && o.map("pid", process.pid) && o.map("triple", process.triple) && + o.map("threads", process.threads) && o.map("modules", process.modules); +} + +json::Value toJSON(const JSONCpu &cpu) { + return Object{ + {"id", cpu.id}, + {"iptTrace", cpu.ipt_trace}, + {"contextSwitchTrace", cpu.context_switch_trace}, + }; } -bool fromJSON(const json::Value &value, JSONTraceIntelPTCPUInfo &cpu_info, - Path path) { +bool fromJSON(const json::Value &value, JSONCpu &cpu, 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); + uint64_t cpu_id; + if (!(o && o.map("id", cpu_id) && o.map("iptTrace", cpu.ipt_trace) && + o.map("contextSwitchTrace", cpu.context_switch_trace))) + return false; + cpu.id = cpu_id; + return true; } -Value toJSON(const JSONTraceIntelPTCPUInfo &cpu_info) { - return Value(Object{{"family", cpu_info.family}, - {"model", cpu_info.model}, - {"stepping", cpu_info.stepping}, - {"vendor", cpu_info.vendor}}); +json::Value toJSON(const pt_cpu &cpu_info) { + return Object{ + {"vendor", cpu_info.vendor == pcv_intel ? "GenuineIntel" : "Unknown"}, + {"family", cpu_info.family}, + {"model", cpu_info.model}, + {"stepping", cpu_info.stepping}, + }; } -llvm::json::Value toJSON(const JSONTraceIntelPTTrace &trace) { - llvm::json::Object json_trace; - json_trace["type"] = trace.type; - json_trace["cpuInfo"] = toJSON(trace.cpuInfo); - return std::move(json_trace); +bool fromJSON(const json::Value &value, pt_cpu &cpu_info, Path path) { + ObjectMapper o(value, path); + std::string vendor; + uint64_t family, model, stepping; + if (!(o && o.map("vendor", vendor) && o.map("family", family) && + o.map("model", model) && o.map("stepping", stepping))) + return false; + cpu_info.vendor = vendor == "GenuineIntel" ? pcv_intel : pcv_unknown; + cpu_info.family = family; + cpu_info.model = model; + cpu_info.stepping = stepping; + return true; } -llvm::json::Value toJSON(const JSONTraceIntelPTSession &session) { - llvm::json::Object json_session; - json_session["trace"] = toJSON(session.ipt_trace); - json_session["processes"] = toJSON(session.session_base); - return std::move(json_session); +json::Value toJSON(const JSONTraceBundleDescription &bundle_description) { + return Object{{"type", bundle_description.type}, + {"processes", bundle_description.processes}, + // We have to do this because the compiler fails at doing it + // automatically because pt_cpu is not in a namespace + {"cpuInfo", toJSON(bundle_description.cpu_info)}, + {"cpus", bundle_description.cpus}, + {"tscPerfZeroConversion", bundle_description.tsc_perf_zero_conversion}}; +} + +bool fromJSON(const json::Value &value, JSONTraceBundleDescription &bundle_description, Path path) { + ObjectMapper o(value, path); + if (!(o && o.map("processes", bundle_description.processes) && + o.map("type", bundle_description.type) && o.map("cpus", bundle_description.cpus) && + o.map("tscPerfZeroConversion", bundle_description.tsc_perf_zero_conversion))) + return false; + if (bundle_description.cpus && !bundle_description.tsc_perf_zero_conversion) { + path.report( + "\"tscPerfZeroConversion\" is required when \"cpus\" is provided"); + return false; + } + // We have to do this because the compiler fails at doing it automatically + // because pt_cpu is not in a namespace + if (!fromJSON(*value.getAsObject()->get("cpuInfo"), bundle_description.cpu_info, + path.field("cpuInfo"))) + return false; + return true; } -} // namespace json -} // namespace llvm +} // namespace trace_intel_pt +} // namespace lldb_private diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTJSONStructs.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTJSONStructs.h index ec024f27b8c9..687c0a793609 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTJSONStructs.h +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTJSONStructs.h @@ -9,67 +9,84 @@ #ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTJSONSTRUCTS_H #define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTJSONSTRUCTS_H -#include "../common/TraceJSONStructs.h" +#include "lldb/lldb-types.h" + +#include "lldb/Utility/TraceIntelPTGDBRemotePackets.h" + +#include "llvm/ADT/Optional.h" +#include "llvm/Support/JSON.h" + #include <intel-pt.h> +#include <vector> namespace lldb_private { namespace trace_intel_pt { -struct JSONTraceIntelPTCPUInfo { - JSONTraceIntelPTCPUInfo() = default; - - JSONTraceIntelPTCPUInfo(pt_cpu cpu_info) { - family = static_cast<int64_t>(cpu_info.family); - model = static_cast<int64_t>(cpu_info.model); - stepping = static_cast<int64_t>(cpu_info.stepping); - vendor = cpu_info.vendor == pcv_intel ? "intel" : "Unknown"; - } +struct JSONModule { + std::string system_path; + llvm::Optional<std::string> file; + JSONUINT64 load_address; + llvm::Optional<std::string> uuid; +}; - int64_t family; - int64_t model; - int64_t stepping; - std::string vendor; +struct JSONThread { + uint64_t tid; + llvm::Optional<std::string> ipt_trace; }; -struct JSONTraceIntelPTTrace { - std::string type; - JSONTraceIntelPTCPUInfo cpuInfo; +struct JSONProcess { + uint64_t pid; + llvm::Optional<std::string> triple; + std::vector<JSONThread> threads; + std::vector<JSONModule> modules; }; -struct JSONTraceIntelPTSession { - JSONTraceIntelPTTrace ipt_trace; - JSONTraceSessionBase session_base; +struct JSONCpu { + lldb::cpu_id_t id; + std::string ipt_trace; + std::string context_switch_trace; }; -struct JSONTraceIntelPTSettings : JSONTracePluginSettings { - JSONTraceIntelPTCPUInfo cpuInfo; +struct JSONTraceBundleDescription { + std::string type; + pt_cpu cpu_info; + std::vector<JSONProcess> processes; + llvm::Optional<std::vector<JSONCpu>> cpus; + llvm::Optional<LinuxPerfZeroTscConversion> tsc_perf_zero_conversion; + + llvm::Optional<std::vector<lldb::cpu_id_t>> GetCpuIds(); }; -} // namespace trace_intel_pt -} // namespace lldb_private +llvm::json::Value toJSON(const JSONModule &module); + +llvm::json::Value toJSON(const JSONThread &thread); -namespace llvm { -namespace json { +llvm::json::Value toJSON(const JSONProcess &process); -bool fromJSON( - const Value &value, - lldb_private::trace_intel_pt::JSONTraceIntelPTSettings &plugin_settings, - Path path); +llvm::json::Value toJSON(const JSONCpu &cpu); -bool fromJSON(const llvm::json::Value &value, - lldb_private::trace_intel_pt::JSONTraceIntelPTCPUInfo &packet, +llvm::json::Value toJSON(const pt_cpu &cpu_info); + +llvm::json::Value toJSON(const JSONTraceBundleDescription &bundle_description); + +bool fromJSON(const llvm::json::Value &value, JSONModule &module, llvm::json::Path path); -llvm::json::Value -toJSON(const lldb_private::trace_intel_pt::JSONTraceIntelPTCPUInfo &cpu_info); +bool fromJSON(const llvm::json::Value &value, JSONThread &thread, + llvm::json::Path path); + +bool fromJSON(const llvm::json::Value &value, JSONProcess &process, + llvm::json::Path path); -llvm::json::Value -toJSON(const lldb_private::trace_intel_pt::JSONTraceIntelPTTrace &trace); +bool fromJSON(const llvm::json::Value &value, JSONCpu &cpu, + llvm::json::Path path); -llvm::json::Value -toJSON(const lldb_private::trace_intel_pt::JSONTraceIntelPTSession &session); +bool fromJSON(const llvm::json::Value &value, pt_cpu &cpu_info, + llvm::json::Path path); -} // namespace json -} // namespace llvm +bool fromJSON(const llvm::json::Value &value, JSONTraceBundleDescription &bundle_description, + llvm::json::Path path); +} // namespace trace_intel_pt +} // namespace lldb_private #endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTJSONSTRUCTS_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTMultiCpuDecoder.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTMultiCpuDecoder.cpp new file mode 100644 index 000000000000..d2dbc049672c --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTMultiCpuDecoder.cpp @@ -0,0 +1,189 @@ +//===-- TraceIntelPTMultiCpuDecoder.cpp ----0------------------------------===// +// +// 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 "TraceIntelPTMultiCpuDecoder.h" + +#include "TraceIntelPT.h" + +#include "llvm/Support/Error.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::trace_intel_pt; +using namespace llvm; + +TraceIntelPTMultiCpuDecoder::TraceIntelPTMultiCpuDecoder( + TraceIntelPTSP trace_sp) + : m_trace_wp(trace_sp) { + for (Process *proc : trace_sp->GetAllProcesses()) { + for (ThreadSP thread_sp : proc->GetThreadList().Threads()) { + m_tids.insert(thread_sp->GetID()); + } + } +} + +TraceIntelPTSP TraceIntelPTMultiCpuDecoder::GetTrace() { + return m_trace_wp.lock(); +} + +bool TraceIntelPTMultiCpuDecoder::TracesThread(lldb::tid_t tid) const { + return m_tids.count(tid); +} + +Expected<DecodedThreadSP> TraceIntelPTMultiCpuDecoder::Decode(Thread &thread) { + if (Error err = CorrelateContextSwitchesAndIntelPtTraces()) + return std::move(err); + + auto it = m_decoded_threads.find(thread.GetID()); + if (it != m_decoded_threads.end()) + return it->second; + + DecodedThreadSP decoded_thread_sp = + std::make_shared<DecodedThread>(thread.shared_from_this()); + + TraceIntelPTSP trace_sp = GetTrace(); + + Error err = trace_sp->OnAllCpusBinaryDataRead( + IntelPTDataKinds::kIptTrace, + [&](const DenseMap<cpu_id_t, ArrayRef<uint8_t>> &buffers) -> Error { + auto it = m_continuous_executions_per_thread->find(thread.GetID()); + if (it != m_continuous_executions_per_thread->end()) + return DecodeSystemWideTraceForThread(*decoded_thread_sp, *trace_sp, + buffers, it->second); + + return Error::success(); + }); + if (err) + return std::move(err); + + m_decoded_threads.try_emplace(thread.GetID(), decoded_thread_sp); + return decoded_thread_sp; +} + +static Expected<std::vector<IntelPTThreadSubtrace>> +GetIntelPTSubtracesForCpu(TraceIntelPT &trace, cpu_id_t cpu_id) { + std::vector<IntelPTThreadSubtrace> intel_pt_subtraces; + Error err = trace.OnCpuBinaryDataRead( + cpu_id, IntelPTDataKinds::kIptTrace, + [&](ArrayRef<uint8_t> data) -> Error { + Expected<std::vector<IntelPTThreadSubtrace>> split_trace = + SplitTraceInContinuousExecutions(trace, data); + if (!split_trace) + return split_trace.takeError(); + + intel_pt_subtraces = std::move(*split_trace); + return Error::success(); + }); + if (err) + return std::move(err); + return intel_pt_subtraces; +} + +Expected<DenseMap<lldb::tid_t, std::vector<IntelPTThreadContinousExecution>>> +TraceIntelPTMultiCpuDecoder::DoCorrelateContextSwitchesAndIntelPtTraces() { + DenseMap<lldb::tid_t, std::vector<IntelPTThreadContinousExecution>> + continuous_executions_per_thread; + TraceIntelPTSP trace_sp = GetTrace(); + + Optional<LinuxPerfZeroTscConversion> conv_opt = + trace_sp->GetPerfZeroTscConversion(); + if (!conv_opt) + return createStringError( + inconvertibleErrorCode(), + "TSC to nanoseconds conversion values were not found"); + + LinuxPerfZeroTscConversion tsc_conversion = *conv_opt; + + for (cpu_id_t cpu_id : trace_sp->GetTracedCpus()) { + Expected<std::vector<IntelPTThreadSubtrace>> intel_pt_subtraces = + GetIntelPTSubtracesForCpu(*trace_sp, cpu_id); + if (!intel_pt_subtraces) + return intel_pt_subtraces.takeError(); + + // We'll be iterating through the thread continuous executions and the intel + // pt subtraces sorted by time. + auto it = intel_pt_subtraces->begin(); + auto on_new_thread_execution = + [&](const ThreadContinuousExecution &thread_execution) { + IntelPTThreadContinousExecution execution(thread_execution); + + for (; it != intel_pt_subtraces->end() && + it->tsc < thread_execution.GetEndTSC(); + it++) { + if (it->tsc > thread_execution.GetStartTSC()) { + execution.intelpt_subtraces.push_back(*it); + } else { + m_unattributed_intelpt_subtraces++; + } + } + continuous_executions_per_thread[thread_execution.tid].push_back( + execution); + }; + Error err = trace_sp->OnCpuBinaryDataRead( + cpu_id, IntelPTDataKinds::kPerfContextSwitchTrace, + [&](ArrayRef<uint8_t> data) -> Error { + Expected<std::vector<ThreadContinuousExecution>> executions = + DecodePerfContextSwitchTrace(data, cpu_id, tsc_conversion); + if (!executions) + return executions.takeError(); + for (const ThreadContinuousExecution &exec : *executions) + on_new_thread_execution(exec); + return Error::success(); + }); + if (err) + return std::move(err); + } + // We now sort the executions of each thread to have them ready for + // instruction decoding + for (auto &tid_executions : continuous_executions_per_thread) + std::sort(tid_executions.second.begin(), tid_executions.second.end()); + + return continuous_executions_per_thread; +} + +Error TraceIntelPTMultiCpuDecoder::CorrelateContextSwitchesAndIntelPtTraces() { + if (m_setup_error) + return createStringError(inconvertibleErrorCode(), m_setup_error->c_str()); + + if (m_continuous_executions_per_thread) + return Error::success(); + + Error err = GetTrace()->GetTimer().ForGlobal().TimeTask<Error>( + "Context switch and Intel PT traces correlation", [&]() -> Error { + if (auto correlation = DoCorrelateContextSwitchesAndIntelPtTraces()) { + m_continuous_executions_per_thread.emplace(std::move(*correlation)); + return Error::success(); + } else { + return correlation.takeError(); + } + }); + if (err) { + m_setup_error = toString(std::move(err)); + return createStringError(inconvertibleErrorCode(), m_setup_error->c_str()); + } + return Error::success(); +} + +size_t TraceIntelPTMultiCpuDecoder::GetNumContinuousExecutionsForThread( + lldb::tid_t tid) const { + if (!m_continuous_executions_per_thread) + return 0; + auto it = m_continuous_executions_per_thread->find(tid); + if (it == m_continuous_executions_per_thread->end()) + return 0; + return it->second.size(); +} + +size_t TraceIntelPTMultiCpuDecoder::GetTotalContinuousExecutionsCount() const { + if (!m_continuous_executions_per_thread) + return 0; + size_t count = 0; + for (const auto &kv : *m_continuous_executions_per_thread) + count += kv.second.size(); + return count; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTMultiCpuDecoder.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTMultiCpuDecoder.h new file mode 100644 index 000000000000..11771e018f7b --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTMultiCpuDecoder.h @@ -0,0 +1,89 @@ +//===-- TraceIntelPTMultiCpuDecoder.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_TRACEINTELPTMULTICPUDECODER_H +#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTMULTICPUDECODER_H + +#include "LibiptDecoder.h" +#include "PerfContextSwitchDecoder.h" +#include "ThreadDecoder.h" +#include "forward-declarations.h" + +namespace lldb_private { +namespace trace_intel_pt { + +/// Class used to decode a multi-cpu Intel PT trace. It assumes that each +/// thread could have potentially been executed on different cpu cores. It uses +/// a context switch trace per CPU with timestamps to identify which thread owns +/// each Intel PT decoded instruction and in which order. It also assumes that +/// the Intel PT data and context switches might have gaps in their traces due +/// to contention or race conditions. Finally, it assumes that a tid is not +/// repeated twice for two different threads because of the shortness of the +/// intel pt trace. +/// +/// This object should be recreated after every stop in the case of live +/// processes. +class TraceIntelPTMultiCpuDecoder { +public: + /// \param[in] TraceIntelPT + /// The trace object to be decoded + TraceIntelPTMultiCpuDecoder(TraceIntelPTSP trace_sp); + + /// \return + /// A \a DecodedThread for the \p thread by decoding its instructions on all + /// CPUs, sorted by TSCs. An \a llvm::Error is returned if the decoder + /// couldn't be properly set up. + llvm::Expected<DecodedThreadSP> Decode(Thread &thread); + + /// \return + /// \b true if the given \p tid is managed by this decoder, regardless of + /// whether there's tracing data associated to it or not. + bool TracesThread(lldb::tid_t tid) const; + + /// \return + /// The number of continuous executions found for the given \p tid. + size_t GetNumContinuousExecutionsForThread(lldb::tid_t tid) const; + + /// \return + /// The total number of continuous executions found across CPUs. + size_t GetTotalContinuousExecutionsCount() const; + +private: + /// Traverse the context switch traces and the basic intel pt continuous + /// subtraces and produce a list of continuous executions for each process and + /// thread. + /// + /// See \a DoCorrelateContextSwitchesAndIntelPtTraces. + /// + /// Any errors are stored in \a m_setup_error. + llvm::Error CorrelateContextSwitchesAndIntelPtTraces(); + + /// Produce a mapping from thread ids to the list of continuos executions with + /// their associated intel pt subtraces. + llvm::Expected< + llvm::DenseMap<lldb::tid_t, std::vector<IntelPTThreadContinousExecution>>> + DoCorrelateContextSwitchesAndIntelPtTraces(); + + TraceIntelPTSP GetTrace(); + + std::weak_ptr<TraceIntelPT> m_trace_wp; + std::set<lldb::tid_t> m_tids; + llvm::Optional< + llvm::DenseMap<lldb::tid_t, std::vector<IntelPTThreadContinousExecution>>> + m_continuous_executions_per_thread; + llvm::DenseMap<lldb::tid_t, DecodedThreadSP> m_decoded_threads; + /// This variable will be non-None if a severe error happened during the setup + /// of the decoder and we don't want decoding to be reattempted. + llvm::Optional<std::string> m_setup_error; + uint64_t m_unattributed_intelpt_subtraces; +}; + +} // namespace trace_intel_pt +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTMULTICPUDECODER_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 714a13b6e5e0..29aa1459306a 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 @@ -35,18 +35,30 @@ let Command = "thread trace start intel pt" in { } let Command = "process trace start intel pt" in { - def process_trace_start_intel_pt_thread_size: Option<"thread-size", "s">, + def process_trace_start_intel_pt_buffer_size: Option<"buffer-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.">; + Desc<"Size in bytes used by each individual per-thread or per-cpu trace " + "buffer. It must be a power of 2 greater than or equal to 4096 (2^12) " + "bytes.">; + def process_trace_start_intel_pt_per_cpu_tracing: + Option<"per-cpu-tracing", "c">, + Group<1>, + Desc<"Instead of having an individual trace buffer per thread, which uses " + "a number trace buffers proportional to the number of running " + "threads, this option triggers the collection on a per cpu core " + "basis. This effectively traces the entire activity on all cpus " + "using a limited amount of trace buffers regardless of the number of " + "threads. This might cause data loss for less frequent threads. This " + "option forces the capture of TSC timestamps (see --tsc). Also, this " + "option can't be used simulatenously with any other trace sessions " + "because of its system-wide nature.">; 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. " + "the sum of the sizes of all thread and cpu 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 " 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 deleted file mode 100644 index 7e2c39a20255..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp +++ /dev/null @@ -1,69 +0,0 @@ -//===-- TraceIntelPTSessionFileParser.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 "TraceIntelPTSessionFileParser.h" - -#include "../common/ThreadPostMortemTrace.h" -#include "TraceIntelPT.h" - -using namespace lldb; -using namespace lldb_private; -using namespace lldb_private::trace_intel_pt; -using namespace llvm; - -StringRef TraceIntelPTSessionFileParser::GetSchema() { - static std::string schema; - if (schema.empty()) { - schema = TraceSessionFileParser::BuildSchema(R"({ - "type": "intel-pt", - "cpuInfo": { - "vendor": "intel" | "unknown", - "family": integer, - "model": integer, - "stepping": integer - } - })"); - } - return schema; -} - -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 &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(cpu_info, threads)); - for (const ParsedProcess &parsed_process : parsed_processes) - parsed_process.target_sp->SetTrace(trace_instance); - - return trace_instance; -} - -Expected<TraceSP> TraceIntelPTSessionFileParser::Parse() { - json::Path::Root root("traceSession"); - JSONTraceSession<JSONTraceIntelPTSettings> session; - if (!json::fromJSON(m_trace_session_file, session, root)) - return CreateJSONError(root, m_trace_session_file); - - if (Expected<std::vector<ParsedProcess>> parsed_processes = - ParseCommonSessionFile(session)) - return CreateTraceIntelPTInstance(ParsePTCPU(session.trace.cpuInfo), - *parsed_processes); - else - return parsed_processes.takeError(); -} 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 deleted file mode 100644 index 34883d3cf300..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h +++ /dev/null @@ -1,58 +0,0 @@ -//===-- TraceIntelPTSessionFileParser.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_TRACEINTELPTSESSIONFILEPARSER_H -#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONFILEPARSER_H - -#include "../common/TraceSessionFileParser.h" -#include "TraceIntelPT.h" -#include "TraceIntelPTJSONStructs.h" - -namespace lldb_private { -namespace trace_intel_pt { - -class TraceIntelPT; - -class TraceIntelPTSessionFileParser : public TraceSessionFileParser { -public: - - /// See \a TraceSessionFileParser::TraceSessionFileParser for the description - /// of these fields. - TraceIntelPTSessionFileParser(Debugger &debugger, - const llvm::json::Value &trace_session_file, - llvm::StringRef session_file_dir) - : TraceSessionFileParser(debugger, session_file_dir, GetSchema()), - m_trace_session_file(trace_session_file) {} - - /// \return - /// The JSON schema for the session data. - static llvm::StringRef GetSchema(); - - /// Parse the structured data trace session and create the corresponding \a - /// Target objects. In case of an error, no targets are created. - /// - /// \return - /// A \a lldb::TraceSP instance with the trace session data. In case of - /// errors, return a null pointer. - llvm::Expected<lldb::TraceSP> Parse(); - - lldb::TraceSP - CreateTraceIntelPTInstance(const pt_cpu &cpu_info, - std::vector<ParsedProcess> &parsed_processes); - -private: - static pt_cpu ParsePTCPU(const JSONTraceIntelPTCPUInfo &cpu_info); - - const llvm::json::Value &m_trace_session_file; -}; - -} // namespace trace_intel_pt -} // namespace lldb_private - - -#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONFILEPARSER_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionSaver.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionSaver.cpp deleted file mode 100644 index a8d03db1c25c..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionSaver.cpp +++ /dev/null @@ -1,79 +0,0 @@ -//===-- TraceIntelPTSessionSaver.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 "TraceIntelPTSessionSaver.h" -#include "../common/TraceSessionSaver.h" -#include "TraceIntelPT.h" -#include "TraceIntelPTJSONStructs.h" -#include "lldb/Core/Module.h" -#include "lldb/Core/ModuleList.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/SectionLoadList.h" -#include "lldb/Target/Target.h" -#include "lldb/Target/ThreadList.h" -#include "lldb/lldb-types.h" -#include "llvm/ADT/None.h" -#include "llvm/Support/Error.h" -#include "llvm/Support/JSON.h" - -#include <fstream> -#include <iostream> -#include <sstream> -#include <string> - -using namespace lldb; -using namespace lldb_private; -using namespace lldb_private::trace_intel_pt; -using namespace llvm; - -llvm::Error TraceIntelPTSessionSaver::SaveToDisk(TraceIntelPT &trace_ipt, - FileSpec directory) { - Process *live_process = trace_ipt.GetLiveProcess(); - if (live_process == nullptr) - return createStringError(inconvertibleErrorCode(), - "Saving a trace requires a live process."); - - if (std::error_code ec = - sys::fs::create_directories(directory.GetPath().c_str())) - return llvm::errorCodeToError(ec); - - llvm::Expected<JSONTraceIntelPTTrace> json_intel_pt_trace = - BuildTraceSection(trace_ipt); - if (!json_intel_pt_trace) - return json_intel_pt_trace.takeError(); - - llvm::Expected<JSONTraceSessionBase> json_session_description = - TraceSessionSaver::BuildProcessesSection( - *live_process, - [&](lldb::tid_t tid) - -> llvm::Expected<llvm::Optional<std::vector<uint8_t>>> { - if (!trace_ipt.IsTraced(tid)) - return None; - return trace_ipt.GetLiveThreadBuffer(tid); - }, - directory); - - if (!json_session_description) - return json_session_description.takeError(); - - JSONTraceIntelPTSession json_intel_pt_session{json_intel_pt_trace.get(), - json_session_description.get()}; - - return TraceSessionSaver::WriteSessionToFile( - llvm::json::toJSON(json_intel_pt_session), directory); -} - -llvm::Expected<JSONTraceIntelPTTrace> -TraceIntelPTSessionSaver::BuildTraceSection(TraceIntelPT &trace_ipt) { - llvm::Expected<pt_cpu> cpu_info = trace_ipt.GetCPUInfo(); - if (!cpu_info) - return cpu_info.takeError(); - - return JSONTraceIntelPTTrace{"intel-pt", - JSONTraceIntelPTCPUInfo(cpu_info.get())}; -} 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 index 3c5f811acc10..a05bf224bf07 100644 --- 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 @@ -9,12 +9,16 @@ #ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_FORWARD_DECLARATIONS_H #define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_FORWARD_DECLARATIONS_H +#include <memory> + namespace lldb_private { namespace trace_intel_pt { class TraceIntelPT; class ThreadDecoder; +using TraceIntelPTSP = std::shared_ptr<TraceIntelPT>; + } // 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/common/TraceHTR.cpp b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/common/TraceHTR.cpp index d29445cc004f..7deeaf2bf10f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/common/TraceHTR.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/common/TraceHTR.cpp @@ -130,8 +130,11 @@ TraceHTR::TraceHTR(Thread &thread, TraceCursor &cursor) // Move cursor to the first instruction in the trace cursor.SetForwards(true); - cursor.Seek(0, TraceCursor::SeekType::Set); + cursor.Seek(0, TraceCursor::SeekType::Beginning); + // TODO: fix after persona0220's patch on a new way to access instruction + // kinds + /* Target &target = thread.GetProcess()->GetTarget(); auto function_name_from_load_address = [&](lldb::addr_t load_address) -> llvm::Optional<ConstString> { @@ -146,15 +149,15 @@ TraceHTR::TraceHTR(Thread &thread, TraceCursor &cursor) return llvm::None; }; - bool more_data_in_trace = true; - while (more_data_in_trace) { - if (cursor.IsError()) { + while (cursor.HasValue()) { if (cursor.IsError()) { // Append a load address of 0 for all instructions that an error occured // while decoding. // TODO: Make distinction between errors by storing the error messages. // Currently, all errors are treated the same. m_instruction_layer_up->AppendInstruction(0); - more_data_in_trace = cursor.Next(); + cursor.Next(); + } else if (cursor.IsEvent()) { + cursor.Next(); } else { lldb::addr_t current_instruction_load_address = cursor.GetLoadAddress(); lldb::TraceInstructionControlFlowType current_instruction_type = @@ -162,7 +165,8 @@ TraceHTR::TraceHTR(Thread &thread, TraceCursor &cursor) m_instruction_layer_up->AppendInstruction( current_instruction_load_address); - more_data_in_trace = cursor.Next(); + cursor.Next(); + bool more_data_in_trace = cursor.HasValue(); if (current_instruction_type & lldb::eTraceInstructionControlFlowTypeCall) { if (more_data_in_trace && !cursor.IsError()) { @@ -178,6 +182,7 @@ TraceHTR::TraceHTR(Thread &thread, TraceCursor &cursor) } } } + */ } void HTRBlockMetadata::MergeMetadata( diff --git a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp index a72e46a0b703..194cc7459027 100644 --- a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp @@ -73,15 +73,22 @@ bool CommandObjectThreadTraceExportCTF::DoExecute(Args &command, if (thread == nullptr) { const uint32_t num_threads = process->GetThreadList().GetSize(); - size_t tid = m_options.m_thread_index.getValueOr(LLDB_INVALID_THREAD_ID); + size_t tid = m_options.m_thread_index.value_or(LLDB_INVALID_THREAD_ID); result.AppendErrorWithFormatv( "Thread index {0} is out of range (valid values are 1 - {1}).\n", tid, num_threads); return false; } else { - TraceHTR htr(*thread, *trace_sp->GetCursor(*thread)); - htr.ExecutePasses(); - if (llvm::Error err = htr.Export(m_options.m_file)) { + auto do_work = [&]() -> Error { + Expected<TraceCursorUP> cursor = trace_sp->CreateNewCursor(*thread); + if (!cursor) + return cursor.takeError(); + TraceHTR htr(*thread, **cursor); + htr.ExecutePasses(); + return htr.Export(m_options.m_file); + }; + + if (llvm::Error err = do_work()) { result.AppendErrorWithFormat("%s\n", toString(std::move(err)).c_str()); return false; } else { 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 2747e45756f0..6cd2165b7535 100644 --- a/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -50,9 +50,6 @@ #include "Plugins/ExpressionParser/Clang/ClangUserExpression.h" #include "Plugins/ExpressionParser/Clang/ClangUtil.h" #include "Plugins/ExpressionParser/Clang/ClangUtilityFunction.h" -#include "lldb/Utility/ArchSpec.h" -#include "lldb/Utility/Flags.h" - #include "lldb/Core/DumpDataExtractor.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" @@ -65,9 +62,11 @@ #include "lldb/Target/Language.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Flags.h" #include "lldb/Utility/LLDBAssert.h" -#include "lldb/Utility/Log.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Scalar.h" @@ -81,6 +80,7 @@ using namespace lldb; using namespace lldb_private; +using namespace lldb_private::dwarf; using namespace clang; using llvm::StringSwitch; @@ -495,6 +495,9 @@ static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) { case clang::Language::HIP: LangStd = LangStandard::lang_hip; break; + case clang::Language::HLSL: + LangStd = LangStandard::lang_hlsl; + break; } } @@ -507,7 +510,6 @@ static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) { Opts.GNUMode = Std.isGNUMode(); Opts.GNUInline = !Std.isC99(); Opts.HexFloats = Std.hasHexFloats(); - Opts.ImplicitInt = Std.hasImplicitInt(); Opts.WChar = true; @@ -688,9 +690,7 @@ ASTContext &TypeSystemClang::getASTContext() { class NullDiagnosticConsumer : public DiagnosticConsumer { public: - NullDiagnosticConsumer() { - m_log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); - } + NullDiagnosticConsumer() { m_log = GetLog(LLDBLog::Expressions); } void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &info) override { @@ -1148,7 +1148,7 @@ CompilerType TypeSystemClang::GetBuiltinTypeForDWARFEncodingAndBitSize( break; } - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES); + Log *log = GetLog(LLDBLog::Types); LLDB_LOG(log, "error: need to add support for DW_TAG_base_type '{0}' " "encoded with DW_ATE = {1:x}, bit_size = {2}", @@ -1492,7 +1492,7 @@ static bool TemplateParameterAllowsValue(NamedDecl *param, // 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); + Log *log = GetLog(LLDBLog::Expressions); LLDB_LOG(log, "Don't know how to compare template parameter to passed" " value. Decl kind of parameter is: {0}", @@ -1540,7 +1540,7 @@ static bool ClassTemplateAllowsToInstantiationArgs( return false; // Ensure that <typename...> != <typename>. - if (pack_parameter.hasValue() != instantiation_values.hasParameterPack()) + if (pack_parameter.has_value() != instantiation_values.hasParameterPack()) return false; // Compare the first pack parameter that was found with the first pack @@ -2022,6 +2022,8 @@ TypeSystemClang::GetOpaqueCompilerType(clang::ASTContext *ast, return ast->getSignedWCharType().getAsOpaquePtr(); case eBasicTypeUnsignedWChar: return ast->getUnsignedWCharType().getAsOpaquePtr(); + case eBasicTypeChar8: + return ast->Char8Ty.getAsOpaquePtr(); case eBasicTypeChar16: return ast->Char16Ty.getAsOpaquePtr(); case eBasicTypeChar32: @@ -4172,6 +4174,7 @@ TypeSystemClang::GetTypeClass(lldb::opaque_compiler_type_t type) { break; case clang::Type::Attributed: + case clang::Type::BTFTagAttributed: break; case clang::Type::TemplateTypeParm: break; @@ -5097,6 +5100,7 @@ lldb::Encoding TypeSystemClang::GetEncoding(lldb::opaque_compiler_type_t type, case clang::Type::DependentSizedExtVector: case clang::Type::UnresolvedUsing: case clang::Type::Attributed: + case clang::Type::BTFTagAttributed: case clang::Type::TemplateTypeParm: case clang::Type::SubstTemplateTypeParm: case clang::Type::SubstTemplateTypeParmPack: @@ -5250,6 +5254,7 @@ lldb::Format TypeSystemClang::GetFormat(lldb::opaque_compiler_type_t type) { case clang::Type::DependentSizedExtVector: case clang::Type::UnresolvedUsing: case clang::Type::Attributed: + case clang::Type::BTFTagAttributed: case clang::Type::TemplateTypeParm: case clang::Type::SubstTemplateTypeParm: case clang::Type::SubstTemplateTypeParmPack: @@ -5483,6 +5488,8 @@ TypeSystemClang::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) { return eBasicTypeSignedChar; case clang::BuiltinType::Char_U: return eBasicTypeUnsignedChar; + case clang::BuiltinType::Char8: + return eBasicTypeChar8; case clang::BuiltinType::Char16: return eBasicTypeChar16; case clang::BuiltinType::Char32: @@ -9797,8 +9804,8 @@ ScratchTypeSystemClang::GetForTarget(Target &target, auto type_system_or_err = target.GetScratchTypeSystemForLanguage( lldb::eLanguageTypeC, create_on_demand); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET), - std::move(err), "Couldn't get scratch TypeSystemClang"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Target), std::move(err), + "Couldn't get scratch TypeSystemClang"); return nullptr; } ScratchTypeSystemClang &scratch_ast = @@ -9830,10 +9837,7 @@ void ScratchTypeSystemClang::Dump(llvm::raw_ostream &output) { std::vector<KeyAndTS> sorted_typesystems; for (const auto &a : m_isolated_asts) sorted_typesystems.emplace_back(a.first, a.second.get()); - llvm::stable_sort(sorted_typesystems, - [](const KeyAndTS &lhs, const KeyAndTS &rhs) { - return lhs.first < rhs.first; - }); + llvm::stable_sort(sorted_typesystems, llvm::less_first()); // Dump each sub-AST too. for (const auto &a : sorted_typesystems) { 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 c59ecdb31790..4883f510eb31 100644 --- a/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h +++ b/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h @@ -35,7 +35,6 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Flags.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" #include "lldb/lldb-enumerations.h" class DWARFASTParserClang; 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 ccaac687ed7a..ac5e316eecb0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp @@ -21,6 +21,7 @@ #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamString.h" @@ -72,7 +73,7 @@ bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly( m_arch, nullptr, nullptr, range.GetBaseAddress(), opcode_data, opcode_size, 99999, prefer_file_cache)); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + Log *log = GetLog(LLDBLog::Unwind); if (disasm_sp) { @@ -379,7 +380,7 @@ size_t UnwindAssemblyInstEmulation::ReadMemory( EmulateInstruction *instruction, void *baton, const EmulateInstruction::Context &context, lldb::addr_t addr, void *dst, size_t dst_len) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + Log *log = GetLog(LLDBLog::Unwind); if (log && log->GetVerbose()) { StreamString strm; @@ -411,7 +412,7 @@ size_t UnwindAssemblyInstEmulation::WriteMemory( instruction->GetArchitecture().GetByteOrder(), instruction->GetArchitecture().GetAddressByteSize()); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + Log *log = GetLog(LLDBLog::Unwind); if (log && log->GetVerbose()) { StreamString strm; @@ -492,7 +493,7 @@ bool UnwindAssemblyInstEmulation::ReadRegister(EmulateInstruction *instruction, RegisterValue ®_value) { bool synthetic = GetRegisterValue(*reg_info, reg_value); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + Log *log = GetLog(LLDBLog::Unwind); if (log && log->GetVerbose()) { @@ -518,7 +519,7 @@ bool UnwindAssemblyInstEmulation::WriteRegister( bool UnwindAssemblyInstEmulation::WriteRegister( EmulateInstruction *instruction, const EmulateInstruction::Context &context, const RegisterInfo *reg_info, const RegisterValue ®_value) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + Log *log = GetLog(LLDBLog::Unwind); if (log && log->GetVerbose()) { @@ -613,6 +614,26 @@ bool UnwindAssemblyInstEmulation::WriteRegister( m_curr_row->SetRegisterLocationToSame(reg_num, false /*must_replace*/); m_curr_row_modified = true; + + // FP has been restored to its original value, we are back + // to using SP to calculate the CFA. + if (m_fp_is_cfa) { + m_fp_is_cfa = false; + RegisterInfo sp_reg_info; + lldb::RegisterKind sp_reg_kind = eRegisterKindGeneric; + uint32_t sp_reg_num = LLDB_REGNUM_GENERIC_SP; + m_inst_emulator_up->GetRegisterInfo(sp_reg_kind, sp_reg_num, + sp_reg_info); + RegisterValue sp_reg_val; + if (GetRegisterValue(sp_reg_info, sp_reg_val)) { + m_cfa_reg_info = sp_reg_info; + const uint32_t cfa_reg_num = + sp_reg_info.kinds[m_unwind_plan_ptr->GetRegisterKind()]; + assert(cfa_reg_num != LLDB_INVALID_REGNUM); + m_curr_row->GetCFAValue().SetIsRegisterPlusOffset( + cfa_reg_num, m_initial_sp - sp_reg_val.GetAsUInt64()); + } + } } break; case EmulateInstruction::eInfoTypeISA: diff --git a/contrib/llvm-project/lldb/source/Symbol/Block.cpp b/contrib/llvm-project/lldb/source/Symbol/Block.cpp index 4aafef34bd2d..6eeabe0ff5e4 100644 --- a/contrib/llvm-project/lldb/source/Symbol/Block.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/Block.cpp @@ -13,6 +13,7 @@ #include "lldb/Symbol/Function.h" #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/VariableList.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include <memory> @@ -334,7 +335,7 @@ void Block::FinalizeRanges() { void Block::AddRange(const Range &range) { Block *parent_block = GetParent(); if (parent_block && !parent_block->Contains(range)) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS)); + Log *log = GetLog(LLDBLog::Symbols); if (log) { ModuleSP module_sp(m_parent_scope->CalculateSymbolContextModule()); Function *function = m_parent_scope->CalculateSymbolContextFunction(); diff --git a/contrib/llvm-project/lldb/source/Symbol/CompactUnwindInfo.cpp b/contrib/llvm-project/lldb/source/Symbol/CompactUnwindInfo.cpp index 830fe5546c1c..ce597523c061 100644 --- a/contrib/llvm-project/lldb/source/Symbol/CompactUnwindInfo.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/CompactUnwindInfo.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "lldb/Symbol/CompactUnwindInfo.h" +#include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" #include "lldb/Core/Section.h" #include "lldb/Symbol/ObjectFile.h" @@ -15,6 +16,7 @@ #include "lldb/Target/Target.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" @@ -182,7 +184,7 @@ bool CompactUnwindInfo::GetUnwindPlan(Target &target, Address addr, if (ArchSpec arch = m_objfile.GetArchitecture()) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + Log *log = GetLog(LLDBLog::Unwind); if (log && log->GetVerbose()) { StreamString strm; addr.Dump( @@ -251,7 +253,7 @@ void CompactUnwindInfo::ScanIndex(const ProcessSP &process_sp) { return; } - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + Log *log = GetLog(LLDBLog::Unwind); if (log) m_objfile.GetModule()->LogMessage( log, "Reading compact unwind first-level indexes"); @@ -316,9 +318,8 @@ void CompactUnwindInfo::ScanIndex(const ProcessSP &process_sp) { m_unwindinfo_data.GetByteSize() || indexSectionOffset > m_unwindinfo_data.GetByteSize() || offset > m_unwindinfo_data.GetByteSize()) { - Host::SystemLog(Host::eSystemLogError, "error: Invalid offset " - "encountered in compact unwind " - "info, skipping\n"); + Debugger::ReportError( + "Invalid offset encountered in compact unwind info, skipping"); // don't trust anything from this compact_unwind section if it looks // blatantly invalid data in the header. m_indexes_computed = eLazyBoolNo; diff --git a/contrib/llvm-project/lldb/source/Symbol/CompileUnit.cpp b/contrib/llvm-project/lldb/source/Symbol/CompileUnit.cpp index 7c840d8bb064..cacb78de2426 100644 --- a/contrib/llvm-project/lldb/source/Symbol/CompileUnit.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/CompileUnit.cpp @@ -249,7 +249,7 @@ 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 uint32_t line = src_location_spec.GetLine().value_or(0); const bool check_inlines = src_location_spec.GetCheckInlines(); // First find all of the file indexes that match our "file_spec". If @@ -287,6 +287,9 @@ void CompileUnit::ResolveSymbolContext( if (num_file_indexes == 0) return; + // Found a matching source file in this compile unit load its debug info. + GetModule()->GetSymbolFile()->SetLoadDebugInfoEnabled(); + LineTable *line_table = sc.comp_unit->GetLineTable(); if (line_table == nullptr) { @@ -312,7 +315,7 @@ void CompileUnit::ResolveSymbolContext( 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 @@ -320,7 +323,7 @@ void CompileUnit::ResolveSymbolContext( const bool inlines = false; const bool exact = true; const llvm::Optional<uint16_t> column = - src_location_spec.GetColumn().hasValue() + src_location_spec.GetColumn() ? llvm::Optional<uint16_t>(line_entry.column) : llvm::None; diff --git a/contrib/llvm-project/lldb/source/Symbol/DWARFCallFrameInfo.cpp b/contrib/llvm-project/lldb/source/Symbol/DWARFCallFrameInfo.cpp index f0dce8f4793a..4e51bd411a75 100644 --- a/contrib/llvm-project/lldb/source/Symbol/DWARFCallFrameInfo.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/DWARFCallFrameInfo.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "lldb/Symbol/DWARFCallFrameInfo.h" +#include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" #include "lldb/Core/Section.h" #include "lldb/Core/dwarf.h" @@ -16,13 +17,15 @@ #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Timer.h" -#include <list> #include <cstring> +#include <list> using namespace lldb; using namespace lldb_private; +using namespace lldb_private::dwarf; // GetDwarfEHPtr // @@ -266,9 +269,9 @@ DWARFCallFrameInfo::ParseCIE(const dw_offset_t cie_offset) { cie_sp->ptr_encoding = DW_EH_PE_absptr; // default cie_sp->version = m_cfi_data.GetU8(&offset); if (cie_sp->version > CFI_VERSION4) { - Host::SystemLog(Host::eSystemLogError, - "CIE parse error: CFI version %d is not supported\n", - cie_sp->version); + Debugger::ReportError( + llvm::formatv("CIE parse error: CFI version {0} is not supported", + cie_sp->version)); return nullptr; } @@ -285,10 +288,10 @@ DWARFCallFrameInfo::ParseCIE(const dw_offset_t cie_offset) { if (i == CFI_AUG_MAX_SIZE && cie_sp->augmentation[CFI_AUG_MAX_SIZE - 1] != '\0') { - Host::SystemLog(Host::eSystemLogError, - "CIE parse error: CIE augmentation string was too large " - "for the fixed sized buffer of %d bytes.\n", - CFI_AUG_MAX_SIZE); + Debugger::ReportError(llvm::formatv( + "CIE parse error: CIE augmentation string was too large " + "for the fixed sized buffer of {0} bytes.", + CFI_AUG_MAX_SIZE)); return nullptr; } @@ -396,7 +399,7 @@ DWARFCallFrameInfo::ParseCIE(const dw_offset_t cie_offset) { void DWARFCallFrameInfo::GetCFIData() { if (!m_cfi_data_initialized) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + Log *log = GetLog(LLDBLog::Unwind); if (log) m_objfile.GetModule()->LogMessage(log, "Reading EH frame info"); m_objfile.ReadSectionData(m_section_sp.get(), m_cfi_data); @@ -449,10 +452,9 @@ void DWARFCallFrameInfo::GetFDEIndex() { } if (next_entry > m_cfi_data.GetByteSize() + 1) { - Host::SystemLog(Host::eSystemLogError, "error: Invalid fde/cie next " - "entry offset of 0x%x found in " - "cie/fde at 0x%x\n", - next_entry, current_entry); + Debugger::ReportError(llvm::formatv("Invalid fde/cie next entry offset " + "of {0:x} found in cie/fde at {1:x}", + next_entry, current_entry)); // Don't trust anything in this eh_frame section if we find blatantly // invalid data. m_fde_index.Clear(); @@ -482,10 +484,9 @@ void DWARFCallFrameInfo::GetFDEIndex() { cie_offset = cie_id; if (cie_offset > m_cfi_data.GetByteSize()) { - Host::SystemLog(Host::eSystemLogError, - "error: Invalid cie offset of 0x%x " - "found in cie/fde at 0x%x\n", - cie_offset, current_entry); + Debugger::ReportError(llvm::formatv("Invalid cie offset of {0:x} " + "found in cie/fde at {1:x}", + cie_offset, current_entry)); // Don't trust anything in this eh_frame section if we find blatantly // invalid data. m_fde_index.Clear(); @@ -511,10 +512,9 @@ void DWARFCallFrameInfo::GetFDEIndex() { FDEEntryMap::Entry fde(addr, length, current_entry); m_fde_index.Append(fde); } else { - Host::SystemLog(Host::eSystemLogError, "error: unable to find CIE at " - "0x%8.8x for cie_id = 0x%8.8x for " - "entry at 0x%8.8x.\n", - cie_offset, cie_id, current_entry); + Debugger::ReportError(llvm::formatv( + "unable to find CIE at {0:x} for cie_id = {1:x} for entry at {2:x}.", + cie_offset, cie_id, current_entry)); } offset = next_entry; } @@ -525,7 +525,7 @@ void DWARFCallFrameInfo::GetFDEIndex() { bool DWARFCallFrameInfo::FDEToUnwindPlan(dw_offset_t dwarf_offset, Address startaddr, UnwindPlan &unwind_plan) { - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND); + Log *log = GetLog(LLDBLog::Unwind); lldb::offset_t offset = dwarf_offset; lldb::offset_t current_entry = offset; diff --git a/contrib/llvm-project/lldb/source/Symbol/Function.cpp b/contrib/llvm-project/lldb/source/Symbol/Function.cpp index dda9ec232715..648a12524aed 100644 --- a/contrib/llvm-project/lldb/source/Symbol/Function.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/Function.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "lldb/Symbol/Function.h" +#include "lldb/Core/Debugger.h" #include "lldb/Core/Disassembler.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleList.h" @@ -18,6 +19,7 @@ #include "lldb/Symbol/SymbolFile.h" #include "lldb/Target/Language.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "llvm/Support/Casting.h" @@ -122,7 +124,7 @@ size_t InlineFunctionInfo::MemorySize() const { lldb::addr_t CallEdge::GetLoadAddress(lldb::addr_t unresolved_pc, Function &caller, Target &target) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); const Address &caller_start_addr = caller.GetAddressRange().GetBaseAddress(); @@ -152,7 +154,7 @@ void DirectCallEdge::ParseSymbolFileAndResolve(ModuleList &images) { if (resolved) return; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); LLDB_LOG(log, "DirectCallEdge: Lazily parsing the call graph for {0}", lazy_callee.symbol_name); @@ -191,7 +193,7 @@ Function *DirectCallEdge::GetCallee(ModuleList &images, ExecutionContext &) { Function *IndirectCallEdge::GetCallee(ModuleList &images, ExecutionContext &exe_ctx) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); Status error; Value callee_addr_val; if (!call_target.Evaluate(&exe_ctx, exe_ctx.GetRegisterContext(), @@ -295,7 +297,7 @@ llvm::ArrayRef<std::unique_ptr<CallEdge>> Function::GetCallEdges() { if (m_call_edges_resolved) return m_call_edges; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); LLDB_LOG(log, "GetCallEdges: Attempting to parse call site info for {0}", GetDisplayName()); @@ -347,12 +349,9 @@ Block &Function::GetBlock(bool can_create) { if (module_sp) { module_sp->GetSymbolFile()->ParseBlocksRecursive(*this); } else { - Host::SystemLog(Host::eSystemLogError, - "error: unable to find module " - "shared pointer for function '%s' " - "in %s\n", - GetName().GetCString(), - m_comp_unit->GetPrimaryFile().GetPath().c_str()); + Debugger::ReportError(llvm::formatv( + "unable to find module shared pointer for function '{0}' in {1}", + GetName().GetCString(), m_comp_unit->GetPrimaryFile().GetPath())); } m_block.SetBlockInfoHasBeenParsed(true, true); } diff --git a/contrib/llvm-project/lldb/source/Symbol/LocateSymbolFile.cpp b/contrib/llvm-project/lldb/source/Symbol/LocateSymbolFile.cpp index ba79bf661cd3..1ff532fe3e6c 100644 --- a/contrib/llvm-project/lldb/source/Symbol/LocateSymbolFile.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/LocateSymbolFile.cpp @@ -10,11 +10,13 @@ #include "lldb/Core/ModuleList.h" #include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/Progress.h" #include "lldb/Host/FileSystem.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/DataBuffer.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Reproducer.h" #include "lldb/Utility/StreamString.h" @@ -128,7 +130,8 @@ static bool LookForDsymNextToExecutablePath(const ModuleSpec &mod_spec, if (FileSystem::Instance().Exists(dsym_yaa_fspec)) { ModuleSpec mutable_mod_spec = mod_spec; - if (Symbols::DownloadObjectAndSymbolFile(mutable_mod_spec, true) && + Status error; + if (Symbols::DownloadObjectAndSymbolFile(mutable_mod_spec, error, true) && FileSystem::Instance().Exists(mutable_mod_spec.GetSymbolFileSpec())) { dsym_fspec = mutable_mod_spec.GetSymbolFileSpec(); return true; @@ -152,7 +155,7 @@ static bool LookForDsymNextToExecutablePath(const ModuleSpec &mod_spec, static bool LocateDSYMInVincinityOfExecutable(const ModuleSpec &module_spec, FileSpec &dsym_fspec) { - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + Log *log = GetLog(LLDBLog::Host); const FileSpec &exec_fspec = module_spec.GetFileSpec(); if (exec_fspec) { if (::LookForDsymNextToExecutablePath(module_spec, exec_fspec, @@ -261,6 +264,10 @@ Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec, FileSystem::Instance().Exists(symbol_file_spec)) return symbol_file_spec; + Progress progress(llvm::formatv( + "Locating external symbol file for {0}", + module_spec.GetFileSpec().GetFilename().AsCString("<Unknown>"))); + FileSpecList debug_file_search_paths = default_search_paths; // Add module directory. @@ -355,18 +362,34 @@ Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec, lldb_private::ModuleSpecList specs; const size_t num_specs = ObjectFile::GetModuleSpecifications(file_spec, 0, 0, specs); - assert(num_specs <= 1 && - "Symbol Vendor supports only a single architecture"); - if (num_specs == 1) { - ModuleSpec mspec; - if (specs.GetModuleSpecAtIndex(0, mspec)) { - // Skip the uuids check if module_uuid is invalid. For example, - // this happens for *.dwp files since at the moment llvm-dwp - // doesn't output build ids, nor does binutils dwp. - if (!module_uuid.IsValid() || module_uuid == mspec.GetUUID()) - return file_spec; + ModuleSpec mspec; + bool valid_mspec = false; + if (num_specs == 2) { + // Special case to handle both i386 and i686 from ObjectFilePECOFF + ModuleSpec mspec2; + if (specs.GetModuleSpecAtIndex(0, mspec) && + specs.GetModuleSpecAtIndex(1, mspec2) && + mspec.GetArchitecture().GetTriple().isCompatibleWith( + mspec2.GetArchitecture().GetTriple())) { + valid_mspec = true; } } + if (!valid_mspec) { + assert(num_specs <= 1 && + "Symbol Vendor supports only a single architecture"); + if (num_specs == 1) { + if (specs.GetModuleSpecAtIndex(0, mspec)) { + valid_mspec = true; + } + } + } + if (valid_mspec) { + // Skip the uuids check if module_uuid is invalid. For example, + // this happens for *.dwp files since at the moment llvm-dwp + // doesn't output build ids, nor does binutils dwp. + if (!module_uuid.IsValid() || module_uuid == mspec.GetUUID()) + return file_spec; + } } } } @@ -384,7 +407,7 @@ FileSpec Symbols::FindSymbolFileInBundle(const FileSpec &symfile_bundle, } bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec, - bool force_lookup) { + Status &error, bool force_lookup) { // Fill in the module_spec.GetFileSpec() for the object file and/or the // module_spec.GetSymbolFileSpec() for the debug symbols file. return false; diff --git a/contrib/llvm-project/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp b/contrib/llvm-project/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp index a13b4a7a54f2..4dc42cf01716 100644 --- a/contrib/llvm-project/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp @@ -18,16 +18,18 @@ #include "Host/macosx/cfcpp/CFCData.h" #include "Host/macosx/cfcpp/CFCReleaser.h" #include "Host/macosx/cfcpp/CFCString.h" +#include "lldb/Core/Module.h" #include "lldb/Core/ModuleList.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Host/Host.h" +#include "lldb/Host/HostInfo.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/DataBuffer.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/ReproducerProvider.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timer.h" #include "lldb/Utility/UUID.h" @@ -39,12 +41,14 @@ using namespace lldb; using namespace lldb_private; -static CFURLRef (*g_dlsym_DBGCopyFullDSYMURLForUUID)(CFUUIDRef uuid, CFURLRef exec_url) = nullptr; -static CFDictionaryRef (*g_dlsym_DBGCopyDSYMPropertyLists)(CFURLRef dsym_url) = nullptr; +static CFURLRef (*g_dlsym_DBGCopyFullDSYMURLForUUID)( + CFUUIDRef uuid, CFURLRef exec_url) = nullptr; +static CFDictionaryRef (*g_dlsym_DBGCopyDSYMPropertyLists)(CFURLRef dsym_url) = + nullptr; int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec, ModuleSpec &return_module_spec) { - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + Log *log = GetLog(LLDBLog::Host); if (!ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) { LLDB_LOGF(log, "Spotlight lookup for .dSYM bundles is disabled."); return 0; @@ -57,22 +61,19 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec, const UUID *uuid = module_spec.GetUUIDPtr(); const ArchSpec *arch = module_spec.GetArchitecturePtr(); - if (repro::Loader *l = repro::Reproducer::Instance().GetLoader()) { - static repro::SymbolFileLoader symbol_file_loader(l); - std::pair<FileSpec, FileSpec> paths = symbol_file_loader.GetPaths(uuid); - return_module_spec.GetFileSpec() = paths.first; - return_module_spec.GetSymbolFileSpec() = paths.second; - return 1; - } - int items_found = 0; if (g_dlsym_DBGCopyFullDSYMURLForUUID == nullptr || g_dlsym_DBGCopyDSYMPropertyLists == nullptr) { - void *handle = dlopen ("/System/Library/PrivateFrameworks/DebugSymbols.framework/DebugSymbols", RTLD_LAZY | RTLD_LOCAL); + void *handle = dlopen( + "/System/Library/PrivateFrameworks/DebugSymbols.framework/DebugSymbols", + RTLD_LAZY | RTLD_LOCAL); if (handle) { - g_dlsym_DBGCopyFullDSYMURLForUUID = (CFURLRef (*)(CFUUIDRef, CFURLRef)) dlsym (handle, "DBGCopyFullDSYMURLForUUID"); - g_dlsym_DBGCopyDSYMPropertyLists = (CFDictionaryRef (*)(CFURLRef)) dlsym (handle, "DBGCopyDSYMPropertyLists"); + g_dlsym_DBGCopyFullDSYMURLForUUID = + (CFURLRef(*)(CFUUIDRef, CFURLRef))dlsym(handle, + "DBGCopyFullDSYMURLForUUID"); + g_dlsym_DBGCopyDSYMPropertyLists = (CFDictionaryRef(*)(CFURLRef))dlsym( + handle, "DBGCopyDSYMPropertyLists"); } } @@ -102,19 +103,17 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec, FALSE)); } - CFCReleaser<CFURLRef> dsym_url( - g_dlsym_DBGCopyFullDSYMURLForUUID(module_uuid_ref.get(), exec_url.get())); + CFCReleaser<CFURLRef> dsym_url(g_dlsym_DBGCopyFullDSYMURLForUUID( + module_uuid_ref.get(), exec_url.get())); char path[PATH_MAX]; if (dsym_url.get()) { if (::CFURLGetFileSystemRepresentation( dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) { - if (log) { - LLDB_LOGF(log, - "DebugSymbols framework returned dSYM path of %s for " - "UUID %s -- looking for the dSYM", - path, uuid->GetAsString().c_str()); - } + LLDB_LOGF(log, + "DebugSymbols framework returned dSYM path of %s for " + "UUID %s -- looking for the dSYM", + path, uuid->GetAsString().c_str()); FileSpec dsym_filespec(path); if (path[0] == '~') FileSystem::Instance().Resolve(dsym_filespec); @@ -148,16 +147,54 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec, uuid_dict = static_cast<CFDictionaryRef>( ::CFDictionaryGetValue(dict.get(), uuid_cfstr.get())); } - if (uuid_dict) { + + // Check to see if we have the file on the local filesystem. + if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) { + ModuleSpec exe_spec; + exe_spec.GetFileSpec() = module_spec.GetFileSpec(); + exe_spec.GetUUID() = module_spec.GetUUID(); + ModuleSP module_sp; + module_sp.reset(new Module(exe_spec)); + if (module_sp && module_sp->GetObjectFile() && + module_sp->MatchesModuleSpec(exe_spec)) { + success = true; + return_module_spec.GetFileSpec() = module_spec.GetFileSpec(); + LLDB_LOGF(log, "using original binary filepath %s for UUID %s", + module_spec.GetFileSpec().GetPath().c_str(), + uuid->GetAsString().c_str()); + ++items_found; + } + } + + // Check if the requested image is in our shared cache. + if (!success) { + SharedCacheImageInfo image_info = HostInfo::GetSharedCacheImageInfo( + module_spec.GetFileSpec().GetPath()); + + // If we found it and it has the correct UUID, let's proceed with + // creating a module from the memory contents. + if (image_info.uuid && (!module_spec.GetUUID() || + module_spec.GetUUID() == image_info.uuid)) { + success = true; + return_module_spec.GetFileSpec() = module_spec.GetFileSpec(); + LLDB_LOGF(log, + "using binary from shared cache for filepath %s for " + "UUID %s", + module_spec.GetFileSpec().GetPath().c_str(), + uuid->GetAsString().c_str()); + ++items_found; + } + } + + // Use the DBGSymbolRichExecutable filepath if present + if (!success && uuid_dict) { CFStringRef exec_cf_path = static_cast<CFStringRef>(::CFDictionaryGetValue( uuid_dict, CFSTR("DBGSymbolRichExecutable"))); if (exec_cf_path && ::CFStringGetFileSystemRepresentation( exec_cf_path, path, sizeof(path))) { - if (log) { - LLDB_LOGF(log, "plist bundle has exec path of %s for UUID %s", - path, uuid->GetAsString().c_str()); - } + LLDB_LOGF(log, "plist bundle has exec path of %s for UUID %s", + path, uuid->GetAsString().c_str()); ++items_found; FileSpec exec_filespec(path); if (path[0] == '~') @@ -169,20 +206,17 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec, } } + // Look next to the dSYM for the binary file. if (!success) { - // No dictionary, check near the dSYM bundle for an executable that - // matches... if (::CFURLGetFileSystemRepresentation( dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) { char *dsym_extension_pos = ::strstr(path, ".dSYM"); if (dsym_extension_pos) { *dsym_extension_pos = '\0'; - if (log) { - LLDB_LOGF(log, - "Looking for executable binary next to dSYM " - "bundle with name with name %s", - path); - } + LLDB_LOGF(log, + "Looking for executable binary next to dSYM " + "bundle with name with name %s", + path); FileSpec file_spec(path); FileSystem::Instance().Resolve(file_spec); ModuleSpecList module_specs; @@ -209,12 +243,10 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec, { ++items_found; return_module_spec.GetFileSpec() = bundle_exe_file_spec; - if (log) { - LLDB_LOGF(log, - "Executable binary %s next to dSYM is " - "compatible; using", - path); - } + LLDB_LOGF(log, + "Executable binary %s next to dSYM is " + "compatible; using", + path); } } } @@ -239,12 +271,10 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec, { ++items_found; return_module_spec.GetFileSpec() = file_spec; - if (log) { - LLDB_LOGF(log, - "Executable binary %s next to dSYM is " - "compatible; using", - path); - } + LLDB_LOGF(log, + "Executable binary %s next to dSYM is " + "compatible; using", + path); } break; } @@ -256,12 +286,6 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec, } } - if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) { - g->GetOrCreate<repro::SymbolFileProvider>().AddSymbolFile( - uuid, return_module_spec.GetFileSpec(), - return_module_spec.GetSymbolFileSpec()); - } - return items_found; } @@ -305,25 +329,32 @@ FileSpec Symbols::FindSymbolFileInBundle(const FileSpec &dsym_bundle_fspec, } static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict, - ModuleSpec &module_spec) { - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + ModuleSpec &module_spec, + Status &error) { + Log *log = GetLog(LLDBLog::Host); bool success = false; if (uuid_dict != NULL && CFGetTypeID(uuid_dict) == CFDictionaryGetTypeID()) { std::string str; CFStringRef cf_str; CFDictionaryRef cf_dict; + cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict, + CFSTR("DBGError")); + if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) { + if (CFCString::FileSystemRepresentation(cf_str, str)) { + error.SetErrorString(str); + } + } + cf_str = (CFStringRef)CFDictionaryGetValue( (CFDictionaryRef)uuid_dict, CFSTR("DBGSymbolRichExecutable")); if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) { if (CFCString::FileSystemRepresentation(cf_str, str)) { module_spec.GetFileSpec().SetFile(str.c_str(), FileSpec::Style::native); FileSystem::Instance().Resolve(module_spec.GetFileSpec()); - if (log) { - LLDB_LOGF(log, - "From dsymForUUID plist: Symbol rich executable is at '%s'", - str.c_str()); - } + LLDB_LOGF(log, + "From dsymForUUID plist: Symbol rich executable is at '%s'", + str.c_str()); } } @@ -335,10 +366,7 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict, FileSpec::Style::native); FileSystem::Instance().Resolve(module_spec.GetFileSpec()); success = true; - if (log) { - LLDB_LOGF(log, "From dsymForUUID plist: dSYM is at '%s'", - str.c_str()); - } + LLDB_LOGF(log, "From dsymForUUID plist: dSYM is at '%s'", str.c_str()); } } @@ -464,30 +492,11 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict, } bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec, - bool force_lookup) { + Status &error, bool force_lookup) { bool success = false; const UUID *uuid_ptr = module_spec.GetUUIDPtr(); const FileSpec *file_spec_ptr = module_spec.GetFileSpecPtr(); - if (repro::Loader *l = repro::Reproducer::Instance().GetLoader()) { - static repro::SymbolFileLoader symbol_file_loader(l); - std::pair<FileSpec, FileSpec> paths = symbol_file_loader.GetPaths(uuid_ptr); - if (paths.first) - module_spec.GetFileSpec() = paths.first; - if (paths.second) - module_spec.GetSymbolFileSpec() = paths.second; - return true; - } - - // Lambda to capture the state of module_spec before returning from this - // function. - auto RecordResult = [&]() { - if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) { - g->GetOrCreate<repro::SymbolFileProvider>().AddSymbolFile( - uuid_ptr, module_spec.GetFileSpec(), module_spec.GetSymbolFileSpec()); - } - }; - // It's expensive to check for the DBGShellCommands defaults setting, only do // it once per lldb run and cache the result. static bool g_have_checked_for_dbgshell_command = false; @@ -513,7 +522,6 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec, // When g_dbgshell_command is NULL, the user has not enabled the use of an // external program to find the symbols, don't run it for them. if (!force_lookup && g_dbgshell_command == NULL) { - RecordResult(); return false; } @@ -592,7 +600,7 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec, g_dsym_for_uuid_exe_path, file_path); if (!command.GetString().empty()) { - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + Log *log = GetLog(LLDBLog::Host); int exit_status = -1; int signo = -1; std::string command_output; @@ -604,15 +612,15 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec, LLDB_LOGF(log, "Calling %s with file %s to find dSYM", g_dsym_for_uuid_exe_path, file_path); } - Status error = Host::RunShellCommand( + error = Host::RunShellCommand( command.GetData(), FileSpec(), // current working directory &exit_status, // Exit status &signo, // Signal int * &command_output, // Command output std::chrono::seconds( - 640), // Large timeout to allow for long dsym download times - false); // Don't run in a shell (we don't need shell expansion) + 640), // Large timeout to allow for long dsym download times + false); // Don't run in a shell (we don't need shell expansion) if (error.Success() && exit_status == 0 && !command_output.empty()) { CFCData data(CFDataCreateWithBytesNoCopy( NULL, (const UInt8 *)command_output.data(), command_output.size(), @@ -628,8 +636,8 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec, CFCString uuid_cfstr(uuid_str.c_str()); CFDictionaryRef uuid_dict = (CFDictionaryRef)CFDictionaryGetValue( plist.get(), uuid_cfstr.get()); - success = - GetModuleSpecInfoFromUUIDDictionary(uuid_dict, module_spec); + success = GetModuleSpecInfoFromUUIDDictionary(uuid_dict, + module_spec, error); } else { const CFIndex num_values = ::CFDictionaryGetCount(plist.get()); if (num_values > 0) { @@ -638,19 +646,17 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec, ::CFDictionaryGetKeysAndValues(plist.get(), NULL, (const void **)&values[0]); if (num_values == 1) { - success = GetModuleSpecInfoFromUUIDDictionary(values[0], - module_spec); - RecordResult(); + success = GetModuleSpecInfoFromUUIDDictionary( + values[0], module_spec, error); return success; } else { for (CFIndex i = 0; i < num_values; ++i) { ModuleSpec curr_module_spec; - if (GetModuleSpecInfoFromUUIDDictionary(values[i], - curr_module_spec)) { + if (GetModuleSpecInfoFromUUIDDictionary( + values[i], curr_module_spec, error)) { if (module_spec.GetArchitecture().IsCompatibleMatch( curr_module_spec.GetArchitecture())) { module_spec = curr_module_spec; - RecordResult(); return true; } } @@ -660,18 +666,15 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec, } } } else { - if (log) { - if (!uuid_str.empty()) - LLDB_LOGF(log, "Called %s on %s, no matches", - g_dsym_for_uuid_exe_path, uuid_str.c_str()); - else if (file_path[0] != '\0') - LLDB_LOGF(log, "Called %s on %s, no matches", - g_dsym_for_uuid_exe_path, file_path); - } + if (!uuid_str.empty()) + LLDB_LOGF(log, "Called %s on %s, no matches", + g_dsym_for_uuid_exe_path, uuid_str.c_str()); + else if (file_path[0] != '\0') + LLDB_LOGF(log, "Called %s on %s, no matches", + g_dsym_for_uuid_exe_path, file_path); } } } } - RecordResult(); return success; } diff --git a/contrib/llvm-project/lldb/source/Symbol/ObjectFile.cpp b/contrib/llvm-project/lldb/source/Symbol/ObjectFile.cpp index e7b19f5e0c51..6d4fb22631bc 100644 --- a/contrib/llvm-project/lldb/source/Symbol/ObjectFile.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/ObjectFile.cpp @@ -19,6 +19,7 @@ #include "lldb/Target/Target.h" #include "lldb/Utility/DataBuffer.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Timer.h" #include "lldb/lldb-private.h" @@ -29,11 +30,12 @@ using namespace lldb; using namespace lldb_private; char ObjectFile::ID; +size_t ObjectFile::g_initial_bytes_to_read = 512; static ObjectFileSP CreateObjectFromContainer(const lldb::ModuleSP &module_sp, const FileSpec *file, lldb::offset_t file_offset, lldb::offset_t file_size, - DataBufferSP &data_sp, lldb::offset_t &data_offset) { + DataBufferSP data_sp, lldb::offset_t &data_offset) { ObjectContainerCreateInstance callback; for (uint32_t idx = 0; (callback = PluginManager::GetObjectContainerCreateCallbackAtIndex( @@ -80,8 +82,8 @@ ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file, // container plug-ins can use these bytes to see if they can parse this // file. if (file_size > 0) { - data_sp = FileSystem::Instance().CreateDataBuffer(file->GetPath(), 512, - file_offset); + data_sp = FileSystem::Instance().CreateDataBuffer( + file->GetPath(), g_initial_bytes_to_read, file_offset); data_offset = 0; } } @@ -114,7 +116,7 @@ ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file, // We failed to find any cached object files in the container plug- // ins, so lets read the first 512 bytes and try again below... data_sp = FileSystem::Instance().CreateDataBuffer( - archive_file.GetPath(), 512, file_offset); + archive_file.GetPath(), g_initial_bytes_to_read, file_offset); } } } @@ -150,7 +152,7 @@ ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file, ObjectFileSP ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const ProcessSP &process_sp, lldb::addr_t header_addr, - DataBufferSP &data_sp) { + WritableDataBufferSP data_sp) { ObjectFileSP object_file_sp; if (module_sp) { @@ -188,8 +190,8 @@ size_t ObjectFile::GetModuleSpecifications(const FileSpec &file, ModuleSpecList &specs, DataBufferSP data_sp) { if (!data_sp) - data_sp = FileSystem::Instance().CreateDataBuffer(file.GetPath(), 512, - file_offset); + data_sp = FileSystem::Instance().CreateDataBuffer( + file.GetPath(), g_initial_bytes_to_read, file_offset); if (data_sp) { if (file_size == 0) { const lldb::offset_t actual_file_size = @@ -239,8 +241,7 @@ size_t ObjectFile::GetModuleSpecifications( ObjectFile::ObjectFile(const lldb::ModuleSP &module_sp, const FileSpec *file_spec_ptr, lldb::offset_t file_offset, lldb::offset_t length, - const lldb::DataBufferSP &data_sp, - lldb::offset_t data_offset) + lldb::DataBufferSP data_sp, lldb::offset_t data_offset) : ModuleChild(module_sp), m_file(), // This file could be different from the original module's file m_type(eTypeInvalid), m_strata(eStrataInvalid), @@ -251,7 +252,7 @@ ObjectFile::ObjectFile(const lldb::ModuleSP &module_sp, m_file = *file_spec_ptr; if (data_sp) m_data.SetData(data_sp, data_offset, length); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); + Log *log = GetLog(LLDBLog::Object); LLDB_LOGF(log, "%p ObjectFile::ObjectFile() module = %p (%s), file = %s, " "file_offset = 0x%8.8" PRIx64 ", size = %" PRIu64, @@ -263,14 +264,14 @@ ObjectFile::ObjectFile(const lldb::ModuleSP &module_sp, ObjectFile::ObjectFile(const lldb::ModuleSP &module_sp, const ProcessSP &process_sp, lldb::addr_t header_addr, - DataBufferSP &header_data_sp) + DataBufferSP header_data_sp) : ModuleChild(module_sp), m_file(), m_type(eTypeInvalid), m_strata(eStrataInvalid), m_file_offset(0), m_length(0), m_data(), m_process_wp(process_sp), m_memory_addr(header_addr), m_sections_up(), m_symtab_up(), m_symtab_once_up(new llvm::once_flag()) { if (header_data_sp) m_data.SetData(header_data_sp, 0, header_data_sp->GetByteSize()); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); + Log *log = GetLog(LLDBLog::Object); LLDB_LOGF(log, "%p ObjectFile::ObjectFile() module = %p (%s), process = %p, " "header_addr = 0x%" PRIx64, @@ -280,7 +281,7 @@ ObjectFile::ObjectFile(const lldb::ModuleSP &module_sp, } ObjectFile::~ObjectFile() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); + Log *log = GetLog(LLDBLog::Object); LLDB_LOGF(log, "%p ObjectFile::~ObjectFile ()\n", static_cast<void *>(this)); } @@ -573,7 +574,7 @@ bool ObjectFile::SplitArchivePathWithObject(llvm::StringRef path_with_object, void ObjectFile::ClearSymtab() { ModuleSP module_sp(GetModule()); if (module_sp) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); + Log *log = GetLog(LLDBLog::Object); LLDB_LOGF(log, "%p ObjectFile::ClearSymtab () symtab = %p", static_cast<void *>(this), static_cast<void *>(m_symtab_up.get())); diff --git a/contrib/llvm-project/lldb/source/Symbol/PostfixExpression.cpp b/contrib/llvm-project/lldb/source/Symbol/PostfixExpression.cpp index 588b3f92c3f4..e80e134f29bb 100644 --- a/contrib/llvm-project/lldb/source/Symbol/PostfixExpression.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/PostfixExpression.cpp @@ -18,6 +18,7 @@ using namespace lldb_private; using namespace lldb_private::postfix; +using namespace lldb_private::dwarf; static llvm::Optional<BinaryOpNode::OpType> GetBinaryOpType(llvm::StringRef token) { diff --git a/contrib/llvm-project/lldb/source/Symbol/Symbol.cpp b/contrib/llvm-project/lldb/source/Symbol/Symbol.cpp index 5ee5b0fe2223..9ec7f2638f71 100644 --- a/contrib/llvm-project/lldb/source/Symbol/Symbol.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/Symbol.cpp @@ -31,19 +31,18 @@ Symbol::Symbol() 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, - const lldb::SectionSP §ion_sp, addr_t offset, addr_t size, - bool size_is_valid, bool contains_linker_annotations, - uint32_t flags) - : SymbolContextScope(), m_uid(symID), m_type_data(0), - m_type_data_resolved(false), m_is_synthetic(is_artificial), - m_is_debug(is_debug), m_is_external(external), m_size_is_sibling(false), +Symbol::Symbol(uint32_t symID, llvm::StringRef name, SymbolType type, + bool external, bool is_debug, bool is_trampoline, + bool is_artificial, const lldb::SectionSP §ion_sp, + addr_t offset, addr_t size, bool size_is_valid, + bool contains_linker_annotations, uint32_t flags) + : SymbolContextScope(), m_uid(symID), m_type_data_resolved(false), + m_is_synthetic(is_artificial), m_is_debug(is_debug), + m_is_external(external), m_size_is_sibling(false), m_size_is_synthesized(false), m_size_is_valid(size_is_valid || size > 0), m_demangled_is_synthesized(false), m_contains_linker_annotations(contains_linker_annotations), - m_is_weak(false), m_type(type), - m_mangled(name), + m_is_weak(false), m_type(type), m_mangled(name), m_addr_range(section_sp, offset, size), m_flags(flags) {} Symbol::Symbol(uint32_t symID, const Mangled &mangled, SymbolType type, @@ -51,9 +50,9 @@ Symbol::Symbol(uint32_t symID, const Mangled &mangled, SymbolType type, bool is_artificial, const AddressRange &range, bool size_is_valid, bool contains_linker_annotations, uint32_t flags) - : SymbolContextScope(), m_uid(symID), m_type_data(0), - m_type_data_resolved(false), m_is_synthetic(is_artificial), - m_is_debug(is_debug), m_is_external(external), m_size_is_sibling(false), + : SymbolContextScope(), m_uid(symID), m_type_data_resolved(false), + m_is_synthetic(is_artificial), m_is_debug(is_debug), + m_is_external(external), m_size_is_sibling(false), m_size_is_synthesized(false), m_size_is_valid(size_is_valid || range.GetByteSize() > 0), m_demangled_is_synthesized(false), diff --git a/contrib/llvm-project/lldb/source/Symbol/SymbolContext.cpp b/contrib/llvm-project/lldb/source/Symbol/SymbolContext.cpp index f1c3a9e5b4e0..a10db0755d03 100644 --- a/contrib/llvm-project/lldb/source/Symbol/SymbolContext.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/SymbolContext.cpp @@ -8,6 +8,7 @@ #include "lldb/Symbol/SymbolContext.h" +#include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Host/Host.h" @@ -19,6 +20,7 @@ #include "lldb/Symbol/SymbolVendor.h" #include "lldb/Symbol/Variable.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" @@ -30,7 +32,7 @@ SymbolContext::SymbolContext() : target_sp(), module_sp(), line_entry() {} SymbolContext::SymbolContext(const ModuleSP &m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) : target_sp(), module_sp(m), comp_unit(cu), function(f), block(b), - line_entry(), symbol(s), variable(nullptr) { + line_entry(), symbol(s) { if (le) line_entry = *le; } @@ -39,14 +41,13 @@ SymbolContext::SymbolContext(const TargetSP &t, const ModuleSP &m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) : target_sp(t), module_sp(m), comp_unit(cu), function(f), block(b), - line_entry(), symbol(s), variable(nullptr) { + line_entry(), symbol(s) { if (le) line_entry = *le; } SymbolContext::SymbolContext(SymbolContextScope *sc_scope) - : target_sp(), module_sp(), comp_unit(nullptr), function(nullptr), - block(nullptr), line_entry(), symbol(nullptr), variable(nullptr) { + : target_sp(), module_sp(), line_entry() { sc_scope->CalculateSymbolContext(this); } @@ -477,7 +478,7 @@ bool SymbolContext::GetParentOfInlinedScope(const Address &curr_frame_pc, curr_inlined_block_inlined_info->GetCallSite().GetColumn(); return true; } else { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS)); + Log *log = GetLog(LLDBLog::Symbols); if (log) { LLDB_LOGF( @@ -494,20 +495,16 @@ bool SymbolContext::GetParentOfInlinedScope(const Address &curr_frame_pc, objfile = symbol_file->GetObjectFile(); } if (objfile) { - Host::SystemLog( - Host::eSystemLogWarning, - "warning: inlined block 0x%8.8" PRIx64 - " doesn't have a range that contains file address 0x%" PRIx64 - " in %s\n", + Debugger::ReportWarning(llvm::formatv( + "inlined block {0:x} doesn't have a range that contains file " + "address {1:x} in {2}", curr_inlined_block->GetID(), curr_frame_pc.GetFileAddress(), - objfile->GetFileSpec().GetPath().c_str()); + objfile->GetFileSpec().GetPath())); } else { - Host::SystemLog( - Host::eSystemLogWarning, - "warning: inlined block 0x%8.8" PRIx64 - " doesn't have a range that contains file address 0x%" PRIx64 - "\n", - curr_inlined_block->GetID(), curr_frame_pc.GetFileAddress()); + Debugger::ReportWarning(llvm::formatv( + "inlined block {0:x} doesn't have a range that contains file " + "address {1:x}", + curr_inlined_block->GetID(), curr_frame_pc.GetFileAddress())); } } #endif @@ -960,8 +957,9 @@ bool SymbolContextSpecifier::AddSpecification(const char *spec_string, // See if we can find the Module, if so stick it in the SymbolContext. FileSpec module_file_spec(spec_string); ModuleSpec module_spec(module_file_spec); - lldb::ModuleSP module_sp( - m_target_sp->GetImages().FindFirstModule(module_spec)); + lldb::ModuleSP module_sp = + m_target_sp ? m_target_sp->GetImages().FindFirstModule(module_spec) + : nullptr; m_type |= eModuleSpecified; if (module_sp) m_module_sp = module_sp; diff --git a/contrib/llvm-project/lldb/source/Symbol/SymbolFile.cpp b/contrib/llvm-project/lldb/source/Symbol/SymbolFile.cpp index b85901af4d67..e69150e9a356 100644 --- a/contrib/llvm-project/lldb/source/Symbol/SymbolFile.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/SymbolFile.cpp @@ -12,6 +12,7 @@ #include "lldb/Core/PluginManager.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/SymbolFileOnDemand.h" #include "lldb/Symbol/TypeMap.h" #include "lldb/Symbol/TypeSystem.h" #include "lldb/Symbol/VariableList.h" @@ -25,6 +26,7 @@ using namespace lldb_private; using namespace lldb; char SymbolFile::ID; +char SymbolFileCommon::ID; void SymbolFile::PreloadSymbols() { // No-op for most implementations. @@ -33,9 +35,6 @@ void SymbolFile::PreloadSymbols() { std::recursive_mutex &SymbolFile::GetModuleMutex() const { return GetObjectFile()->GetModule()->GetMutex(); } -ObjectFile *SymbolFile::GetMainObjectFile() { - return m_objfile_sp->GetModule()->GetObjectFile(); -} SymbolFile *SymbolFile::FindPlugin(ObjectFileSP objfile_sp) { std::unique_ptr<SymbolFile> best_symfile_up; @@ -79,6 +78,24 @@ SymbolFile *SymbolFile::FindPlugin(ObjectFileSP objfile_sp) { } } if (best_symfile_up) { + // If symbol on-demand is enabled the winning symbol file parser is + // wrapped with SymbolFileOnDemand so that hydration of the debug info + // can be controlled to improve performance. + // + // Currently the supported on-demand symbol files include: + // executables, shared libraries and debug info files. + // + // To reduce unnecessary wrapping files with zero debug abilities are + // skipped. + ObjectFile::Type obj_file_type = objfile_sp->CalculateType(); + if (ModuleList::GetGlobalModuleListProperties().GetLoadSymbolOnDemand() && + best_symfile_abilities > 0 && + (obj_file_type == ObjectFile::eTypeExecutable || + obj_file_type == ObjectFile::eTypeSharedLibrary || + obj_file_type == ObjectFile::eTypeDebugInfo)) { + best_symfile_up = + std::make_unique<SymbolFileOnDemand>(std::move(best_symfile_up)); + } // Let the winning symbol file parser initialize itself more completely // now that it has been chosen best_symfile_up->InitializeObject(); @@ -87,16 +104,6 @@ SymbolFile *SymbolFile::FindPlugin(ObjectFileSP objfile_sp) { return best_symfile_up.release(); } -llvm::Expected<TypeSystem &> -SymbolFile::GetTypeSystemForLanguage(lldb::LanguageType language) { - auto type_system_or_err = - m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language); - if (type_system_or_err) { - type_system_or_err->SetSymbolFile(this); - } - return type_system_or_err; -} - uint32_t SymbolFile::ResolveSymbolContext(const SourceLocationSpec &src_location_spec, lldb::SymbolContextItem resolve_scope, @@ -154,7 +161,37 @@ void SymbolFile::AssertModuleLock() { #endif } -uint32_t SymbolFile::GetNumCompileUnits() { +SymbolFile::RegisterInfoResolver::~RegisterInfoResolver() = default; + +Symtab *SymbolFileCommon::GetSymtab() { + std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); + if (m_symtab) + return m_symtab; + + // Fetch the symtab from the main object file. + m_symtab = GetMainObjectFile()->GetSymtab(); + + // Then add our symbols to it. + if (m_symtab) + AddSymbols(*m_symtab); + + return m_symtab; +} + +ObjectFile *SymbolFileCommon::GetMainObjectFile() { + return m_objfile_sp->GetModule()->GetObjectFile(); +} + +void SymbolFileCommon::SectionFileAddressesChanged() { + ObjectFile *module_objfile = GetMainObjectFile(); + ObjectFile *symfile_objfile = GetObjectFile(); + if (symfile_objfile != module_objfile) + symfile_objfile->SectionFileAddressesChanged(); + if (m_symtab) + m_symtab->SectionFileAddressesChanged(); +} + +uint32_t SymbolFileCommon::GetNumCompileUnits() { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); if (!m_compile_units) { // Create an array of compile unit shared pointers -- which will each @@ -164,7 +201,7 @@ uint32_t SymbolFile::GetNumCompileUnits() { return m_compile_units->size(); } -CompUnitSP SymbolFile::GetCompileUnitAtIndex(uint32_t idx) { +CompUnitSP SymbolFileCommon::GetCompileUnitAtIndex(uint32_t idx) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); uint32_t num = GetNumCompileUnits(); if (idx >= num) @@ -175,7 +212,8 @@ CompUnitSP SymbolFile::GetCompileUnitAtIndex(uint32_t idx) { return cu_sp; } -void SymbolFile::SetCompileUnitAtIndex(uint32_t idx, const CompUnitSP &cu_sp) { +void SymbolFileCommon::SetCompileUnitAtIndex(uint32_t idx, + const CompUnitSP &cu_sp) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); const size_t num_compile_units = GetNumCompileUnits(); assert(idx < num_compile_units); @@ -190,31 +228,29 @@ void SymbolFile::SetCompileUnitAtIndex(uint32_t idx, const CompUnitSP &cu_sp) { (*m_compile_units)[idx] = cu_sp; } -Symtab *SymbolFile::GetSymtab() { - std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); - if (m_symtab) - return m_symtab; - - // Fetch the symtab from the main object file. - m_symtab = GetMainObjectFile()->GetSymtab(); - - // Then add our symbols to it. - if (m_symtab) - AddSymbols(*m_symtab); - - return m_symtab; +llvm::Expected<TypeSystem &> +SymbolFileCommon::GetTypeSystemForLanguage(lldb::LanguageType language) { + auto type_system_or_err = + m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language); + if (type_system_or_err) { + type_system_or_err->SetSymbolFile(this); + } + return type_system_or_err; } -void SymbolFile::SectionFileAddressesChanged() { - ObjectFile *module_objfile = GetMainObjectFile(); - ObjectFile *symfile_objfile = GetObjectFile(); - if (symfile_objfile != module_objfile) - symfile_objfile->SectionFileAddressesChanged(); - if (m_symtab) - m_symtab->SectionFileAddressesChanged(); +uint64_t SymbolFileCommon::GetDebugInfoSize() { + if (!m_objfile_sp) + return 0; + ModuleSP module_sp(m_objfile_sp->GetModule()); + if (!module_sp) + return 0; + const SectionList *section_list = module_sp->GetSectionList(); + if (section_list) + return section_list->GetDebugInfoSize(); + return 0; } -void SymbolFile::Dump(Stream &s) { +void SymbolFileCommon::Dump(Stream &s) { s.Format("SymbolFile {0} ({1})\n", GetPluginName(), GetMainObjectFile()->GetFileSpec()); s.PutCString("Types:\n"); @@ -234,17 +270,3 @@ void SymbolFile::Dump(Stream &s) { if (Symtab *symtab = GetSymtab()) symtab->Dump(&s, nullptr, eSortOrderNone); } - -SymbolFile::RegisterInfoResolver::~RegisterInfoResolver() = default; - -uint64_t SymbolFile::GetDebugInfoSize() { - if (!m_objfile_sp) - return 0; - ModuleSP module_sp(m_objfile_sp->GetModule()); - if (!module_sp) - return 0; - const SectionList *section_list = module_sp->GetSectionList(); - if (section_list) - return section_list->GetDebugInfoSize(); - return 0; -} diff --git a/contrib/llvm-project/lldb/source/Symbol/SymbolFileOnDemand.cpp b/contrib/llvm-project/lldb/source/Symbol/SymbolFileOnDemand.cpp new file mode 100644 index 000000000000..b97bc5460daf --- /dev/null +++ b/contrib/llvm-project/lldb/source/Symbol/SymbolFileOnDemand.cpp @@ -0,0 +1,590 @@ +//===-- SymbolFileDWARFDebugMap.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/Symbol/SymbolFileOnDemand.h" + +#include "lldb/Core/Module.h" +#include "lldb/Symbol/SymbolFile.h" + +#include <memory> + +using namespace lldb; +using namespace lldb_private; + +char SymbolFileOnDemand::ID; + +SymbolFileOnDemand::SymbolFileOnDemand( + std::unique_ptr<SymbolFile> &&symbol_file) + : m_sym_file_impl(std::move(symbol_file)) {} + +SymbolFileOnDemand::~SymbolFileOnDemand() = default; + +uint32_t SymbolFileOnDemand::CalculateAbilities() { + // Explicitly allow ability checking to pass though. + // This should be a cheap operation. + return m_sym_file_impl->CalculateAbilities(); +} + +std::recursive_mutex &SymbolFileOnDemand::GetModuleMutex() const { + return m_sym_file_impl->GetModuleMutex(); +} + +void SymbolFileOnDemand::InitializeObject() { + if (!m_debug_info_enabled) { + LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(), + __FUNCTION__); + return; + } + return m_sym_file_impl->InitializeObject(); +} + +lldb::LanguageType SymbolFileOnDemand::ParseLanguage(CompileUnit &comp_unit) { + if (!m_debug_info_enabled) { + Log *log = GetLog(); + LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__); + if (log) { + lldb::LanguageType langType = m_sym_file_impl->ParseLanguage(comp_unit); + if (langType != eLanguageTypeUnknown) + LLDB_LOG(log, "Language {0} would return if hydrated.", langType); + } + return eLanguageTypeUnknown; + } + return m_sym_file_impl->ParseLanguage(comp_unit); +} + +XcodeSDK SymbolFileOnDemand::ParseXcodeSDK(CompileUnit &comp_unit) { + if (!m_debug_info_enabled) { + Log *log = GetLog(); + LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__); + XcodeSDK defaultValue{}; + if (log) { + XcodeSDK sdk = m_sym_file_impl->ParseXcodeSDK(comp_unit); + if (!(sdk == defaultValue)) + LLDB_LOG(log, "SDK {0} would return if hydrated.", sdk.GetString()); + } + return defaultValue; + } + return m_sym_file_impl->ParseXcodeSDK(comp_unit); +} + +size_t SymbolFileOnDemand::ParseFunctions(CompileUnit &comp_unit) { + if (!m_debug_info_enabled) { + LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(), + __FUNCTION__); + return 0; + } + return m_sym_file_impl->ParseFunctions(comp_unit); +} + +bool SymbolFileOnDemand::ParseLineTable(CompileUnit &comp_unit) { + if (!m_debug_info_enabled) { + LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(), + __FUNCTION__); + return false; + } + return m_sym_file_impl->ParseLineTable(comp_unit); +} + +bool SymbolFileOnDemand::ParseDebugMacros(CompileUnit &comp_unit) { + if (!m_debug_info_enabled) { + LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(), + __FUNCTION__); + return false; + } + return m_sym_file_impl->ParseDebugMacros(comp_unit); +} + +bool SymbolFileOnDemand::ForEachExternalModule( + CompileUnit &comp_unit, + llvm::DenseSet<lldb_private::SymbolFile *> &visited_symbol_files, + llvm::function_ref<bool(Module &)> lambda) { + if (!m_debug_info_enabled) { + LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(), + __FUNCTION__); + // Return false to not early exit. + return false; + } + return m_sym_file_impl->ForEachExternalModule(comp_unit, visited_symbol_files, + lambda); +} + +bool SymbolFileOnDemand::ParseSupportFiles(CompileUnit &comp_unit, + FileSpecList &support_files) { + LLDB_LOG(GetLog(), + "[{0}] {1} is not skipped: explicitly allowed to support breakpoint", + GetSymbolFileName(), __FUNCTION__); + // Explicitly allow this API through to support source line breakpoint. + return m_sym_file_impl->ParseSupportFiles(comp_unit, support_files); +} + +bool SymbolFileOnDemand::ParseIsOptimized(CompileUnit &comp_unit) { + if (!m_debug_info_enabled) { + Log *log = GetLog(); + LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__); + if (log) { + bool optimized = m_sym_file_impl->ParseIsOptimized(comp_unit); + if (optimized) { + LLDB_LOG(log, "Would return optimized if hydrated."); + } + } + return false; + } + return m_sym_file_impl->ParseIsOptimized(comp_unit); +} + +size_t SymbolFileOnDemand::ParseTypes(CompileUnit &comp_unit) { + if (!m_debug_info_enabled) { + LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(), + __FUNCTION__); + return 0; + } + return m_sym_file_impl->ParseTypes(comp_unit); +} + +bool SymbolFileOnDemand::ParseImportedModules( + const lldb_private::SymbolContext &sc, + std::vector<SourceModule> &imported_modules) { + if (!m_debug_info_enabled) { + Log *log = GetLog(); + LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__); + if (log) { + std::vector<SourceModule> tmp_imported_modules; + bool succeed = + m_sym_file_impl->ParseImportedModules(sc, tmp_imported_modules); + if (succeed) + LLDB_LOG(log, "{0} imported modules would be parsed if hydrated.", + tmp_imported_modules.size()); + } + return false; + } + return m_sym_file_impl->ParseImportedModules(sc, imported_modules); +} + +size_t SymbolFileOnDemand::ParseBlocksRecursive(Function &func) { + if (!m_debug_info_enabled) { + LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(), + __FUNCTION__); + return 0; + } + return m_sym_file_impl->ParseBlocksRecursive(func); +} + +size_t SymbolFileOnDemand::ParseVariablesForContext(const SymbolContext &sc) { + if (!m_debug_info_enabled) { + LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(), + __FUNCTION__); + return 0; + } + return m_sym_file_impl->ParseVariablesForContext(sc); +} + +Type *SymbolFileOnDemand::ResolveTypeUID(lldb::user_id_t type_uid) { + if (!m_debug_info_enabled) { + Log *log = GetLog(); + LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__); + if (log) { + Type *resolved_type = m_sym_file_impl->ResolveTypeUID(type_uid); + if (resolved_type) + LLDB_LOG(log, "Type would be parsed for {0} if hydrated.", type_uid); + } + return nullptr; + } + return m_sym_file_impl->ResolveTypeUID(type_uid); +} + +llvm::Optional<SymbolFile::ArrayInfo> +SymbolFileOnDemand::GetDynamicArrayInfoForUID( + lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) { + if (!m_debug_info_enabled) { + LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(), + __FUNCTION__); + return llvm::None; + } + return m_sym_file_impl->GetDynamicArrayInfoForUID(type_uid, exe_ctx); +} + +bool SymbolFileOnDemand::CompleteType(CompilerType &compiler_type) { + if (!m_debug_info_enabled) { + LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(), + __FUNCTION__); + return false; + } + return m_sym_file_impl->CompleteType(compiler_type); +} + +CompilerDecl SymbolFileOnDemand::GetDeclForUID(lldb::user_id_t type_uid) { + if (!m_debug_info_enabled) { + Log *log = GetLog(); + LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__); + if (log) { + CompilerDecl parsed_decl = m_sym_file_impl->GetDeclForUID(type_uid); + if (parsed_decl != CompilerDecl()) { + LLDB_LOG(log, "CompilerDecl {0} would be parsed for {1} if hydrated.", + parsed_decl.GetName(), type_uid); + } + } + return CompilerDecl(); + } + return m_sym_file_impl->GetDeclForUID(type_uid); +} + +CompilerDeclContext +SymbolFileOnDemand::GetDeclContextForUID(lldb::user_id_t type_uid) { + if (!m_debug_info_enabled) { + LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(), + __FUNCTION__); + return CompilerDeclContext(); + } + return m_sym_file_impl->GetDeclContextForUID(type_uid); +} + +CompilerDeclContext +SymbolFileOnDemand::GetDeclContextContainingUID(lldb::user_id_t type_uid) { + if (!m_debug_info_enabled) { + LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(), + __FUNCTION__); + return CompilerDeclContext(); + } + return m_sym_file_impl->GetDeclContextContainingUID(type_uid); +} + +void SymbolFileOnDemand::ParseDeclsForContext(CompilerDeclContext decl_ctx) { + if (!m_debug_info_enabled) { + LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(), + __FUNCTION__); + return; + } + return m_sym_file_impl->ParseDeclsForContext(decl_ctx); +} + +uint32_t +SymbolFileOnDemand::ResolveSymbolContext(const Address &so_addr, + SymbolContextItem resolve_scope, + SymbolContext &sc) { + if (!m_debug_info_enabled) { + LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(), + __FUNCTION__); + return 0; + } + return m_sym_file_impl->ResolveSymbolContext(so_addr, resolve_scope, sc); +} + +uint32_t SymbolFileOnDemand::ResolveSymbolContext( + const SourceLocationSpec &src_location_spec, + SymbolContextItem resolve_scope, SymbolContextList &sc_list) { + if (!m_debug_info_enabled) { + LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(), + __FUNCTION__); + return 0; + } + return m_sym_file_impl->ResolveSymbolContext(src_location_spec, resolve_scope, + sc_list); +} + +void SymbolFileOnDemand::Dump(lldb_private::Stream &s) { + if (!m_debug_info_enabled) { + LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(), + __FUNCTION__); + return; + } + return m_sym_file_impl->Dump(s); +} + +void SymbolFileOnDemand::DumpClangAST(lldb_private::Stream &s) { + if (!m_debug_info_enabled) { + LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(), + __FUNCTION__); + return; + } + return m_sym_file_impl->DumpClangAST(s); +} + +void SymbolFileOnDemand::FindGlobalVariables(const RegularExpression ®ex, + uint32_t max_matches, + VariableList &variables) { + if (!m_debug_info_enabled) { + LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(), + __FUNCTION__); + return; + } + return m_sym_file_impl->FindGlobalVariables(regex, max_matches, variables); +} + +void SymbolFileOnDemand::FindGlobalVariables( + ConstString name, const CompilerDeclContext &parent_decl_ctx, + uint32_t max_matches, VariableList &variables) { + if (!m_debug_info_enabled) { + Log *log = GetLog(); + Symtab *symtab = GetSymtab(); + if (!symtab) { + LLDB_LOG(log, "[{0}] {1} is skipped - fail to get symtab", + GetSymbolFileName(), __FUNCTION__); + return; + } + Symbol *sym = symtab->FindFirstSymbolWithNameAndType( + name, eSymbolTypeData, Symtab::eDebugAny, Symtab::eVisibilityAny); + if (!sym) { + LLDB_LOG(log, "[{0}] {1} is skipped - fail to find match in symtab", + GetSymbolFileName(), __FUNCTION__); + return; + } + LLDB_LOG(log, "[{0}] {1} is NOT skipped - found match in symtab", + GetSymbolFileName(), __FUNCTION__); + + // Found match in symbol table hydrate debug info and + // allow the FindGlobalVariables to go through. + SetLoadDebugInfoEnabled(); + } + return m_sym_file_impl->FindGlobalVariables(name, parent_decl_ctx, + max_matches, variables); +} + +void SymbolFileOnDemand::FindFunctions(const RegularExpression ®ex, + bool include_inlines, + SymbolContextList &sc_list) { + if (!m_debug_info_enabled) { + Log *log = GetLog(); + Symtab *symtab = GetSymtab(); + if (!symtab) { + LLDB_LOG(log, "[{0}] {1} is skipped - fail to get symtab", + GetSymbolFileName(), __FUNCTION__); + return; + } + std::vector<uint32_t> symbol_indexes; + symtab->AppendSymbolIndexesMatchingRegExAndType( + regex, eSymbolTypeAny, Symtab::eDebugAny, Symtab::eVisibilityAny, + symbol_indexes); + if (symbol_indexes.empty()) { + LLDB_LOG(log, "[{0}] {1} is skipped - fail to find match in symtab", + GetSymbolFileName(), __FUNCTION__); + return; + } + LLDB_LOG(log, "[{0}] {1} is NOT skipped - found match in symtab", + GetSymbolFileName(), __FUNCTION__); + + // Found match in symbol table hydrate debug info and + // allow the FindFucntions to go through. + SetLoadDebugInfoEnabled(); + } + return m_sym_file_impl->FindFunctions(regex, include_inlines, sc_list); +} + +void SymbolFileOnDemand::FindFunctions( + ConstString name, const CompilerDeclContext &parent_decl_ctx, + FunctionNameType name_type_mask, bool include_inlines, + SymbolContextList &sc_list) { + if (!m_debug_info_enabled) { + Log *log = GetLog(); + + Symtab *symtab = GetSymtab(); + if (!symtab) { + LLDB_LOG(log, "[{0}] {1}({2}) is skipped - fail to get symtab", + GetSymbolFileName(), __FUNCTION__, name); + return; + } + + SymbolContextList sc_list_helper; + symtab->FindFunctionSymbols(name, name_type_mask, sc_list_helper); + if (sc_list_helper.GetSize() == 0) { + LLDB_LOG(log, "[{0}] {1}({2}) is skipped - fail to find match in symtab", + GetSymbolFileName(), __FUNCTION__, name); + return; + } + LLDB_LOG(log, "[{0}] {1}({2}) is NOT skipped - found match in symtab", + GetSymbolFileName(), __FUNCTION__, name); + + // Found match in symbol table hydrate debug info and + // allow the FindFucntions to go through. + SetLoadDebugInfoEnabled(); + } + return m_sym_file_impl->FindFunctions(name, parent_decl_ctx, name_type_mask, + include_inlines, sc_list); +} + +void SymbolFileOnDemand::GetMangledNamesForFunction( + const std::string &scope_qualified_name, + std::vector<ConstString> &mangled_names) { + if (!m_debug_info_enabled) { + Log *log = GetLog(); + LLDB_LOG(log, "[{0}] {1}({2}) is skipped", GetSymbolFileName(), + __FUNCTION__, scope_qualified_name); + return; + } + return m_sym_file_impl->GetMangledNamesForFunction(scope_qualified_name, + mangled_names); +} + +void SymbolFileOnDemand::FindTypes( + ConstString name, const CompilerDeclContext &parent_decl_ctx, + uint32_t max_matches, + llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, + TypeMap &types) { + if (!m_debug_info_enabled) { + Log *log = GetLog(); + LLDB_LOG(log, "[{0}] {1}({2}) is skipped", GetSymbolFileName(), + __FUNCTION__, name); + return; + } + return m_sym_file_impl->FindTypes(name, parent_decl_ctx, max_matches, + searched_symbol_files, types); +} + +void SymbolFileOnDemand::FindTypes( + llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages, + llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) { + if (!m_debug_info_enabled) { + LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(), + __FUNCTION__); + return; + } + return m_sym_file_impl->FindTypes(pattern, languages, searched_symbol_files, + types); +} + +void SymbolFileOnDemand::GetTypes(SymbolContextScope *sc_scope, + TypeClass type_mask, TypeList &type_list) { + if (!m_debug_info_enabled) { + LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(), + __FUNCTION__); + return; + } + return m_sym_file_impl->GetTypes(sc_scope, type_mask, type_list); +} + +llvm::Expected<TypeSystem &> +SymbolFileOnDemand::GetTypeSystemForLanguage(LanguageType language) { + if (!m_debug_info_enabled) { + Log *log = GetLog(); + LLDB_LOG(log, "[{0}] {1} is skipped for language type {2}", + GetSymbolFileName(), __FUNCTION__, language); + return llvm::make_error<llvm::StringError>( + "GetTypeSystemForLanguage is skipped by SymbolFileOnDemand", + llvm::inconvertibleErrorCode()); + } + return m_sym_file_impl->GetTypeSystemForLanguage(language); +} + +CompilerDeclContext +SymbolFileOnDemand::FindNamespace(ConstString name, + const CompilerDeclContext &parent_decl_ctx) { + if (!m_debug_info_enabled) { + LLDB_LOG(GetLog(), "[{0}] {1}({2}) is skipped", GetSymbolFileName(), + __FUNCTION__, name); + return SymbolFile::FindNamespace(name, parent_decl_ctx); + } + return m_sym_file_impl->FindNamespace(name, parent_decl_ctx); +} + +std::vector<std::unique_ptr<lldb_private::CallEdge>> +SymbolFileOnDemand::ParseCallEdgesInFunction(UserID func_id) { + if (!m_debug_info_enabled) { + Log *log = GetLog(); + LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__); + if (log) { + std::vector<std::unique_ptr<lldb_private::CallEdge>> call_edges = + m_sym_file_impl->ParseCallEdgesInFunction(func_id); + if (call_edges.size() > 0) { + LLDB_LOG(log, "{0} call edges would be parsed for {1} if hydrated.", + call_edges.size(), func_id.GetID()); + } + } + return {}; + } + return m_sym_file_impl->ParseCallEdgesInFunction(func_id); +} + +lldb::UnwindPlanSP +SymbolFileOnDemand::GetUnwindPlan(const Address &address, + const RegisterInfoResolver &resolver) { + if (!m_debug_info_enabled) { + LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(), + __FUNCTION__); + return nullptr; + } + return m_sym_file_impl->GetUnwindPlan(address, resolver); +} + +llvm::Expected<lldb::addr_t> +SymbolFileOnDemand::GetParameterStackSize(Symbol &symbol) { + if (!m_debug_info_enabled) { + Log *log = GetLog(); + LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__); + if (log) { + llvm::Expected<lldb::addr_t> stack_size = + m_sym_file_impl->GetParameterStackSize(symbol); + if (stack_size) { + LLDB_LOG(log, "{0} stack size would return for symbol {1} if hydrated.", + *stack_size, symbol.GetName()); + } + } + return SymbolFile::GetParameterStackSize(symbol); + } + return m_sym_file_impl->GetParameterStackSize(symbol); +} + +void SymbolFileOnDemand::PreloadSymbols() { + m_preload_symbols = true; + if (!m_debug_info_enabled) { + LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(), + __FUNCTION__); + return; + } + return m_sym_file_impl->PreloadSymbols(); +} + +uint64_t SymbolFileOnDemand::GetDebugInfoSize() { + // Always return the real debug info size. + LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(), + __FUNCTION__); + return m_sym_file_impl->GetDebugInfoSize(); +} + +StatsDuration::Duration SymbolFileOnDemand::GetDebugInfoParseTime() { + // Always return the real parse time. + LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(), + __FUNCTION__); + return m_sym_file_impl->GetDebugInfoParseTime(); +} + +StatsDuration::Duration SymbolFileOnDemand::GetDebugInfoIndexTime() { + // Always return the real index time. + LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(), + __FUNCTION__); + return m_sym_file_impl->GetDebugInfoIndexTime(); +} + +void SymbolFileOnDemand::SetLoadDebugInfoEnabled() { + if (m_debug_info_enabled) + return; + LLDB_LOG(GetLog(), "[{0}] Hydrate debug info", GetSymbolFileName()); + m_debug_info_enabled = true; + InitializeObject(); + if (m_preload_symbols) + PreloadSymbols(); +} + +uint32_t SymbolFileOnDemand::GetNumCompileUnits() { + LLDB_LOG(GetLog(), "[{0}] {1} is not skipped to support breakpoint hydration", + GetSymbolFileName(), __FUNCTION__); + return m_sym_file_impl->GetNumCompileUnits(); +} + +CompUnitSP SymbolFileOnDemand::GetCompileUnitAtIndex(uint32_t idx) { + LLDB_LOG(GetLog(), "[{0}] {1} is not skipped to support breakpoint hydration", + GetSymbolFileName(), __FUNCTION__); + return m_sym_file_impl->GetCompileUnitAtIndex(idx); +} + +uint32_t SymbolFileOnDemand::GetAbilities() { + if (!m_debug_info_enabled) { + LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(), + __FUNCTION__); + return 0; + } + return m_sym_file_impl->GetAbilities(); +} diff --git a/contrib/llvm-project/lldb/source/Symbol/Symtab.cpp b/contrib/llvm-project/lldb/source/Symbol/Symtab.cpp index d148706003ad..eb2447efbad1 100644 --- a/contrib/llvm-project/lldb/source/Symbol/Symtab.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/Symtab.cpp @@ -1204,6 +1204,7 @@ bool DecodeCStrMap(const DataExtractor &data, lldb::offset_t *offset_ptr, if (identifier != kIdentifierCStrMap) return false; const uint32_t count = data.GetU32(offset_ptr); + cstr_map.Reserve(count); for (uint32_t i=0; i<count; ++i) { llvm::StringRef str(strtab.Get(data.GetU32(offset_ptr))); @@ -1213,6 +1214,16 @@ bool DecodeCStrMap(const DataExtractor &data, lldb::offset_t *offset_ptr, return false; cstr_map.Append(ConstString(str), value); } + // We must sort the UniqueCStringMap after decoding it since it is a vector + // of UniqueCStringMap::Entry objects which contain a ConstString and type T. + // ConstString objects are sorted by "const char *" and then type T and + // the "const char *" are point values that will depend on the order in which + // ConstString objects are created and in which of the 256 string pools they + // are created in. So after we decode all of the entries, we must sort the + // name map to ensure name lookups succeed. If we encode and decode within + // the same process we wouldn't need to sort, so unit testing didn't catch + // this issue when first checked in. + cstr_map.Sort(); return true; } diff --git a/contrib/llvm-project/lldb/source/Symbol/Type.cpp b/contrib/llvm-project/lldb/source/Symbol/Type.cpp index d6c82ed1dd80..4ee5a3e76ae4 100644 --- a/contrib/llvm-project/lldb/source/Symbol/Type.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/Type.cpp @@ -11,6 +11,7 @@ #include "lldb/Core/Module.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Scalar.h" #include "lldb/Utility/StreamString.h" @@ -145,7 +146,7 @@ Type::Type(lldb::user_id_t uid, SymbolFile *symbol_file, ConstString name, const Declaration &decl, const CompilerType &compiler_type, ResolveState compiler_type_resolve_state, uint32_t opaque_payload) : std::enable_shared_from_this<Type>(), UserID(uid), m_name(name), - m_symbol_file(symbol_file), m_context(context), m_encoding_type(nullptr), + m_symbol_file(symbol_file), m_context(context), m_encoding_uid(encoding_uid), m_encoding_uid_type(encoding_uid_type), m_decl(decl), m_compiler_type(compiler_type), m_compiler_type_resolve_state(compiler_type ? compiler_type_resolve_state @@ -323,7 +324,7 @@ void Type::DumpValue(ExecutionContext *exe_ctx, Stream *s, exe_ctx, s, format == lldb::eFormatDefault ? GetFormat() : format, data, data_byte_offset, GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr) - .getValueOr(0), + .value_or(0), 0, // Bitfield bit size 0, // Bitfield bit offset show_types, show_summary, verbose, 0); @@ -433,7 +434,7 @@ bool Type::ReadFromMemory(ExecutionContext *exe_ctx, lldb::addr_t addr, const uint64_t byte_size = GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr) - .getValueOr(0); + .value_or(0); if (data.GetByteSize() < byte_size) { lldb::DataBufferSP data_sp(new DataBufferHeap(byte_size, '\0')); data.SetData(data_sp); @@ -535,10 +536,8 @@ bool Type::ResolveCompilerType(ResolveState compiler_type_resolve_state) { auto type_system_or_err = m_symbol_file->GetTypeSystemForLanguage(eLanguageTypeC); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR( - lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), - "Unable to construct void type from TypeSystemClang"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Unable to construct void type from TypeSystemClang"); } else { CompilerType void_compiler_type = type_system_or_err->GetBasicTypeFromAST(eBasicTypeVoid); diff --git a/contrib/llvm-project/lldb/source/Symbol/UnwindPlan.cpp b/contrib/llvm-project/lldb/source/Symbol/UnwindPlan.cpp index 5547998691db..bd4690547c6b 100644 --- a/contrib/llvm-project/lldb/source/Symbol/UnwindPlan.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/UnwindPlan.cpp @@ -13,7 +13,9 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" +#include "llvm/DebugInfo/DIContext.h" #include "llvm/DebugInfo/DWARF/DWARFExpression.h" using namespace lldb; @@ -406,7 +408,7 @@ const UnwindPlan::RowSP UnwindPlan::GetRowAtIndex(uint32_t idx) const { if (idx < m_row_list.size()) return m_row_list[idx]; else { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + Log *log = GetLog(LLDBLog::Unwind); LLDB_LOGF(log, "error: UnwindPlan::GetRowAtIndex(idx = %u) invalid index " "(number rows is %u)", @@ -417,7 +419,7 @@ const UnwindPlan::RowSP UnwindPlan::GetRowAtIndex(uint32_t idx) const { const UnwindPlan::RowSP UnwindPlan::GetLastRow() const { if (m_row_list.empty()) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + Log *log = GetLog(LLDBLog::Unwind); LLDB_LOGF(log, "UnwindPlan::GetLastRow() when rows are empty"); return UnwindPlan::RowSP(); } @@ -434,7 +436,7 @@ void UnwindPlan::SetPlanValidAddressRange(const AddressRange &range) { bool UnwindPlan::PlanValidAtAddress(Address addr) { // If this UnwindPlan has no rows, it is an invalid UnwindPlan. if (GetRowCount() == 0) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + Log *log = GetLog(LLDBLog::Unwind); if (log) { StreamString s; if (addr.Dump(&s, nullptr, Address::DumpStyleSectionNameOffset)) { @@ -457,7 +459,7 @@ bool UnwindPlan::PlanValidAtAddress(Address addr) { if (GetRowAtIndex(0).get() == nullptr || GetRowAtIndex(0)->GetCFAValue().GetValueType() == Row::FAValue::unspecified) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + Log *log = GetLog(LLDBLog::Unwind); if (log) { StreamString s; if (addr.Dump(&s, nullptr, Address::DumpStyleSectionNameOffset)) { diff --git a/contrib/llvm-project/lldb/source/Symbol/Variable.cpp b/contrib/llvm-project/lldb/source/Symbol/Variable.cpp index 89682fc39141..b92c86654496 100644 --- a/contrib/llvm-project/lldb/source/Symbol/Variable.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/Variable.cpp @@ -147,23 +147,13 @@ void Variable::Dump(Stream *s, bool show_context) const { if (m_location.IsValid()) { s->PutCString(", location = "); - lldb::addr_t loclist_base_addr = LLDB_INVALID_ADDRESS; - if (m_location.IsLocationList()) { - SymbolContext variable_sc; - m_owner_scope->CalculateSymbolContext(&variable_sc); - if (variable_sc.function) - loclist_base_addr = variable_sc.function->GetAddressRange() - .GetBaseAddress() - .GetFileAddress(); - } ABISP abi; if (m_owner_scope) { ModuleSP module_sp(m_owner_scope->CalculateSymbolContextModule()); if (module_sp) abi = ABI::FindPlugin(ProcessSP(), module_sp->GetArchitecture()); } - m_location.GetDescription(s, lldb::eDescriptionLevelBrief, - loclist_base_addr, abi.get()); + m_location.GetDescription(s, lldb::eDescriptionLevelBrief, abi.get()); } if (m_external) @@ -253,6 +243,14 @@ bool Variable::LocationIsValidForAddress(const Address &address) { // Be sure to resolve the address to section offset prior to calling this // function. if (address.IsSectionOffset()) { + // We need to check if the address is valid for both scope range and value + // range. + // Empty scope range means block range. + bool valid_in_scope_range = + GetScopeRange().IsEmpty() || GetScopeRange().FindEntryThatContains( + address.GetFileAddress()) != nullptr; + if (!valid_in_scope_range) + return false; SymbolContext sc; CalculateSymbolContext(&sc); if (sc.module_sp == address.GetModule()) { @@ -445,36 +443,25 @@ Status Variable::GetValuesForVariableExpressionPath( return error; } -bool Variable::DumpLocationForAddress(Stream *s, const Address &address) { - // Be sure to resolve the address to section offset prior to calling this - // function. - if (address.IsSectionOffset()) { - SymbolContext sc; - CalculateSymbolContext(&sc); - if (sc.module_sp == address.GetModule()) { - ABISP abi; - if (m_owner_scope) { - ModuleSP module_sp(m_owner_scope->CalculateSymbolContextModule()); - if (module_sp) - abi = ABI::FindPlugin(ProcessSP(), module_sp->GetArchitecture()); - } +bool Variable::DumpLocations(Stream *s, const Address &address) { + SymbolContext sc; + CalculateSymbolContext(&sc); + ABISP abi; + if (m_owner_scope) { + ModuleSP module_sp(m_owner_scope->CalculateSymbolContextModule()); + if (module_sp) + abi = ABI::FindPlugin(ProcessSP(), module_sp->GetArchitecture()); + } - const addr_t file_addr = address.GetFileAddress(); - if (sc.function) { - if (sc.function->GetAddressRange().ContainsFileAddress(address)) { - addr_t loclist_base_file_addr = - sc.function->GetAddressRange().GetBaseAddress().GetFileAddress(); - if (loclist_base_file_addr == LLDB_INVALID_ADDRESS) - return false; - return m_location.DumpLocationForAddress(s, eDescriptionLevelBrief, - loclist_base_file_addr, - file_addr, abi.get()); - } - } - return m_location.DumpLocationForAddress(s, eDescriptionLevelBrief, - LLDB_INVALID_ADDRESS, file_addr, - abi.get()); - } + const addr_t file_addr = address.GetFileAddress(); + if (sc.function) { + addr_t loclist_base_file_addr = + sc.function->GetAddressRange().GetBaseAddress().GetFileAddress(); + if (loclist_base_file_addr == LLDB_INVALID_ADDRESS) + return false; + return m_location.DumpLocations(s, eDescriptionLevelBrief, + loclist_base_file_addr, file_addr, + abi.get()); } return false; } diff --git a/contrib/llvm-project/lldb/source/Target/ABI.cpp b/contrib/llvm-project/lldb/source/Target/ABI.cpp index 6e8772cbd142..86bf01180271 100644 --- a/contrib/llvm-project/lldb/source/Target/ABI.cpp +++ b/contrib/llvm-project/lldb/source/Target/ABI.cpp @@ -15,6 +15,7 @@ #include "lldb/Symbol/TypeSystem.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "llvm/MC/TargetRegistry.h" #include <cctype> @@ -203,7 +204,7 @@ std::unique_ptr<llvm::MCRegisterInfo> ABI::MakeMCRegisterInfo(const ArchSpec &ar const llvm::Target *target = llvm::TargetRegistry::lookupTarget(triple, lookup_error); if (!target) { - LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS), + LLDB_LOG(GetLog(LLDBLog::Process), "Failed to create an llvm target for {0}: {1}", triple, lookup_error); return nullptr; diff --git a/contrib/llvm-project/lldb/source/Target/AssertFrameRecognizer.cpp b/contrib/llvm-project/lldb/source/Target/AssertFrameRecognizer.cpp index a2315b6d63c6..5f4682bd5c11 100644 --- a/contrib/llvm-project/lldb/source/Target/AssertFrameRecognizer.cpp +++ b/contrib/llvm-project/lldb/source/Target/AssertFrameRecognizer.cpp @@ -1,3 +1,4 @@ +#include "lldb/Target/AssertFrameRecognizer.h" #include "lldb/Core/Module.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/SymbolContext.h" @@ -5,11 +6,7 @@ #include "lldb/Target/StackFrameList.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" - -#include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" - -#include "lldb/Target/AssertFrameRecognizer.h" +#include "lldb/Utility/LLDBLog.h" using namespace llvm; using namespace lldb; @@ -53,7 +50,7 @@ bool GetAbortLocation(llvm::Triple::OSType os, SymbolLocation &location) { location.symbols_are_regex = true; break; default: - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + Log *log = GetLog(LLDBLog::Unwind); LLDB_LOG(log, "AssertFrameRecognizer::GetAbortLocation Unsupported OS"); return false; } @@ -83,7 +80,7 @@ bool GetAssertLocation(llvm::Triple::OSType os, SymbolLocation &location) { location.symbols.push_back(ConstString("__GI___assert_fail")); break; default: - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + Log *log = GetLog(LLDBLog::Unwind); LLDB_LOG(log, "AssertFrameRecognizer::GetAssertLocation Unsupported OS"); return false; } @@ -151,7 +148,7 @@ AssertFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame_sp) { prev_frame_sp = thread_sp->GetStackFrameAtIndex(frame_index); if (!prev_frame_sp) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + Log *log = GetLog(LLDBLog::Unwind); LLDB_LOG(log, "Abort Recognizer: Hit unwinding bound ({1} frames)!", frames_to_fetch); break; diff --git a/contrib/llvm-project/lldb/source/Target/DynamicRegisterInfo.cpp b/contrib/llvm-project/lldb/source/Target/DynamicRegisterInfo.cpp index 9f894f86aea8..e2962b02ed7f 100644 --- a/contrib/llvm-project/lldb/source/Target/DynamicRegisterInfo.cpp +++ b/contrib/llvm-project/lldb/source/Target/DynamicRegisterInfo.cpp @@ -11,6 +11,7 @@ #include "lldb/DataFormatters/FormatManager.h" #include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/StringExtractor.h" @@ -192,7 +193,7 @@ llvm::Expected<uint32_t> DynamicRegisterInfo::ByteOffsetFromRegInfoDict( size_t DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict, const ArchSpec &arch) { - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT); + Log *log = GetLog(LLDBLog::Object); assert(!m_finalized); StructuredData::Array *sets = nullptr; if (dict.GetValueForKeyAsArray("sets", sets)) { diff --git a/contrib/llvm-project/lldb/source/Target/ExecutionContext.cpp b/contrib/llvm-project/lldb/source/Target/ExecutionContext.cpp index b5cf13582af1..a5288b81cd17 100644 --- a/contrib/llvm-project/lldb/source/Target/ExecutionContext.cpp +++ b/contrib/llvm-project/lldb/source/Target/ExecutionContext.cpp @@ -19,9 +19,7 @@ using namespace lldb_private; ExecutionContext::ExecutionContext() : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {} -ExecutionContext::ExecutionContext(const ExecutionContext &rhs) - : m_target_sp(rhs.m_target_sp), m_process_sp(rhs.m_process_sp), - m_thread_sp(rhs.m_thread_sp), m_frame_sp(rhs.m_frame_sp) {} +ExecutionContext::ExecutionContext(const ExecutionContext &rhs) = default; ExecutionContext::ExecutionContext(const lldb::TargetSP &target_sp, bool get_process) @@ -398,28 +396,24 @@ ExecutionContextRef::ExecutionContextRef() : 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(), - m_tid(LLDB_INVALID_THREAD_ID), m_stack_id() { + : m_target_wp(), m_process_wp(), m_thread_wp(), m_stack_id() { if (exe_ctx) *this = *exe_ctx; } ExecutionContextRef::ExecutionContextRef(const ExecutionContext &exe_ctx) - : 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() { *this = exe_ctx; } ExecutionContextRef::ExecutionContextRef(Target *target, bool adopt_selected) - : 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() { SetTargetPtr(target, adopt_selected); } ExecutionContextRef::ExecutionContextRef(const ExecutionContextRef &rhs) - : m_target_wp(rhs.m_target_wp), m_process_wp(rhs.m_process_wp), - m_thread_wp(rhs.m_thread_wp), m_tid(rhs.m_tid), - m_stack_id(rhs.m_stack_id) {} + + = default; ExecutionContextRef &ExecutionContextRef:: operator=(const ExecutionContextRef &rhs) { diff --git a/contrib/llvm-project/lldb/source/Target/Language.cpp b/contrib/llvm-project/lldb/source/Target/Language.cpp index eee1ff1512d9..6df36aeeb7b7 100644 --- a/contrib/llvm-project/lldb/source/Target/Language.cpp +++ b/contrib/llvm-project/lldb/source/Target/Language.cpp @@ -428,6 +428,14 @@ bool Language::GetFormatterPrefixSuffix(ValueObject &valobj, return false; } +bool Language::DemangledNameContainsPath(llvm::StringRef path, + ConstString demangled) const { + // The base implementation does a simple contains comparision: + if (path.empty()) + return false; + return demangled.GetStringRef().contains(path); +} + DumpValueObjectOptions::DeclPrintingHelper Language::GetDeclPrintingHelper() { return nullptr; } diff --git a/contrib/llvm-project/lldb/source/Target/LanguageRuntime.cpp b/contrib/llvm-project/lldb/source/Target/LanguageRuntime.cpp index be878d69fa00..ce3646c8b05c 100644 --- a/contrib/llvm-project/lldb/source/Target/LanguageRuntime.cpp +++ b/contrib/llvm-project/lldb/source/Target/LanguageRuntime.cpp @@ -104,8 +104,7 @@ public: ExceptionBreakpointResolver(lldb::LanguageType language, bool catch_bp, bool throw_bp) : BreakpointResolver(nullptr, BreakpointResolver::ExceptionResolver), - m_language(language), m_language_runtime(nullptr), m_catch_bp(catch_bp), - m_throw_bp(throw_bp) {} + m_language(language), m_catch_bp(catch_bp), m_throw_bp(throw_bp) {} ~ExceptionBreakpointResolver() override = default; @@ -195,7 +194,7 @@ protected: lldb::BreakpointResolverSP m_actual_resolver_sp; lldb::LanguageType m_language; - LanguageRuntime *m_language_runtime; + LanguageRuntime *m_language_runtime = nullptr; bool m_catch_bp; bool m_throw_bp; }; diff --git a/contrib/llvm-project/lldb/source/Target/Memory.cpp b/contrib/llvm-project/lldb/source/Target/Memory.cpp index 806e92aa4ed5..a07a72f31922 100644 --- a/contrib/llvm-project/lldb/source/Target/Memory.cpp +++ b/contrib/llvm-project/lldb/source/Target/Memory.cpp @@ -9,6 +9,7 @@ #include "lldb/Target/Memory.h" #include "lldb/Target/Process.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RangeMap.h" #include "lldb/Utility/State.h" @@ -265,8 +266,8 @@ lldb::addr_t AllocatedBlock::ReserveBlock(uint32_t size) { // We must return something valid for zero bytes. if (size == 0) size = 1; - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); - + Log *log = GetLog(LLDBLog::Process); + const size_t free_count = m_free_blocks.GetSize(); for (size_t i=0; i<free_count; ++i) { @@ -321,7 +322,7 @@ bool AllocatedBlock::FreeBlock(addr_t addr) { m_reserved_blocks.RemoveEntryAtIndex(entry_idx); success = true; } - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGV(log, "({0}) (addr = {1:x}) => {2}", this, addr, success); return success; } @@ -351,7 +352,7 @@ AllocatedMemoryCache::AllocatePage(uint32_t byte_size, uint32_t permissions, addr_t addr = m_process.DoAllocateMemory(page_byte_size, permissions, error); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); if (log) { LLDB_LOGF(log, "Process::DoAllocateMemory (byte_size = 0x%8.8" PRIx32 @@ -390,7 +391,7 @@ lldb::addr_t AllocatedMemoryCache::AllocateMemory(size_t byte_size, if (block_sp) addr = block_sp->ReserveBlock(byte_size); } - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "AllocatedMemoryCache::AllocateMemory (byte_size = 0x%8.8" PRIx32 ", permissions = %s) => 0x%16.16" PRIx64, @@ -410,7 +411,7 @@ bool AllocatedMemoryCache::DeallocateMemory(lldb::addr_t addr) { break; } } - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "AllocatedMemoryCache::DeallocateMemory (addr = 0x%16.16" PRIx64 ") => %i", diff --git a/contrib/llvm-project/lldb/source/Target/ModuleCache.cpp b/contrib/llvm-project/lldb/source/Target/ModuleCache.cpp index 7143fcd2707c..29bd2b2394b5 100644 --- a/contrib/llvm-project/lldb/source/Target/ModuleCache.cpp +++ b/contrib/llvm-project/lldb/source/Target/ModuleCache.cpp @@ -13,6 +13,7 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Host/File.h" #include "lldb/Host/LockFile.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/FileUtilities.h" @@ -80,7 +81,7 @@ FileSpec GetSymbolFileSpec(const FileSpec &module_file_spec) { void DeleteExistingModule(const FileSpec &root_dir_spec, const FileSpec &sysroot_module_path_spec) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES)); + Log *log = GetLog(LLDBLog::Modules); UUID module_uuid; { auto module_sp = diff --git a/contrib/llvm-project/lldb/source/Target/PathMappingList.cpp b/contrib/llvm-project/lldb/source/Target/PathMappingList.cpp index e49f6213cf27..4ebb175fcd85 100644 --- a/contrib/llvm-project/lldb/source/Target/PathMappingList.cpp +++ b/contrib/llvm-project/lldb/source/Target/PathMappingList.cpp @@ -40,12 +40,10 @@ std::string NormalizePath(llvm::StringRef path) { PathMappingList::PathMappingList() : m_pairs() {} PathMappingList::PathMappingList(ChangedCallback callback, void *callback_baton) - : m_pairs(), m_callback(callback), m_callback_baton(callback_baton), - m_mod_id(0) {} + : m_pairs(), m_callback(callback), m_callback_baton(callback_baton) {} PathMappingList::PathMappingList(const PathMappingList &rhs) - : m_pairs(rhs.m_pairs), m_callback(nullptr), m_callback_baton(nullptr), - m_mod_id(0) {} + : m_pairs(rhs.m_pairs) {} const PathMappingList &PathMappingList::operator=(const PathMappingList &rhs) { if (this != &rhs) { @@ -190,7 +188,7 @@ PathMappingList::RemapPath(llvm::StringRef mapping_path, continue; } FileSpec remapped(it.second.GetStringRef()); - auto orig_style = FileSpec::GuessPathStyle(prefix).getValueOr( + auto orig_style = FileSpec::GuessPathStyle(prefix).value_or( llvm::sys::path::Style::native); AppendPathComponents(remapped, path, orig_style); if (!only_if_exists || FileSystem::Instance().Exists(remapped)) @@ -206,7 +204,7 @@ bool PathMappingList::ReverseRemapPath(const FileSpec &file, FileSpec &fixed) co if (!path_ref.consume_front(it.second.GetStringRef())) continue; auto orig_file = it.first.GetStringRef(); - auto orig_style = FileSpec::GuessPathStyle(orig_file).getValueOr( + auto orig_style = FileSpec::GuessPathStyle(orig_file).value_or( llvm::sys::path::Style::native); fixed.SetFile(orig_file, orig_style); AppendPathComponents(fixed, path_ref, orig_style); diff --git a/contrib/llvm-project/lldb/source/Target/Platform.cpp b/contrib/llvm-project/lldb/source/Target/Platform.cpp index 3c331c8760df..559f7664c72e 100644 --- a/contrib/llvm-project/lldb/source/Target/Platform.cpp +++ b/contrib/llvm-project/lldb/source/Target/Platform.cpp @@ -19,6 +19,7 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/StreamFile.h" +#include "lldb/Host/FileCache.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" @@ -34,9 +35,11 @@ #include "lldb/Target/UnixSignals.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StructuredData.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" @@ -48,8 +51,6 @@ using namespace lldb; using namespace lldb_private; -static uint32_t g_initialize_count = 0; - // Use a singleton function for g_local_platform_sp to avoid init constructors // since LLDB is often part of a shared library static PlatformSP &GetHostPlatformSP() { @@ -134,26 +135,9 @@ void PlatformProperties::SetDefaultModuleCacheDirectory( /// or attaching to processes unless another platform is specified. PlatformSP Platform::GetHostPlatform() { return GetHostPlatformSP(); } -static std::vector<PlatformSP> &GetPlatformList() { - static std::vector<PlatformSP> g_platform_list; - return g_platform_list; -} - -static std::recursive_mutex &GetPlatformListMutex() { - static std::recursive_mutex g_mutex; - return g_mutex; -} - -void Platform::Initialize() { g_initialize_count++; } +void Platform::Initialize() {} -void Platform::Terminate() { - if (g_initialize_count > 0) { - if (--g_initialize_count == 0) { - std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex()); - GetPlatformList().clear(); - } - } -} +void Platform::Terminate() {} PlatformProperties &Platform::GetGlobalPlatformProperties() { static PlatformProperties g_settings; @@ -164,11 +148,6 @@ void Platform::SetHostPlatform(const lldb::PlatformSP &platform_sp) { // The native platform should use its static void Platform::Initialize() // function to register itself as the native platform. GetHostPlatformSP() = platform_sp; - - if (platform_sp) { - std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex()); - GetPlatformList().push_back(platform_sp); - } } Status Platform::GetFileWithUUID(const FileSpec &platform_file, @@ -271,108 +250,15 @@ bool Platform::GetModuleSpec(const FileSpec &module_file_spec, module_spec); } -PlatformSP Platform::Find(ConstString name) { - if (name) { - static ConstString g_host_platform_name("host"); - if (name == g_host_platform_name) - return GetHostPlatform(); - - std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex()); - for (const auto &platform_sp : GetPlatformList()) { - if (platform_sp->GetName() == name) - return platform_sp; - } - } - return PlatformSP(); -} - -PlatformSP Platform::Create(ConstString name, Status &error) { - PlatformCreateInstance create_callback = nullptr; +PlatformSP Platform::Create(llvm::StringRef name) { lldb::PlatformSP platform_sp; - if (name) { - static ConstString g_host_platform_name("host"); - if (name == g_host_platform_name) - return GetHostPlatform(); - - create_callback = PluginManager::GetPlatformCreateCallbackForPluginName( - name.GetStringRef()); - if (create_callback) - platform_sp = create_callback(true, nullptr); - else - error.SetErrorStringWithFormat( - "unable to find a plug-in for the platform named \"%s\"", - name.GetCString()); - } else - error.SetErrorString("invalid platform name"); - - if (platform_sp) { - std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex()); - GetPlatformList().push_back(platform_sp); - } - - return platform_sp; -} - -PlatformSP Platform::Create(const ArchSpec &arch, ArchSpec *platform_arch_ptr, - Status &error) { - lldb::PlatformSP platform_sp; - if (arch.IsValid()) { - // Scope for locker - { - // First try exact arch matches across all platforms already created - std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex()); - for (const auto &platform_sp : GetPlatformList()) { - if (platform_sp->IsCompatibleArchitecture(arch, true, - platform_arch_ptr)) - return platform_sp; - } - - // Next try compatible arch matches across all platforms already created - for (const auto &platform_sp : GetPlatformList()) { - if (platform_sp->IsCompatibleArchitecture(arch, false, - platform_arch_ptr)) - return platform_sp; - } - } + if (name == GetHostPlatformName()) + return GetHostPlatform(); - PlatformCreateInstance create_callback; - // First try exact arch matches across all platform plug-ins - uint32_t idx; - for (idx = 0; (create_callback = - PluginManager::GetPlatformCreateCallbackAtIndex(idx)); - ++idx) { - if (create_callback) { - platform_sp = create_callback(false, &arch); - if (platform_sp && - platform_sp->IsCompatibleArchitecture(arch, true, - platform_arch_ptr)) { - std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex()); - GetPlatformList().push_back(platform_sp); - return platform_sp; - } - } - } - // Next try compatible arch matches across all platform plug-ins - for (idx = 0; (create_callback = - PluginManager::GetPlatformCreateCallbackAtIndex(idx)); - ++idx) { - if (create_callback) { - platform_sp = create_callback(false, &arch); - if (platform_sp && - platform_sp->IsCompatibleArchitecture(arch, false, - platform_arch_ptr)) { - std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex()); - GetPlatformList().push_back(platform_sp); - return platform_sp; - } - } - } - } else - error.SetErrorString("invalid platform name"); - if (platform_arch_ptr) - platform_arch_ptr->Clear(); - platform_sp.reset(); - return platform_sp; + if (PlatformCreateInstance create_callback = + PluginManager::GetPlatformCreateCallbackForPluginName(name)) + return create_callback(true, nullptr); + return nullptr; } ArchSpec Platform::GetAugmentedArchSpec(Platform *platform, llvm::StringRef triple) { @@ -384,14 +270,13 @@ ArchSpec Platform::GetAugmentedArchSpec(Platform *platform, llvm::StringRef trip /// Default Constructor Platform::Platform(bool is_host) : m_is_host(is_host), m_os_version_set_while_connected(false), - m_system_arch_set_while_connected(false), m_sdk_sysroot(), m_sdk_build(), - m_working_dir(), m_remote_url(), m_name(), m_system_arch(), m_mutex(), - m_max_uid_name_len(0), m_max_gid_name_len(0), m_supports_rsync(false), - m_rsync_opts(), m_rsync_prefix(), m_supports_ssh(false), m_ssh_opts(), + m_system_arch_set_while_connected(false), m_max_uid_name_len(0), + m_max_gid_name_len(0), m_supports_rsync(false), m_rsync_opts(), + m_rsync_prefix(), m_supports_ssh(false), m_ssh_opts(), m_ignores_remote_hostname(false), m_trap_handlers(), m_calculated_trap_handlers(false), m_module_cache(std::make_unique<ModuleCache>()) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); + Log *log = GetLog(LLDBLog::Object); LLDB_LOGF(log, "%p Platform::Platform()", static_cast<void *>(this)); } @@ -623,7 +508,7 @@ RecurseCopy_Callback(void *baton, llvm::sys::fs::file_type ft, Status Platform::Install(const FileSpec &src, const FileSpec &dst) { Status error; - Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); + Log *log = GetLog(LLDBLog::Platform); LLDB_LOGF(log, "Platform::Install (src='%s', dst='%s')", src.GetPath().c_str(), dst.GetPath().c_str()); FileSpec fixed_dst(dst); @@ -733,7 +618,7 @@ Status Platform::Install(const FileSpec &src, const FileSpec &dst) { bool Platform::SetWorkingDirectory(const FileSpec &file_spec) { if (IsHost()) { - Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); + Log *log = GetLog(LLDBLog::Platform); LLDB_LOG(log, "{0}", file_spec); if (std::error_code ec = llvm::sys::fs::set_current_path(file_spec.GetPath())) { LLDB_LOG(log, "error: {0}", ec.message()); @@ -786,15 +671,63 @@ Status Platform::SetFilePermissions(const FileSpec &file_spec, } } -ConstString Platform::GetName() { return ConstString(GetPluginName()); } +user_id_t Platform::OpenFile(const FileSpec &file_spec, + File::OpenOptions flags, uint32_t mode, + Status &error) { + if (IsHost()) + return FileCache::GetInstance().OpenFile(file_spec, flags, mode, error); + return UINT64_MAX; +} + +bool Platform::CloseFile(user_id_t fd, Status &error) { + if (IsHost()) + return FileCache::GetInstance().CloseFile(fd, error); + return false; +} + +user_id_t Platform::GetFileSize(const FileSpec &file_spec) { + if (!IsHost()) + return UINT64_MAX; + + uint64_t Size; + if (llvm::sys::fs::file_size(file_spec.GetPath(), Size)) + return 0; + return Size; +} + +uint64_t Platform::ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst, + uint64_t dst_len, Status &error) { + if (IsHost()) + return FileCache::GetInstance().ReadFile(fd, offset, dst, dst_len, error); + error.SetErrorStringWithFormatv( + "Platform::ReadFile() is not supported in the {0} platform", + GetPluginName()); + return -1; +} + +uint64_t Platform::WriteFile(lldb::user_id_t fd, uint64_t offset, + const void *src, uint64_t src_len, Status &error) { + if (IsHost()) + return FileCache::GetInstance().WriteFile(fd, offset, src, src_len, error); + error.SetErrorStringWithFormatv( + "Platform::WriteFile() is not supported in the {0} platform", + GetPluginName()); + return -1; +} + +UserIDResolver &Platform::GetUserIDResolver() { + if (IsHost()) + return HostInfo::GetUserIDResolver(); + return UserIDResolver::GetNoopResolver(); +} const char *Platform::GetHostname() { if (IsHost()) return "127.0.0.1"; - if (m_name.empty()) + if (m_hostname.empty()) return nullptr; - return m_name.c_str(); + return m_hostname.c_str(); } ConstString Platform::GetFullNameForDylib(ConstString basename) { @@ -802,7 +735,7 @@ ConstString Platform::GetFullNameForDylib(ConstString basename) { } bool Platform::SetRemoteWorkingDirectory(const FileSpec &working_dir) { - Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); + Log *log = GetLog(LLDBLog::Platform); LLDB_LOGF(log, "Platform::SetRemoteWorkingDirectory('%s')", working_dir.GetCString()); m_working_dir = working_dir; @@ -847,7 +780,9 @@ Platform::ResolveExecutable(const ModuleSpec &module_spec, // architectures that we should be using (in the correct order) and see // if we can find a match that way ModuleSpec arch_module_spec(module_spec); - for (const ArchSpec &arch : GetSupportedArchitectures()) { + ArchSpec process_host_arch; + for (const ArchSpec &arch : + GetSupportedArchitectures(process_host_arch)) { arch_module_spec.GetArchitecture() = arch; error = ModuleList::GetSharedModule(arch_module_spec, exe_module_sp, module_search_paths_ptr, nullptr, @@ -894,7 +829,8 @@ Platform::ResolveRemoteExecutable(const ModuleSpec &module_spec, // correct order) and see if we can find a match that way StreamString arch_names; llvm::ListSeparator LS; - for (const ArchSpec &arch : GetSupportedArchitectures()) { + ArchSpec process_host_arch; + for (const ArchSpec &arch : GetSupportedArchitectures(process_host_arch)) { resolved_module_spec.GetArchitecture() = arch; error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, module_search_paths_ptr, nullptr, @@ -992,7 +928,7 @@ ArchSpec Platform::GetAugmentedArchSpec(llvm::StringRef triple) { ArchSpec compatible_arch; ArchSpec raw_arch(triple); - if (!IsCompatibleArchitecture(raw_arch, false, &compatible_arch)) + if (!IsCompatibleArchitecture(raw_arch, {}, false, &compatible_arch)) return raw_arch; if (!compatible_arch.IsValid()) @@ -1056,7 +992,7 @@ uint32_t Platform::FindProcesses(const ProcessInstanceInfoMatch &match_info, Status Platform::LaunchProcess(ProcessLaunchInfo &launch_info) { Status error; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + Log *log = GetLog(LLDBLog::Platform); LLDB_LOGF(log, "Platform::%s()", __FUNCTION__); // Take care of the host case so that each subclass can just call this @@ -1109,7 +1045,7 @@ Status Platform::ShellExpandArguments(ProcessLaunchInfo &launch_info) { } Status Platform::KillProcess(const lldb::pid_t pid) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + Log *log = GetLog(LLDBLog::Platform); LLDB_LOGF(log, "Platform::%s, pid %" PRIu64, __FUNCTION__, pid); if (!IsHost()) { @@ -1123,7 +1059,7 @@ Status Platform::KillProcess(const lldb::pid_t pid) { lldb::ProcessSP Platform::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, Target &target, Status &error) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + Log *log = GetLog(LLDBLog::Platform); LLDB_LOG(log, "target = {0})", &target); ProcessSP process_sp; @@ -1202,16 +1138,6 @@ lldb::ProcessSP Platform::DebugProcess(ProcessLaunchInfo &launch_info, return process_sp; } -lldb::PlatformSP -Platform::GetPlatformForArchitecture(const ArchSpec &arch, - ArchSpec *platform_arch_ptr) { - lldb::PlatformSP platform_sp; - Status error; - if (arch.IsValid()) - platform_sp = Platform::Create(arch, platform_arch_ptr, error); - return platform_sp; -} - std::vector<ArchSpec> Platform::CreateArchList(llvm::ArrayRef<llvm::Triple::ArchType> archs, llvm::Triple::OSType os) { @@ -1228,6 +1154,7 @@ Platform::CreateArchList(llvm::ArrayRef<llvm::Triple::ArchType> archs, /// Lets a platform answer if it is compatible with a given /// architecture and the target triple contained within. bool Platform::IsCompatibleArchitecture(const ArchSpec &arch, + const ArchSpec &process_host_arch, bool exact_arch_match, ArchSpec *compatible_arch_ptr) { // If the architecture is invalid, we must answer true... @@ -1235,7 +1162,8 @@ bool Platform::IsCompatibleArchitecture(const ArchSpec &arch, ArchSpec platform_arch; auto match = exact_arch_match ? &ArchSpec::IsExactMatch : &ArchSpec::IsCompatibleMatch; - for (const ArchSpec &platform_arch : GetSupportedArchitectures()) { + for (const ArchSpec &platform_arch : + GetSupportedArchitectures(process_host_arch)) { if ((arch.*match)(platform_arch)) { if (compatible_arch_ptr) *compatible_arch_ptr = platform_arch; @@ -1250,7 +1178,7 @@ bool Platform::IsCompatibleArchitecture(const ArchSpec &arch, Status Platform::PutFile(const FileSpec &source, const FileSpec &destination, uint32_t uid, uint32_t gid) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + Log *log = GetLog(LLDBLog::Platform); LLDB_LOGF(log, "[PutFile] Using block by block transfer....\n"); auto source_open_options = @@ -1278,7 +1206,7 @@ Status Platform::PutFile(const FileSpec &source, const FileSpec &destination, return error; if (dest_file == UINT64_MAX) return Status("unable to open target file"); - lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024 * 16, 0)); + lldb::WritableDataBufferSP buffer_sp(new DataBufferHeap(1024 * 16, 0)); uint64_t offset = 0; for (;;) { size_t bytes_read = buffer_sp->GetByteSize(); @@ -1317,17 +1245,21 @@ Status Platform::CreateSymlink(const FileSpec &src, // The name of the link is in src const FileSpec &dst) // The symlink points to dst { - Status error("unimplemented"); - return error; + if (IsHost()) + return FileSystem::Instance().Symlink(src, dst); + return Status("unimplemented"); } bool Platform::GetFileExists(const lldb_private::FileSpec &file_spec) { + if (IsHost()) + return FileSystem::Instance().Exists(file_spec); return false; } Status Platform::Unlink(const FileSpec &path) { - Status error("unimplemented"); - return error; + if (IsHost()) + return llvm::sys::fs::remove(path.GetPath()); + return Status("unimplemented"); } MmapArgList Platform::GetMmapArgumentList(const ArchSpec &arch, addr_t addr, @@ -1373,8 +1305,7 @@ lldb_private::Status Platform::RunShellCommand( if (IsHost()) return Host::RunShellCommand(shell, command, working_dir, status_ptr, signo_ptr, command_output, timeout); - else - return Status("unimplemented"); + return Status("unable to run a remote command without a platform"); } bool Platform::CalculateMD5(const FileSpec &file_spec, uint64_t &low, @@ -1533,7 +1464,11 @@ lldb_private::Status OptionGroupPlatformCaching::SetOptionValue( return error; } -Environment Platform::GetEnvironment() { return Environment(); } +Environment Platform::GetEnvironment() { + if (IsHost()) + return Host::GetEnvironment(); + return Environment(); +} const std::vector<ConstString> &Platform::GetTrapHandlerSymbolNames() { if (!m_calculated_trap_handlers) { @@ -1573,8 +1508,10 @@ Status Platform::GetRemoteSharedModule(const ModuleSpec &module_spec, bool *did_create_ptr) { // Get module information from a target. ModuleSpec resolved_module_spec; + ArchSpec process_host_arch; bool got_module_spec = false; if (process) { + process_host_arch = process->GetSystemArchitecture(); // Try to get module information from the process if (process->GetModuleSpec(module_spec.GetFileSpec(), module_spec.GetArchitecture(), @@ -1592,7 +1529,7 @@ Status Platform::GetRemoteSharedModule(const ModuleSpec &module_spec, // architectures that we should be using (in the correct order) and see if // we can find a match that way ModuleSpec arch_module_spec(module_spec); - for (const ArchSpec &arch : GetSupportedArchitectures()) { + for (const ArchSpec &arch : GetSupportedArchitectures(process_host_arch)) { arch_module_spec.GetArchitecture() = arch; error = ModuleList::GetSharedModule(arch_module_spec, module_sp, nullptr, nullptr, nullptr); @@ -1646,7 +1583,7 @@ bool Platform::GetCachedSharedModule(const ModuleSpec &module_spec, !GetGlobalPlatformProperties().GetModuleCacheDirectory()) return false; - Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); + Log *log = GetLog(LLDBLog::Platform); // Check local cache for a module. auto error = m_module_cache->GetAndPut( @@ -1728,7 +1665,7 @@ Status Platform::DownloadSymbolFile(const lldb::ModuleSP &module_sp, FileSpec Platform::GetModuleCacheRoot() { auto dir_spec = GetGlobalPlatformProperties().GetModuleCacheDirectory(); - dir_spec.AppendPathComponent(GetName().AsCString()); + dir_spec.AppendPathComponent(GetPluginName()); return dir_spec; } @@ -2007,3 +1944,133 @@ size_t Platform::GetSoftwareBreakpointTrapOpcode(Target &target, CompilerType Platform::GetSiginfoType(const llvm::Triple& triple) { return CompilerType(); } + +Args Platform::GetExtraStartupCommands() { + return {}; +} + +PlatformSP PlatformList::GetOrCreate(llvm::StringRef name) { + std::lock_guard<std::recursive_mutex> guard(m_mutex); + for (const PlatformSP &platform_sp : m_platforms) { + if (platform_sp->GetName() == name) + return platform_sp; + } + return Create(name); +} + +PlatformSP PlatformList::GetOrCreate(const ArchSpec &arch, + const ArchSpec &process_host_arch, + ArchSpec *platform_arch_ptr, + Status &error) { + std::lock_guard<std::recursive_mutex> guard(m_mutex); + // First try exact arch matches across all platforms already created + for (const auto &platform_sp : m_platforms) { + if (platform_sp->IsCompatibleArchitecture(arch, process_host_arch, true, + platform_arch_ptr)) + return platform_sp; + } + + // Next try compatible arch matches across all platforms already created + for (const auto &platform_sp : m_platforms) { + if (platform_sp->IsCompatibleArchitecture(arch, process_host_arch, false, + platform_arch_ptr)) + return platform_sp; + } + + PlatformCreateInstance create_callback; + // First try exact arch matches across all platform plug-ins + uint32_t idx; + for (idx = 0; + (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex(idx)); + ++idx) { + PlatformSP platform_sp = create_callback(false, &arch); + if (platform_sp && platform_sp->IsCompatibleArchitecture( + arch, process_host_arch, true, platform_arch_ptr)) { + m_platforms.push_back(platform_sp); + return platform_sp; + } + } + // Next try compatible arch matches across all platform plug-ins + for (idx = 0; + (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex(idx)); + ++idx) { + PlatformSP platform_sp = create_callback(false, &arch); + if (platform_sp && platform_sp->IsCompatibleArchitecture( + arch, process_host_arch, false, platform_arch_ptr)) { + m_platforms.push_back(platform_sp); + return platform_sp; + } + } + if (platform_arch_ptr) + platform_arch_ptr->Clear(); + return nullptr; +} + +PlatformSP PlatformList::GetOrCreate(const ArchSpec &arch, + const ArchSpec &process_host_arch, + ArchSpec *platform_arch_ptr) { + Status error; + if (arch.IsValid()) + return GetOrCreate(arch, process_host_arch, platform_arch_ptr, error); + return nullptr; +} + +PlatformSP PlatformList::GetOrCreate(llvm::ArrayRef<ArchSpec> archs, + const ArchSpec &process_host_arch, + std::vector<PlatformSP> &candidates) { + candidates.clear(); + candidates.reserve(archs.size()); + + if (archs.empty()) + return nullptr; + + PlatformSP host_platform_sp = Platform::GetHostPlatform(); + + // Prefer the selected platform if it matches at least one architecture. + if (m_selected_platform_sp) { + for (const ArchSpec &arch : archs) { + if (m_selected_platform_sp->IsCompatibleArchitecture( + arch, process_host_arch, false, nullptr)) + return m_selected_platform_sp; + } + } + + // Prefer the host platform if it matches at least one architecture. + if (host_platform_sp) { + for (const ArchSpec &arch : archs) { + if (host_platform_sp->IsCompatibleArchitecture(arch, process_host_arch, + false, nullptr)) + return host_platform_sp; + } + } + + // Collect a list of candidate platforms for the architectures. + for (const ArchSpec &arch : archs) { + if (PlatformSP platform = GetOrCreate(arch, process_host_arch, nullptr)) + candidates.push_back(platform); + } + + // The selected or host platform didn't match any of the architectures. If + // the same platform supports all architectures then that's the obvious next + // best thing. + if (candidates.size() == archs.size()) { + if (std::all_of(candidates.begin(), candidates.end(), + [&](const PlatformSP &p) -> bool { + return p->GetName() == candidates.front()->GetName(); + })) { + return candidates.front(); + } + } + + // At this point we either have no platforms that match the given + // architectures or multiple platforms with no good way to disambiguate + // between them. + return nullptr; +} + +PlatformSP PlatformList::Create(llvm::StringRef name) { + std::lock_guard<std::recursive_mutex> guard(m_mutex); + PlatformSP platform_sp = Platform::Create(name); + m_platforms.push_back(platform_sp); + return platform_sp; +} diff --git a/contrib/llvm-project/lldb/source/Target/Process.cpp b/contrib/llvm-project/lldb/source/Target/Process.cpp index 6a306ab762da..046706637691 100644 --- a/contrib/llvm-project/lldb/source/Target/Process.cpp +++ b/contrib/llvm-project/lldb/source/Target/Process.cpp @@ -64,6 +64,7 @@ #include "lldb/Target/ThreadPlanStack.h" #include "lldb/Target/UnixSignals.h" #include "lldb/Utility/Event.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/NameMatches.h" #include "lldb/Utility/ProcessInfo.h" @@ -435,11 +436,11 @@ Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp, m_private_run_lock(), m_finalizing(false), m_clear_thread_plans_on_stop(false), m_force_next_event_delivery(false), m_last_broadcast_state(eStateInvalid), m_destroy_in_process(false), - m_can_interpret_function_calls(false), m_warnings_issued(), - m_run_thread_plan_lock(), m_can_jit(eCanJITDontKnow) { + m_can_interpret_function_calls(false), m_run_thread_plan_lock(), + m_can_jit(eCanJITDontKnow) { CheckInWithManager(); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); + Log *log = GetLog(LLDBLog::Object); LLDB_LOGF(log, "%p Process::Process()", static_cast<void *>(this)); if (!m_unix_signals_sp) @@ -489,7 +490,7 @@ Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp, } Process::~Process() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); + Log *log = GetLog(LLDBLog::Object); LLDB_LOGF(log, "%p Process::~Process()", static_cast<void *>(this)); StopPrivateStateThread(); @@ -630,7 +631,7 @@ void Process::SyncIOHandler(uint32_t iohandler_id, auto Result = m_iohandler_sync.WaitForValueNotEqualTo(iohandler_id, timeout); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); if (Result) { LLDB_LOG( log, @@ -657,7 +658,7 @@ StateType Process::WaitForProcessToStop(const Timeout<std::micro> &timeout, if (state == eStateDetached || state == eStateExited) return state; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOG(log, "timeout = {0}", timeout); if (!wait_always && StateIsStoppedState(state, true) && @@ -954,7 +955,7 @@ void Process::RestoreProcessEvents() { RestoreBroadcaster(); } StateType Process::GetStateChangedEvents(EventSP &event_sp, const Timeout<std::micro> &timeout, ListenerSP hijack_listener_sp) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOG(log, "timeout = {0}, event_sp)...", timeout); ListenerSP listener_sp = hijack_listener_sp; @@ -976,7 +977,7 @@ StateType Process::GetStateChangedEvents(EventSP &event_sp, } Event *Process::PeekAtStateChangedEvents() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "Process::%s...", __FUNCTION__); @@ -997,7 +998,7 @@ Event *Process::PeekAtStateChangedEvents() { StateType Process::GetStateChangedEventsPrivate(EventSP &event_sp, const Timeout<std::micro> &timeout) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOG(log, "timeout = {0}, event_sp)...", timeout); StateType state = eStateInvalid; @@ -1016,7 +1017,7 @@ Process::GetStateChangedEventsPrivate(EventSP &event_sp, bool Process::GetEventsPrivate(EventSP &event_sp, const Timeout<std::micro> &timeout, bool control_only) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOG(log, "timeout = {0}, event_sp)...", timeout); if (control_only) @@ -1050,8 +1051,7 @@ bool Process::SetExitStatus(int status, const char *cstr) { // Use a mutex to protect setting the exit status. std::lock_guard<std::mutex> guard(m_exit_status_mutex); - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STATE | - LIBLLDB_LOG_PROCESS)); + Log *log(GetLog(LLDBLog::State | LLDBLog::Process)); LLDB_LOGF( log, "Process::SetExitStatus (status=%i (0x%8.8x), description=%s%s%s)", status, status, cstr ? "\"" : "", cstr ? cstr : "NULL", cstr ? "\"" : ""); @@ -1106,7 +1106,7 @@ bool Process::SetProcessExitStatus( int signo, // Zero for no signal int exit_status // Exit value of process if signal is zero ) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "Process::SetProcessExitStatus (pid=%" PRIu64 ", exited=%i, signal=%i, exit_status=%i)\n", @@ -1307,8 +1307,7 @@ void Process::SetPublicState(StateType new_state, bool restarted) { GetTarget().GetStatistics().SetFirstPublicStopTime(); } - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STATE | - LIBLLDB_LOG_PROCESS)); + Log *log(GetLog(LLDBLog::State | LLDBLog::Process)); LLDB_LOGF(log, "Process::SetPublicState (state = %s, restarted = %i)", StateAsCString(new_state), restarted); const StateType old_state = m_public_state.GetValue(); @@ -1337,8 +1336,7 @@ void Process::SetPublicState(StateType new_state, bool restarted) { } Status Process::Resume() { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STATE | - LIBLLDB_LOG_PROCESS)); + Log *log(GetLog(LLDBLog::State | LLDBLog::Process)); LLDB_LOGF(log, "Process::Resume -- locking run lock"); if (!m_public_run_lock.TrySetRunning()) { Status error("Resume request failed - process still running."); @@ -1356,8 +1354,7 @@ Status Process::Resume() { static const char *g_resume_sync_name = "lldb.Process.ResumeSynchronous.hijack"; Status Process::ResumeSynchronous(Stream *stream) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STATE | - LIBLLDB_LOG_PROCESS)); + Log *log(GetLog(LLDBLog::State | LLDBLog::Process)); LLDB_LOGF(log, "Process::ResumeSynchronous -- locking run lock"); if (!m_public_run_lock.TrySetRunning()) { Status error("Resume request failed - process still running."); @@ -1416,8 +1413,7 @@ void Process::SetPrivateState(StateType new_state) { if (m_finalizing) return; - Log *log(lldb_private::GetLogIfAnyCategoriesSet( - LIBLLDB_LOG_STATE | LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_UNWIND)); + Log *log(GetLog(LLDBLog::State | LLDBLog::Process | LLDBLog::Unwind)); bool state_changed = false; LLDB_LOGF(log, "Process::SetPrivateState (%s)", StateAsCString(new_state)); @@ -1755,7 +1751,7 @@ size_t Process::GetSoftwareBreakpointTrapOpcode(BreakpointSite *bp_site) { Status Process::EnableSoftwareBreakpoint(BreakpointSite *bp_site) { Status error; assert(bp_site != nullptr); - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); const addr_t bp_addr = bp_site->GetLoadAddress(); LLDB_LOGF( log, "Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64, @@ -1831,7 +1827,7 @@ Status Process::EnableSoftwareBreakpoint(BreakpointSite *bp_site) { Status Process::DisableSoftwareBreakpoint(BreakpointSite *bp_site) { Status error; assert(bp_site != nullptr); - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); addr_t bp_addr = bp_site->GetLoadAddress(); lldb::user_id_t breakID = bp_site->GetID(); LLDB_LOGF(log, @@ -1923,6 +1919,9 @@ Status Process::DisableSoftwareBreakpoint(BreakpointSite *bp_site) { //#define VERIFY_MEMORY_READS size_t Process::ReadMemory(addr_t addr, void *buf, size_t size, Status &error) { + if (ABISP abi_sp = GetABI()) + addr = abi_sp->FixAnyAddress(addr); + error.Clear(); if (!GetDisableMemoryCache()) { #if defined(VERIFY_MEMORY_READS) @@ -2035,6 +2034,9 @@ size_t Process::ReadMemoryFromInferior(addr_t addr, void *buf, size_t size, Status &error) { LLDB_SCOPED_TIMER(); + if (ABISP abi_sp = GetABI()) + addr = abi_sp->FixAnyAddress(addr); + if (buf == nullptr || size == 0) return 0; @@ -2117,6 +2119,9 @@ size_t Process::WriteMemoryPrivate(addr_t addr, const void *buf, size_t size, size_t Process::WriteMemory(addr_t addr, const void *buf, size_t size, Status &error) { + if (ABISP abi_sp = GetABI()) + addr = abi_sp->FixAnyAddress(addr); + #if defined(ENABLE_MEMORY_CACHING) m_memory_cache.Flush(addr, size); #endif @@ -2265,7 +2270,7 @@ addr_t Process::AllocateMemory(size_t size, uint32_t permissions, return m_allocated_memory_cache.AllocateMemory(size, permissions, error); #else addr_t allocated_addr = DoAllocateMemory(size, permissions, error); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "Process::AllocateMemory(size=%" PRIu64 ", permissions=%s) => 0x%16.16" PRIx64 @@ -2289,7 +2294,7 @@ addr_t Process::CallocateMemory(size_t size, uint32_t permissions, bool Process::CanJIT() { if (m_can_jit == eCanJITDontKnow) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); Status err; uint64_t allocated_memory = AllocateMemory( @@ -2335,7 +2340,7 @@ Status Process::DeallocateMemory(addr_t ptr) { #else error = DoDeallocateMemory(ptr); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "Process::DeallocateMemory(addr=0x%16.16" PRIx64 ") => err = %s (m_stop_id = %u, m_memory_id = %u)", @@ -2348,7 +2353,7 @@ Status Process::DeallocateMemory(addr_t ptr) { ModuleSP Process::ReadModuleFromMemory(const FileSpec &file_spec, lldb::addr_t header_addr, size_t size_to_read) { - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + Log *log = GetLog(LLDBLog::Host); if (log) { LLDB_LOGF(log, "Process::ReadModuleFromMemory reading %s binary from memory", @@ -2433,6 +2438,39 @@ void Process::LoadOperatingSystemPlugin(bool flush) { } Status Process::Launch(ProcessLaunchInfo &launch_info) { + StateType state_after_launch = eStateInvalid; + EventSP first_stop_event_sp; + Status status = + LaunchPrivate(launch_info, state_after_launch, first_stop_event_sp); + if (status.Fail()) + return status; + + if (state_after_launch != eStateStopped && + state_after_launch != eStateCrashed) + return Status(); + + // Note, the stop event was consumed above, but not handled. This + // was done to give DidLaunch a chance to run. The target is either + // stopped or crashed. Directly set the state. This is done to + // prevent a stop message with a bunch of spurious output on thread + // status, as well as not pop a ProcessIOHandler. + SetPublicState(state_after_launch, false); + + if (PrivateStateThreadIsValid()) + ResumePrivateStateThread(); + else + StartPrivateStateThread(); + + // Target was stopped at entry as was intended. Need to notify the + // listeners about it. + if (launch_info.GetFlags().Test(eLaunchFlagStopAtEntry)) + HandlePrivateEvent(first_stop_event_sp); + + return Status(); +} + +Status Process::LaunchPrivate(ProcessLaunchInfo &launch_info, StateType &state, + EventSP &event_sp) { Status error; m_abi_sp.reset(); m_dyld_up.reset(); @@ -2449,7 +2487,7 @@ Status Process::Launch(ProcessLaunchInfo &launch_info) { // be a way to express this path, without actually having a module. // The way to do that is to set the ExecutableFile in the LaunchInfo. // Figure that out here: - + FileSpec exe_spec_to_use; if (!exe_module) { if (!launch_info.GetExecutableFile()) { @@ -2459,7 +2497,7 @@ Status Process::Launch(ProcessLaunchInfo &launch_info) { exe_spec_to_use = launch_info.GetExecutableFile(); } else exe_spec_to_use = exe_module->GetFileSpec(); - + if (exe_module && FileSystem::Instance().Exists(exe_module->GetFileSpec())) { // Install anything that might need to be installed prior to launching. // For host systems, this will do nothing, but if we are connected to a @@ -2468,6 +2506,7 @@ 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); @@ -2477,93 +2516,88 @@ Status Process::Launch(ProcessLaunchInfo &launch_info) { PausePrivateStateThread(); error = WillLaunch(exe_module); - if (error.Success()) { - const bool restarted = false; - SetPublicState(eStateLaunching, restarted); - m_should_detach = false; + if (error.Fail()) { + std::string local_exec_file_path = exe_spec_to_use.GetPath(); + return Status("file doesn't exist: '%s'", local_exec_file_path.c_str()); + } - if (m_public_run_lock.TrySetRunning()) { - // Now launch using these arguments. - error = DoLaunch(exe_module, launch_info); - } else { - // This shouldn't happen - error.SetErrorString("failed to acquire process run lock"); + const bool restarted = false; + SetPublicState(eStateLaunching, restarted); + m_should_detach = false; + + if (m_public_run_lock.TrySetRunning()) { + // Now launch using these arguments. + error = DoLaunch(exe_module, launch_info); + } else { + // This shouldn't happen + error.SetErrorString("failed to acquire process run lock"); + } + + if (error.Fail()) { + if (GetID() != LLDB_INVALID_PROCESS_ID) { + SetID(LLDB_INVALID_PROCESS_ID); + const char *error_string = error.AsCString(); + if (error_string == nullptr) + error_string = "launch failed"; + SetExitStatus(-1, error_string); } + return error; + } - if (error.Fail()) { - if (GetID() != LLDB_INVALID_PROCESS_ID) { - SetID(LLDB_INVALID_PROCESS_ID); - const char *error_string = error.AsCString(); - if (error_string == nullptr) - error_string = "launch failed"; - SetExitStatus(-1, error_string); - } - } else { - EventSP event_sp; + // Now wait for the process to launch and return control to us, and then + // call DidLaunch: + state = WaitForProcessStopPrivate(event_sp, seconds(10)); - // Now wait for the process to launch and return control to us, and then - // call DidLaunch: - StateType state = WaitForProcessStopPrivate(event_sp, seconds(10)); - - if (state == eStateInvalid || !event_sp) { - // We were able to launch the process, but we failed to catch the - // initial stop. - error.SetErrorString("failed to catch stop after launch"); - SetExitStatus(0, "failed to catch stop after launch"); - Destroy(false); - } else if (state == eStateStopped || state == eStateCrashed) { - DidLaunch(); - - DynamicLoader *dyld = GetDynamicLoader(); - if (dyld) - dyld->DidLaunch(); - - GetJITLoaders().DidLaunch(); - - SystemRuntime *system_runtime = GetSystemRuntime(); - if (system_runtime) - system_runtime->DidLaunch(); - - if (!m_os_up) - LoadOperatingSystemPlugin(false); - - // We successfully launched the process and stopped, now it the - // right time to set up signal filters before resuming. - UpdateAutomaticSignalFiltering(); - - // Note, the stop event was consumed above, but not handled. This - // was done to give DidLaunch a chance to run. The target is either - // stopped or crashed. Directly set the state. This is done to - // prevent a stop message with a bunch of spurious output on thread - // status, as well as not pop a ProcessIOHandler. - // We are done with the launch hijack listener, and this stop should - // go to the public state listener: - RestoreProcessEvents(); - SetPublicState(state, false); - - if (PrivateStateThreadIsValid()) - ResumePrivateStateThread(); - else - StartPrivateStateThread(); - - // Target was stopped at entry as was intended. Need to notify the - // listeners about it. - if (state == eStateStopped && - launch_info.GetFlags().Test(eLaunchFlagStopAtEntry)) - HandlePrivateEvent(event_sp); - } else if (state == eStateExited) { - // We exited while trying to launch somehow. Don't call DidLaunch - // as that's not likely to work, and return an invalid pid. - HandlePrivateEvent(event_sp); - } + if (state == eStateInvalid || !event_sp) { + // We were able to launch the process, but we failed to catch the + // initial stop. + error.SetErrorString("failed to catch stop after launch"); + SetExitStatus(0, error.AsCString()); + Destroy(false); + return error; + } + + if (state == eStateExited) { + // We exited while trying to launch somehow. Don't call DidLaunch + // as that's not likely to work, and return an invalid pid. + HandlePrivateEvent(event_sp); + return Status(); + } + + if (state == eStateStopped || state == eStateCrashed) { + DidLaunch(); + + // Now that we know the process type, update its signal responses from the + // ones stored in the Target: + if (m_unix_signals_sp) { + StreamSP warning_strm = GetTarget().GetDebugger().GetAsyncErrorStream(); + GetTarget().UpdateSignalsFromDummy(m_unix_signals_sp, warning_strm); } - } else { - std::string local_exec_file_path = exe_spec_to_use.GetPath(); - error.SetErrorStringWithFormat("file doesn't exist: '%s'", - local_exec_file_path.c_str()); + + DynamicLoader *dyld = GetDynamicLoader(); + if (dyld) + dyld->DidLaunch(); + + GetJITLoaders().DidLaunch(); + + SystemRuntime *system_runtime = GetSystemRuntime(); + if (system_runtime) + system_runtime->DidLaunch(); + + if (!m_os_up) + LoadOperatingSystemPlugin(false); + + // We successfully launched the process and stopped, now it the + // right time to set up signal filters before resuming. + UpdateAutomaticSignalFiltering(); + return Status(); } - return error; + return Status("Unexpected process state after the launch: %s, expected %s, " + "%s, %s or %s", + StateAsCString(state), StateAsCString(eStateInvalid), + StateAsCString(eStateExited), StateAsCString(eStateStopped), + StateAsCString(eStateCrashed)); } Status Process::LoadCore() { @@ -2601,7 +2635,7 @@ Status Process::LoadCore() { WaitForProcessToStop(llvm::None, &event_sp, true, listener_sp); if (!StateIsStoppedState(state, false)) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "Process::Halt() failed to stop, state is: %s", StateAsCString(state)); error.SetErrorString( @@ -2641,7 +2675,7 @@ SystemRuntime *Process::GetSystemRuntime() { Process::AttachCompletionHandler::AttachCompletionHandler(Process *process, uint32_t exec_count) : NextEventAction(process), m_exec_count(exec_count) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF( log, "Process::AttachCompletionHandler::%s process=%p, exec_count=%" PRIu32, @@ -2650,7 +2684,7 @@ Process::AttachCompletionHandler::AttachCompletionHandler(Process *process, Process::NextEventAction::EventActionResult Process::AttachCompletionHandler::PerformAction(lldb::EventSP &event_sp) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); StateType state = ProcessEventData::GetStateFromEvent(event_sp.get()); LLDB_LOGF(log, @@ -2843,8 +2877,7 @@ Status Process::Attach(ProcessAttachInfo &attach_info) { } void Process::CompleteAttach() { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | - LIBLLDB_LOG_TARGET)); + Log *log(GetLog(LLDBLog::Process | LLDBLog::Target)); LLDB_LOGF(log, "Process::%s()", __FUNCTION__); // Let the process subclass figure out at much as it can about the process @@ -2868,21 +2901,22 @@ void Process::CompleteAttach() { // switch architectures. PlatformSP platform_sp(GetTarget().GetPlatform()); assert(platform_sp); + ArchSpec process_host_arch = GetSystemArchitecture(); if (platform_sp) { const ArchSpec &target_arch = GetTarget().GetArchitecture(); if (target_arch.IsValid() && - !platform_sp->IsCompatibleArchitecture(target_arch, false, nullptr)) { + !platform_sp->IsCompatibleArchitecture(target_arch, process_host_arch, + false, nullptr)) { ArchSpec platform_arch; - platform_sp = - platform_sp->GetPlatformForArchitecture(target_arch, &platform_arch); + platform_sp = GetTarget().GetDebugger().GetPlatformList().GetOrCreate( + target_arch, process_host_arch, &platform_arch); if (platform_sp) { GetTarget().SetPlatform(platform_sp); GetTarget().SetArchitecture(platform_arch); - LLDB_LOGF(log, - "Process::%s switching platform to %s and architecture " - "to %s based on info from attach", - __FUNCTION__, platform_sp->GetName().AsCString(""), - platform_arch.GetTriple().getTriple().c_str()); + LLDB_LOG(log, + "switching platform to {0} and architecture to {1} based on " + "info from attach", + platform_sp->GetName(), platform_arch.GetTriple().getTriple()); } } else if (!process_arch.IsValid()) { ProcessInstanceInfo process_info; @@ -2901,6 +2935,12 @@ void Process::CompleteAttach() { } } } + // Now that we know the process type, update its signal responses from the + // ones stored in the Target: + if (m_unix_signals_sp) { + StreamSP warning_strm = GetTarget().GetDebugger().GetAsyncErrorStream(); + GetTarget().UpdateSignalsFromDummy(m_unix_signals_sp, warning_strm); + } // We have completed the attach, now it is time to find the dynamic loader // plug-in @@ -2999,8 +3039,7 @@ Status Process::ConnectRemote(llvm::StringRef remote_url) { } Status Process::PrivateResume() { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | - LIBLLDB_LOG_STEP)); + Log *log(GetLog(LLDBLog::Process | LLDBLog::Step)); LLDB_LOGF(log, "Process::PrivateResume() m_stop_id = %u, public state: %s " "private state: %s", @@ -3104,7 +3143,7 @@ Status Process::StopForDestroyOrDetach(lldb::EventSP &exit_event_sp) { // still need to interrupt. if (m_public_state.GetValue() == eStateRunning || m_private_state.GetValue() == eStateRunning) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "Process::%s() About to stop.", __FUNCTION__); ListenerSP listener_sp( @@ -3311,8 +3350,7 @@ bool Process::ShouldBroadcastEvent(Event *event_ptr) { const StateType state = Process::ProcessEventData::GetStateFromEvent(event_ptr); bool return_value = true; - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EVENTS | - LIBLLDB_LOG_PROCESS)); + Log *log(GetLog(LLDBLog::Events | LLDBLog::Process)); switch (state) { case eStateDetached: @@ -3463,7 +3501,7 @@ bool Process::ShouldBroadcastEvent(Event *event_ptr) { } bool Process::StartPrivateStateThread(bool is_secondary_thread) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS)); + Log *log = GetLog(LLDBLog::Events); bool already_running = PrivateStateThreadIsValid(); LLDB_LOGF(log, "Process::%s()%s ", __FUNCTION__, @@ -3494,15 +3532,15 @@ bool Process::StartPrivateStateThread(bool is_secondary_thread) { "<lldb.process.internal-state(pid=%" PRIu64 ")>", GetID()); } - // Create the private state thread, and start it running. - PrivateStateThreadArgs *args_ptr = - new PrivateStateThreadArgs(this, is_secondary_thread); llvm::Expected<HostThread> private_state_thread = - ThreadLauncher::LaunchThread(thread_name, Process::PrivateStateThread, - (void *)args_ptr, 8 * 1024 * 1024); + ThreadLauncher::LaunchThread( + thread_name, + [this, is_secondary_thread] { + return RunPrivateStateThread(is_secondary_thread); + }, + 8 * 1024 * 1024); if (!private_state_thread) { - LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST), - "failed to launch host thread: {}", + LLDB_LOG(GetLog(LLDBLog::Host), "failed to launch host thread: {}", llvm::toString(private_state_thread.takeError())); return false; } @@ -3525,7 +3563,7 @@ void Process::StopPrivateStateThread() { if (m_private_state_thread.IsJoinable()) ControlPrivateStateThread(eBroadcastInternalStateControlStop); else { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF( log, "Went to stop the private state thread, but it was already invalid."); @@ -3533,7 +3571,7 @@ void Process::StopPrivateStateThread() { } void Process::ControlPrivateStateThread(uint32_t signal) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); assert(signal == eBroadcastInternalStateControlStop || signal == eBroadcastInternalStateControlPause || @@ -3591,7 +3629,7 @@ void Process::SendAsyncInterrupt() { } void Process::HandlePrivateEvent(EventSP &event_sp) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); m_resume_requested = false; const StateType new_state = @@ -3715,18 +3753,10 @@ Status Process::HaltPrivate() { return error; } -thread_result_t Process::PrivateStateThread(void *arg) { - std::unique_ptr<PrivateStateThreadArgs> args_up( - static_cast<PrivateStateThreadArgs *>(arg)); - thread_result_t result = - args_up->process->RunPrivateStateThread(args_up->is_secondary_thread); - return result; -} - thread_result_t Process::RunPrivateStateThread(bool is_secondary_thread) { bool control_only = true; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "Process::%s (arg = %p, pid = %" PRIu64 ") thread starting...", __FUNCTION__, static_cast<void *>(this), GetID()); @@ -3854,8 +3884,7 @@ Process::ProcessEventData::ProcessEventData() : EventData(), m_process_wp() {} Process::ProcessEventData::ProcessEventData(const ProcessSP &process_sp, StateType state) - : EventData(), m_process_wp(), m_state(state), m_restarted(false), - m_update_state(0), m_interrupted(false) { + : EventData(), m_process_wp(), m_state(state) { if (process_sp) m_process_wp = process_sp; } @@ -3926,8 +3955,7 @@ bool Process::ProcessEventData::ShouldStop(Event *event_ptr, for (idx = 0; idx < not_suspended_thread_list.GetSize(); ++idx) { curr_thread_list = process_sp->GetThreadList(); if (curr_thread_list.GetSize() != num_threads) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP | - LIBLLDB_LOG_PROCESS)); + Log *log(GetLog(LLDBLog::Step | LLDBLog::Process)); LLDB_LOGF( log, "Number of threads changed from %u to %u while processing event.", @@ -3938,8 +3966,7 @@ bool Process::ProcessEventData::ShouldStop(Event *event_ptr, lldb::ThreadSP thread_sp = not_suspended_thread_list.GetThreadAtIndex(idx); if (thread_sp->GetIndexID() != thread_index_array[idx]) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP | - LIBLLDB_LOG_PROCESS)); + Log *log(GetLog(LLDBLog::Step | LLDBLog::Process)); LLDB_LOGF(log, "The thread at position %u changed from %u to %u while " "processing event.", @@ -4232,7 +4259,7 @@ size_t Process::GetAsyncProfileData(char *buf, size_t buf_size, Status &error) { std::string &one_profile_data = m_profile_data.front(); size_t bytes_available = one_profile_data.size(); if (bytes_available > 0) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "Process::GetProfileData (buf = %p, size = %" PRIu64 ")", static_cast<void *>(buf), static_cast<uint64_t>(buf_size)); if (bytes_available > buf_size) { @@ -4253,7 +4280,7 @@ size_t Process::GetSTDOUT(char *buf, size_t buf_size, Status &error) { std::lock_guard<std::recursive_mutex> guard(m_stdio_communication_mutex); size_t bytes_available = m_stdout_data.size(); if (bytes_available > 0) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "Process::GetSTDOUT (buf = %p, size = %" PRIu64 ")", static_cast<void *>(buf), static_cast<uint64_t>(buf_size)); if (bytes_available > buf_size) { @@ -4272,7 +4299,7 @@ size_t Process::GetSTDERR(char *buf, size_t buf_size, Status &error) { std::lock_guard<std::recursive_mutex> gaurd(m_stdio_communication_mutex); size_t bytes_available = m_stderr_data.size(); if (bytes_available > 0) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "Process::GetSTDERR (buf = %p, size = %" PRIu64 ")", static_cast<void *>(buf), static_cast<uint64_t>(buf_size)); if (bytes_available > buf_size) { @@ -4306,6 +4333,12 @@ public: ~IOHandlerProcessSTDIO() override = default; + void SetIsRunning(bool running) { + std::lock_guard<std::mutex> guard(m_mutex); + SetIsDone(!running); + m_is_running = running; + } + // Each IOHandler gets to run until it is done. It should read data from the // "in" and place output into "out" and "err and return when done. void Run() override { @@ -4325,49 +4358,52 @@ public: // FD_ZERO, FD_SET are not supported on windows #ifndef _WIN32 const int pipe_read_fd = m_pipe.GetReadFileDescriptor(); - m_is_running = true; - while (!GetIsDone()) { + SetIsRunning(true); + while (true) { + { + std::lock_guard<std::mutex> guard(m_mutex); + if (GetIsDone()) + break; + } + SelectHelper select_helper; select_helper.FDSetRead(read_fd); select_helper.FDSetRead(pipe_read_fd); Status error = select_helper.Select(); - if (error.Fail()) { - SetIsDone(true); - } else { - char ch = 0; - size_t n; - if (select_helper.FDIsSetRead(read_fd)) { - n = 1; - if (m_read_file.Read(&ch, n).Success() && n == 1) { - if (m_write_file.Write(&ch, n).Fail() || n != 1) - SetIsDone(true); - } else - SetIsDone(true); - } - if (select_helper.FDIsSetRead(pipe_read_fd)) { - size_t bytes_read; - // Consume the interrupt byte - Status error = m_pipe.Read(&ch, 1, bytes_read); - if (error.Success()) { - switch (ch) { - case 'q': - SetIsDone(true); - break; - case 'i': - if (StateIsRunningState(m_process->GetState())) - m_process->SendAsyncInterrupt(); - break; - } - } + if (error.Fail()) + break; + + char ch = 0; + size_t n; + if (select_helper.FDIsSetRead(read_fd)) { + n = 1; + if (m_read_file.Read(&ch, n).Success() && n == 1) { + if (m_write_file.Write(&ch, n).Fail() || n != 1) + break; + } else + break; + } + + if (select_helper.FDIsSetRead(pipe_read_fd)) { + size_t bytes_read; + // Consume the interrupt byte + Status error = m_pipe.Read(&ch, 1, bytes_read); + if (error.Success()) { + if (ch == 'q') + break; + if (ch == 'i') + if (StateIsRunningState(m_process->GetState())) + m_process->SendAsyncInterrupt(); } } } - m_is_running = false; + SetIsRunning(false); #endif } void Cancel() override { + std::lock_guard<std::mutex> guard(m_mutex); SetIsDone(true); // Only write to our pipe to cancel if we are in // IOHandlerProcessSTDIO::Run(). We can end up with a python command that @@ -4424,7 +4460,8 @@ protected: NativeFile m_write_file; // Write to this file (usually the primary pty for // getting io to debuggee) Pipe m_pipe; - std::atomic<bool> m_is_running{false}; + std::mutex m_mutex; + bool m_is_running = false; }; void Process::SetSTDIOFileDescriptor(int fd) { @@ -4453,7 +4490,7 @@ bool Process::ProcessIOHandlerIsActive() { bool Process::PushProcessIOHandler() { IOHandlerSP io_handler_sp(m_process_input_reader); if (io_handler_sp) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "Process::%s pushing IO handler", __FUNCTION__); io_handler_sp->SetIsDone(false); @@ -4491,7 +4528,7 @@ namespace { class RestorePlanState { public: RestorePlanState(lldb::ThreadPlanSP thread_plan_sp) - : m_thread_plan_sp(thread_plan_sp), m_already_reset(false) { + : m_thread_plan_sp(thread_plan_sp) { if (m_thread_plan_sp) { m_private = m_thread_plan_sp->GetPrivate(); m_is_controlling = m_thread_plan_sp->IsControllingPlan(); @@ -4512,7 +4549,7 @@ public: private: lldb::ThreadPlanSP m_thread_plan_sp; - bool m_already_reset; + bool m_already_reset = false; bool m_private; bool m_is_controlling; bool m_okay_to_discard; @@ -4562,7 +4599,7 @@ HandleStoppedEvent(lldb::tid_t thread_id, const ThreadPlanSP &thread_plan_sp, EventSP &event_to_broadcast_sp, const EvaluateExpressionOptions &options, bool handle_interrupts) { - Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP | LIBLLDB_LOG_PROCESS); + Log *log = GetLog(LLDBLog::Step | LLDBLog::Process); ThreadSP thread_sp = thread_plan_sp->GetTarget() .GetProcessSP() @@ -4730,8 +4767,7 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx, lldb::StateType old_state = eStateInvalid; lldb::ThreadPlanSP stopper_base_plan_sp; - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP | - LIBLLDB_LOG_PROCESS)); + Log *log(GetLog(LLDBLog::Step | LLDBLog::Process)); if (m_private_state_thread.EqualsThread(Host::GetCurrentThread())) { // Yikes, we are running on the private state thread! So we can't wait for // public events on this thread, since we are the thread that is generating @@ -5498,7 +5534,7 @@ size_t Process::GetThreadStatus(Stream &strm, stop_format); ++num_thread_infos_dumped; } else { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "Process::GetThreadStatus - thread 0x" PRIu64 " vanished while running Thread::GetStatus."); } @@ -5586,7 +5622,7 @@ lldb::addr_t Process::GetDataAddressMask() { } void Process::DidExec() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "Process::%s()", __FUNCTION__); Target &target = GetTarget(); @@ -5683,48 +5719,12 @@ void Process::ModulesDidLoad(ModuleList &module_list) { } } -void Process::PrintWarning(uint64_t warning_type, const void *repeat_key, - const char *fmt, ...) { - bool print_warning = true; - - StreamSP stream_sp = GetTarget().GetDebugger().GetAsyncOutputStream(); - if (!stream_sp) - return; - - if (repeat_key != nullptr) { - WarningsCollection::iterator it = m_warnings_issued.find(warning_type); - if (it == m_warnings_issued.end()) { - m_warnings_issued[warning_type] = WarningsPointerSet(); - m_warnings_issued[warning_type].insert(repeat_key); - } else { - if (it->second.find(repeat_key) != it->second.end()) { - print_warning = false; - } else { - it->second.insert(repeat_key); - } - } - } - - if (print_warning) { - va_list args; - va_start(args, fmt); - stream_sp->PrintfVarArg(fmt, args); - va_end(args); - } -} - void Process::PrintWarningOptimization(const SymbolContext &sc) { if (!GetWarningsOptimization()) return; - if (!sc.module_sp) + if (!sc.module_sp || !sc.function || !sc.function->GetIsOptimized()) return; - if (!sc.module_sp->GetFileSpec().GetFilename().IsEmpty() && sc.function && - sc.function->GetIsOptimized()) { - PrintWarning(Process::Warnings::eWarningsOptimization, sc.module_sp.get(), - "%s was compiled with optimization - stepping may behave " - "oddly; variables may not be available.\n", - sc.module_sp->GetFileSpec().GetFilename().GetCString()); - } + sc.module_sp->ReportWarningOptimization(GetTarget().GetDebugger().GetID()); } void Process::PrintWarningUnsupportedLanguage(const SymbolContext &sc) { @@ -5737,13 +5737,10 @@ void Process::PrintWarningUnsupportedLanguage(const SymbolContext &sc) { return; LanguageSet plugins = PluginManager::GetAllTypeSystemSupportedLanguagesForTypes(); - if (!plugins[language]) { - PrintWarning(Process::Warnings::eWarningsUnsupportedLanguage, - sc.module_sp.get(), - "This version of LLDB has no plugin for the language \"%s\". " - "Inspection of frame variables will be limited.\n", - Language::GetNameForLanguageType(language)); - } + if (plugins[language]) + return; + sc.module_sp->ReportWarningUnsupportedLanguage( + language, GetTarget().GetDebugger().GetID()); } bool Process::GetProcessInfo(ProcessInstanceInfo &info) { @@ -5856,7 +5853,7 @@ Process::AdvanceAddressToNextBranchInstruction(Address default_stop_addr, Status Process::GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &range_info) { if (const lldb::ABISP &abi = GetABI()) - load_addr = abi->FixDataAddress(load_addr); + load_addr = abi->FixAnyAddress(load_addr); return DoGetMemoryRegionInfo(load_addr, range_info); } @@ -5891,7 +5888,7 @@ Status Process::GetMemoryRegions(lldb_private::MemoryRegionInfos ®ion_list) { range_end != LLDB_INVALID_ADDRESS && // If we have non-address bits and some are set then the end // is at or beyond the end of mappable memory. - !(abi && (abi->FixDataAddress(range_end) != range_end))); + !(abi && (abi->FixAnyAddress(range_end) != range_end))); return error; } @@ -5907,7 +5904,7 @@ Process::ConfigureStructuredData(ConstString type_name, void Process::MapSupportedStructuredDataPlugins( const StructuredData::Array &supported_type_names) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); // Bail out early if there are no type names to map. if (supported_type_names.GetSize() == 0) { diff --git a/contrib/llvm-project/lldb/source/Target/ProcessTrace.cpp b/contrib/llvm-project/lldb/source/Target/ProcessTrace.cpp index 41d5b01b61d8..6b147cb285a7 100644 --- a/contrib/llvm-project/lldb/source/Target/ProcessTrace.cpp +++ b/contrib/llvm-project/lldb/source/Target/ProcessTrace.cpp @@ -13,6 +13,7 @@ #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" +#include "lldb/Target/ABI.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" @@ -80,6 +81,9 @@ Status ProcessTrace::DoDestroy() { return Status(); } size_t ProcessTrace::ReadMemory(addr_t addr, void *buf, size_t size, Status &error) { + if (const ABISP &abi = GetABI()) + addr = abi->FixAnyAddress(addr); + // Don't allow the caching that lldb_private::Process::ReadMemory does since // we have it all cached in the trace files. return DoReadMemory(addr, buf, size, error); diff --git a/contrib/llvm-project/lldb/source/Target/RegisterContextUnwind.cpp b/contrib/llvm-project/lldb/source/Target/RegisterContextUnwind.cpp index 315ccea65d1f..e98aed7e1555 100644 --- a/contrib/llvm-project/lldb/source/Target/RegisterContextUnwind.cpp +++ b/contrib/llvm-project/lldb/source/Target/RegisterContextUnwind.cpp @@ -32,10 +32,11 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/VASPrintf.h" #include "lldb/lldb-private.h" - #include <memory> using namespace lldb; @@ -81,14 +82,13 @@ RegisterContextUnwind::RegisterContextUnwind(Thread &thread, } bool RegisterContextUnwind::IsUnwindPlanValidForCurrentPC( - lldb::UnwindPlanSP unwind_plan_sp, int &valid_pc_offset) { + lldb::UnwindPlanSP unwind_plan_sp) { if (!unwind_plan_sp) return false; // check if m_current_pc is valid if (unwind_plan_sp->PlanValidAtAddress(m_current_pc)) { // yes - current offset can be used as is - valid_pc_offset = m_current_offset; return true; } @@ -100,8 +100,6 @@ bool RegisterContextUnwind::IsUnwindPlanValidForCurrentPC( Address pc_minus_one(m_current_pc); pc_minus_one.SetOffset(m_current_pc.GetOffset() - 1); if (unwind_plan_sp->PlanValidAtAddress(pc_minus_one)) { - // *valid_pc_offset = m_current_offset - 1; - valid_pc_offset = m_current_pc.GetOffset() - 1; return true; } @@ -112,7 +110,7 @@ bool RegisterContextUnwind::IsUnwindPlanValidForCurrentPC( // zeroth frame or currently executing frame. void RegisterContextUnwind::InitializeZerothFrame() { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + Log *log = GetLog(LLDBLog::Unwind); ExecutionContext exe_ctx(m_thread.shared_from_this()); RegisterContextSP reg_ctx_sp = m_thread.GetRegisterContext(); @@ -303,7 +301,7 @@ void RegisterContextUnwind::InitializeZerothFrame() { // RegisterContextUnwind "below" it to provide things like its current pc value. void RegisterContextUnwind::InitializeNonZerothFrame() { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + Log *log = GetLog(LLDBLog::Unwind); if (IsFrameZero()) { m_frame_type = eNotAValidFrame; UnwindLogMsg("non-zeroth frame tests positive for IsFrameZero -- that " @@ -513,9 +511,12 @@ void RegisterContextUnwind::InitializeNonZerothFrame() { } else if (!addr_range.GetBaseAddress().IsValid() || addr_range.GetBaseAddress().GetSection() != m_current_pc.GetSection() || addr_range.GetBaseAddress().GetOffset() != m_current_pc.GetOffset()) { - // If our "current" pc isn't the start of a function, no need - // to decrement and recompute. - decr_pc_and_recompute_addr_range = false; + // If our "current" pc isn't the start of a function, decrement the pc + // if we're up the stack. + if (m_behaves_like_zeroth_frame) + decr_pc_and_recompute_addr_range = false; + else + decr_pc_and_recompute_addr_range = true; } else if (IsTrapHandlerSymbol(process, m_sym_ctx)) { // Signal dispatch may set the return address of the handler it calls to // point to the first byte of a return trampoline (like __kernel_rt_sigreturn), @@ -635,9 +636,9 @@ void RegisterContextUnwind::InitializeNonZerothFrame() { } } else { m_full_unwind_plan_sp = GetFullUnwindPlanForFrame(); - int valid_offset = -1; - if (IsUnwindPlanValidForCurrentPC(m_full_unwind_plan_sp, valid_offset)) { - active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset(valid_offset); + if (IsUnwindPlanValidForCurrentPC(m_full_unwind_plan_sp)) { + active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset( + m_current_offset_backed_up_one); row_register_kind = m_full_unwind_plan_sp->GetRegisterKind(); PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp); if (active_row.get() && log) { @@ -1006,8 +1007,7 @@ UnwindPlanSP RegisterContextUnwind::GetFullUnwindPlanForFrame() { unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite( process->GetTarget(), m_thread); } - int valid_offset = -1; - if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp, valid_offset)) { + if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp)) { UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because this " "is the call-site unwind plan", unwind_plan_sp->GetSourceName().GetCString()); @@ -1046,7 +1046,7 @@ UnwindPlanSP RegisterContextUnwind::GetFullUnwindPlanForFrame() { } } - if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp, valid_offset)) { + if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp)) { UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because we " "failed to find a call-site unwind plan that would work", unwind_plan_sp->GetSourceName().GetCString()); @@ -1247,7 +1247,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)); + Log *log = GetLog(LLDBLog::Unwind); // Have we already found this register location? if (!m_registers.empty()) { @@ -1312,7 +1312,8 @@ RegisterContextUnwind::SavedLocationForRegister( LLDB_REGNUM_GENERIC_PC); UnwindPlan::RowSP active_row = - m_full_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset); + m_full_unwind_plan_sp->GetRowForFunctionOffset( + m_current_offset_backed_up_one); unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind(); if (got_new_full_unwindplan && active_row.get() && log) { @@ -1769,7 +1770,8 @@ bool RegisterContextUnwind::TryFallbackUnwindPlan() { m_full_unwind_plan_sp = m_fallback_unwind_plan_sp; UnwindPlan::RowSP active_row = - m_fallback_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset); + m_fallback_unwind_plan_sp->GetRowForFunctionOffset( + m_current_offset_backed_up_one); if (active_row && active_row->GetCFAValue().GetValueType() != @@ -2230,7 +2232,8 @@ bool RegisterContextUnwind::WriteRegister(const RegisterInfo *reg_info, } // Don't need to implement this one -bool RegisterContextUnwind::ReadAllRegisterValues(lldb::DataBufferSP &data_sp) { +bool RegisterContextUnwind::ReadAllRegisterValues( + lldb::WritableDataBufferSP &data_sp) { return false; } @@ -2324,45 +2327,35 @@ bool RegisterContextUnwind::ReadPC(addr_t &pc) { } void RegisterContextUnwind::UnwindLogMsg(const char *fmt, ...) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); - if (log) { - va_list args; - va_start(args, fmt); - - char *logmsg; - if (vasprintf(&logmsg, fmt, args) == -1 || logmsg == nullptr) { - if (logmsg) - free(logmsg); - va_end(args); - return; - } - va_end(args); + Log *log = GetLog(LLDBLog::Unwind); + if (!log) + return; + + va_list args; + va_start(args, fmt); + llvm::SmallString<0> logmsg; + if (VASprintf(logmsg, fmt, args)) { LLDB_LOGF(log, "%*sth%d/fr%u %s", m_frame_number < 100 ? m_frame_number : 100, "", - m_thread.GetIndexID(), m_frame_number, logmsg); - free(logmsg); + m_thread.GetIndexID(), m_frame_number, logmsg.c_str()); } + va_end(args); } void RegisterContextUnwind::UnwindLogMsgVerbose(const char *fmt, ...) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); - if (log && log->GetVerbose()) { - va_list args; - va_start(args, fmt); - - char *logmsg; - if (vasprintf(&logmsg, fmt, args) == -1 || logmsg == nullptr) { - if (logmsg) - free(logmsg); - va_end(args); - return; - } - va_end(args); + Log *log = GetLog(LLDBLog::Unwind); + if (!log || !log->GetVerbose()) + return; + + va_list args; + va_start(args, fmt); + llvm::SmallString<0> logmsg; + if (VASprintf(logmsg, fmt, args)) { LLDB_LOGF(log, "%*sth%d/fr%u %s", m_frame_number < 100 ? m_frame_number : 100, "", - m_thread.GetIndexID(), m_frame_number, logmsg); - free(logmsg); + m_thread.GetIndexID(), m_frame_number, logmsg.c_str()); } + va_end(args); } diff --git a/contrib/llvm-project/lldb/source/Target/RemoteAwarePlatform.cpp b/contrib/llvm-project/lldb/source/Target/RemoteAwarePlatform.cpp index b92d4d5fcaa7..c7b0ade845cf 100644 --- a/contrib/llvm-project/lldb/source/Target/RemoteAwarePlatform.cpp +++ b/contrib/llvm-project/lldb/source/Target/RemoteAwarePlatform.cpp @@ -10,7 +10,6 @@ #include "lldb/Core/Module.h" #include "lldb/Core/ModuleList.h" #include "lldb/Core/ModuleSpec.h" -#include "lldb/Host/FileCache.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" @@ -132,7 +131,9 @@ Status RemoteAwarePlatform::ResolveExecutable( // if we can find a match that way StreamString arch_names; llvm::ListSeparator LS; - for (const ArchSpec &arch : GetSupportedArchitectures()) { + ArchSpec process_host_arch; + for (const ArchSpec &arch : + GetSupportedArchitectures(process_host_arch)) { resolved_module_spec.GetArchitecture() = arch; error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, module_search_paths_ptr, nullptr, nullptr); @@ -178,14 +179,12 @@ Status RemoteAwarePlatform::RunShellCommand( llvm::StringRef shell, llvm::StringRef command, const FileSpec &working_dir, int *status_ptr, int *signo_ptr, std::string *command_output, const Timeout<std::micro> &timeout) { - if (IsHost()) - return Host::RunShellCommand(shell, command, working_dir, status_ptr, - signo_ptr, command_output, timeout); if (m_remote_platform_sp) return m_remote_platform_sp->RunShellCommand(shell, command, working_dir, status_ptr, signo_ptr, command_output, timeout); - return Status("unable to run a remote command without a platform"); + return Platform::RunShellCommand(shell, command, working_dir, status_ptr, + signo_ptr, command_output, timeout); } Status RemoteAwarePlatform::MakeDirectory(const FileSpec &file_spec, @@ -214,16 +213,12 @@ Status RemoteAwarePlatform::SetFilePermissions(const FileSpec &file_spec, lldb::user_id_t RemoteAwarePlatform::OpenFile(const FileSpec &file_spec, File::OpenOptions flags, uint32_t mode, Status &error) { - if (IsHost()) - return FileCache::GetInstance().OpenFile(file_spec, flags, mode, error); if (m_remote_platform_sp) return m_remote_platform_sp->OpenFile(file_spec, flags, mode, error); return Platform::OpenFile(file_spec, flags, mode, error); } bool RemoteAwarePlatform::CloseFile(lldb::user_id_t fd, Status &error) { - if (IsHost()) - return FileCache::GetInstance().CloseFile(fd, error); if (m_remote_platform_sp) return m_remote_platform_sp->CloseFile(fd, error); return Platform::CloseFile(fd, error); @@ -232,8 +227,6 @@ bool RemoteAwarePlatform::CloseFile(lldb::user_id_t fd, Status &error) { uint64_t RemoteAwarePlatform::ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst, uint64_t dst_len, Status &error) { - if (IsHost()) - return FileCache::GetInstance().ReadFile(fd, offset, dst, dst_len, error); if (m_remote_platform_sp) return m_remote_platform_sp->ReadFile(fd, offset, dst, dst_len, error); return Platform::ReadFile(fd, offset, dst, dst_len, error); @@ -242,20 +235,12 @@ uint64_t RemoteAwarePlatform::ReadFile(lldb::user_id_t fd, uint64_t offset, uint64_t RemoteAwarePlatform::WriteFile(lldb::user_id_t fd, uint64_t offset, const void *src, uint64_t src_len, Status &error) { - if (IsHost()) - return FileCache::GetInstance().WriteFile(fd, offset, src, src_len, error); if (m_remote_platform_sp) return m_remote_platform_sp->WriteFile(fd, offset, src, src_len, error); return Platform::WriteFile(fd, offset, src, src_len, error); } lldb::user_id_t RemoteAwarePlatform::GetFileSize(const FileSpec &file_spec) { - if (IsHost()) { - uint64_t Size; - if (llvm::sys::fs::file_size(file_spec.GetPath(), Size)) - return 0; - return Size; - } if (m_remote_platform_sp) return m_remote_platform_sp->GetFileSize(file_spec); return Platform::GetFileSize(file_spec); @@ -263,24 +248,18 @@ lldb::user_id_t RemoteAwarePlatform::GetFileSize(const FileSpec &file_spec) { Status RemoteAwarePlatform::CreateSymlink(const FileSpec &src, const FileSpec &dst) { - if (IsHost()) - return FileSystem::Instance().Symlink(src, dst); if (m_remote_platform_sp) return m_remote_platform_sp->CreateSymlink(src, dst); return Platform::CreateSymlink(src, dst); } bool RemoteAwarePlatform::GetFileExists(const FileSpec &file_spec) { - if (IsHost()) - return FileSystem::Instance().Exists(file_spec); if (m_remote_platform_sp) return m_remote_platform_sp->GetFileExists(file_spec); return Platform::GetFileExists(file_spec); } Status RemoteAwarePlatform::Unlink(const FileSpec &file_spec) { - if (IsHost()) - return llvm::sys::fs::remove(file_spec.GetPath()); if (m_remote_platform_sp) return m_remote_platform_sp->Unlink(file_spec); return Platform::Unlink(file_spec); @@ -288,11 +267,9 @@ Status RemoteAwarePlatform::Unlink(const FileSpec &file_spec) { bool RemoteAwarePlatform::CalculateMD5(const FileSpec &file_spec, uint64_t &low, uint64_t &high) { - if (IsHost()) - return Platform::CalculateMD5(file_spec, low, high); if (m_remote_platform_sp) return m_remote_platform_sp->CalculateMD5(file_spec, low, high); - return false; + return Platform::CalculateMD5(file_spec, low, high); } FileSpec RemoteAwarePlatform::GetRemoteWorkingDirectory() { @@ -347,55 +324,42 @@ ArchSpec RemoteAwarePlatform::GetRemoteSystemArchitecture() { } const char *RemoteAwarePlatform::GetHostname() { - if (IsHost()) - return Platform::GetHostname(); if (m_remote_platform_sp) return m_remote_platform_sp->GetHostname(); - return nullptr; + return Platform::GetHostname(); } UserIDResolver &RemoteAwarePlatform::GetUserIDResolver() { - if (IsHost()) - return HostInfo::GetUserIDResolver(); if (m_remote_platform_sp) return m_remote_platform_sp->GetUserIDResolver(); - return UserIDResolver::GetNoopResolver(); + return Platform::GetUserIDResolver(); } Environment RemoteAwarePlatform::GetEnvironment() { - if (IsRemote()) { - if (m_remote_platform_sp) - return m_remote_platform_sp->GetEnvironment(); - return Environment(); - } - return Host::GetEnvironment(); + if (m_remote_platform_sp) + return m_remote_platform_sp->GetEnvironment(); + return Platform::GetEnvironment(); } bool RemoteAwarePlatform::IsConnected() const { - if (IsHost()) - return true; - else if (m_remote_platform_sp) + if (m_remote_platform_sp) return m_remote_platform_sp->IsConnected(); - return false; + return Platform::IsConnected(); } bool RemoteAwarePlatform::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) { - if (IsHost()) - return Platform::GetProcessInfo(pid, process_info); if (m_remote_platform_sp) return m_remote_platform_sp->GetProcessInfo(pid, process_info); - return false; + return Platform::GetProcessInfo(pid, process_info); } uint32_t RemoteAwarePlatform::FindProcesses(const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos) { - if (IsHost()) - return Platform::FindProcesses(match_info, process_infos); if (m_remote_platform_sp) return m_remote_platform_sp->FindProcesses(match_info, process_infos); - return 0; + return Platform::FindProcesses(match_info, process_infos); } lldb::ProcessSP RemoteAwarePlatform::ConnectProcess(llvm::StringRef connect_url, @@ -411,25 +375,15 @@ lldb::ProcessSP RemoteAwarePlatform::ConnectProcess(llvm::StringRef connect_url, } Status RemoteAwarePlatform::LaunchProcess(ProcessLaunchInfo &launch_info) { - Status error; - - if (IsHost()) { - error = Platform::LaunchProcess(launch_info); - } else { - if (m_remote_platform_sp) - error = m_remote_platform_sp->LaunchProcess(launch_info); - else - error.SetErrorString("the platform is not currently connected"); - } - return error; + if (m_remote_platform_sp) + return m_remote_platform_sp->LaunchProcess(launch_info); + return Platform::LaunchProcess(launch_info); } Status RemoteAwarePlatform::KillProcess(const lldb::pid_t pid) { - if (IsHost()) - return Platform::KillProcess(pid); if (m_remote_platform_sp) return m_remote_platform_sp->KillProcess(pid); - return Status("the platform is not currently connected"); + return Platform::KillProcess(pid); } size_t RemoteAwarePlatform::ConnectToWaitingProcesses(Debugger &debugger, diff --git a/contrib/llvm-project/lldb/source/Target/SectionLoadList.cpp b/contrib/llvm-project/lldb/source/Target/SectionLoadList.cpp index f1a626b04802..03160ee10dd8 100644 --- a/contrib/llvm-project/lldb/source/Target/SectionLoadList.cpp +++ b/contrib/llvm-project/lldb/source/Target/SectionLoadList.cpp @@ -13,6 +13,7 @@ #include "lldb/Symbol/Block.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Symbol/SymbolContext.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Stream.h" @@ -63,7 +64,7 @@ SectionLoadList::GetSectionLoadAddress(const lldb::SectionSP §ion) const { bool SectionLoadList::SetSectionLoadAddress(const lldb::SectionSP §ion, addr_t load_addr, bool warn_multiple) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); ModuleSP module_sp(section->GetModule()); if (module_sp) { @@ -136,7 +137,7 @@ size_t SectionLoadList::SetSectionUnloaded(const lldb::SectionSP §ion_sp) { size_t unload_count = 0; if (section_sp) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); if (log && log->GetVerbose()) { ModuleSP module_sp = section_sp->GetModule(); @@ -171,7 +172,7 @@ size_t SectionLoadList::SetSectionUnloaded(const lldb::SectionSP §ion_sp) { bool SectionLoadList::SetSectionUnloaded(const lldb::SectionSP §ion_sp, addr_t load_addr) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); if (log && log->GetVerbose()) { ModuleSP module_sp = section_sp->GetModule(); diff --git a/contrib/llvm-project/lldb/source/Target/StackFrame.cpp b/contrib/llvm-project/lldb/source/Target/StackFrame.cpp index 58de26b23b65..1e3dbc73a04e 100644 --- a/contrib/llvm-project/lldb/source/Target/StackFrame.cpp +++ b/contrib/llvm-project/lldb/source/Target/StackFrame.cpp @@ -29,6 +29,7 @@ #include "lldb/Target/StackFrameRecognizer.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegisterValue.h" @@ -551,7 +552,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( if (!var_sp && (options & eExpressionPathOptionsAllowDirectIVarAccess)) { // Check for direct ivars access which helps us with implicit access to - // ivars with the "this->" or "self->" + // ivars using "this" or "self". GetSymbolContext(eSymbolContextFunction | eSymbolContextBlock); lldb::LanguageType method_language = eLanguageTypeUnknown; bool is_instance_method = false; @@ -562,7 +563,13 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( var_sp = variable_list->FindVariable(method_object_name); if (var_sp) { separator_idx = 0; - var_expr_storage = "->"; + if (Type *var_type = var_sp->GetType()) + if (auto compiler_type = var_type->GetForwardCompilerType()) + if (!compiler_type.IsPointerType()) + var_expr_storage = "."; + + if (var_expr_storage.empty()) + var_expr_storage = "->"; var_expr_storage += var_expr; var_expr = var_expr_storage; synthetically_added_instance_object = true; @@ -1336,9 +1343,8 @@ lldb::ValueObjectSP StackFrame::GuessValueForAddress(lldb::addr_t addr) { auto c_type_system_or_err = target_sp->GetScratchTypeSystemForLanguage(eLanguageTypeC); if (auto err = c_type_system_or_err.takeError()) { - LLDB_LOG_ERROR( - lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD), - std::move(err), "Unable to guess value for given address"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Thread), std::move(err), + "Unable to guess value for given address"); return ValueObjectSP(); } else { CompilerType void_ptr_type = @@ -1384,7 +1390,7 @@ ValueObjectSP GetValueForOffset(StackFrame &frame, ValueObjectSP &parent, } int64_t child_offset = child_sp->GetByteOffset(); - int64_t child_size = child_sp->GetByteSize().getValueOr(0); + int64_t child_size = child_sp->GetByteSize().value_or(0); if (offset >= child_offset && offset < (child_offset + child_size)) { return GetValueForOffset(frame, child_sp, offset - child_offset); @@ -1417,8 +1423,8 @@ ValueObjectSP GetValueForDereferincingOffset(StackFrame &frame, } if (offset >= 0 && uint64_t(offset) >= pointee->GetByteSize()) { - int64_t index = offset / pointee->GetByteSize().getValueOr(1); - offset = offset % pointee->GetByteSize().getValueOr(1); + int64_t index = offset / pointee->GetByteSize().value_or(1); + offset = offset % pointee->GetByteSize().value_or(1); const bool can_create = true; pointee = base->GetSyntheticArrayMember(index, can_create); } diff --git a/contrib/llvm-project/lldb/source/Target/StackFrameList.cpp b/contrib/llvm-project/lldb/source/Target/StackFrameList.cpp index 061500152a49..14663e4b7c7b 100644 --- a/contrib/llvm-project/lldb/source/Target/StackFrameList.cpp +++ b/contrib/llvm-project/lldb/source/Target/StackFrameList.cpp @@ -21,6 +21,7 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Target/Unwind.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "llvm/ADT/SmallPtrSet.h" @@ -65,7 +66,7 @@ uint32_t StackFrameList::GetCurrentInlinedDepth() { if (cur_pc != m_current_inlined_pc) { m_current_inlined_pc = LLDB_INVALID_ADDRESS; m_current_inlined_depth = UINT32_MAX; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (log && log->GetVerbose()) LLDB_LOGF( log, @@ -89,7 +90,7 @@ void StackFrameList::ResetCurrentInlinedDepth() { if (!m_frames[0]->IsInlined()) { m_current_inlined_depth = UINT32_MAX; m_current_inlined_pc = LLDB_INVALID_ADDRESS; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (log && log->GetVerbose()) LLDB_LOGF( log, @@ -187,7 +188,7 @@ void StackFrameList::ResetCurrentInlinedDepth() { } m_current_inlined_pc = curr_pc; m_current_inlined_depth = num_inlined_functions + 1; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (log && log->GetVerbose()) LLDB_LOGF(log, "ResetCurrentInlinedDepth: setting inlined " @@ -376,7 +377,7 @@ void StackFrameList::SynthesizeTailCallFrames(StackFrame &next_frame) { if (!next_reg_ctx_sp) return; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); StackFrame &prev_frame = *m_frames.back().get(); diff --git a/contrib/llvm-project/lldb/source/Target/Statistics.cpp b/contrib/llvm-project/lldb/source/Target/Statistics.cpp index ebddad837d14..b8ad25e71f06 100644 --- a/contrib/llvm-project/lldb/source/Target/Statistics.cpp +++ b/contrib/llvm-project/lldb/source/Target/Statistics.cpp @@ -62,6 +62,17 @@ json::Value ModuleStats::ToJSON() const { debug_info_index_loaded_from_cache); module.try_emplace("debugInfoIndexSavedToCache", debug_info_index_saved_to_cache); + module.try_emplace("debugInfoEnabled", debug_info_enabled); + module.try_emplace("symbolTableStripped", symtab_stripped); + if (!symfile_path.empty()) + module.try_emplace("symbolFilePath", symfile_path); + + if (!symfile_modules.empty()) { + json::Array symfile_ids; + for (const auto symfile_id: symfile_modules) + symfile_ids.emplace_back(symfile_id); + module.try_emplace("symbolFileModuleIdentifiers", std::move(symfile_ids)); + } return module; } @@ -174,7 +185,10 @@ llvm::json::Value DebuggerStats::ReportStatistics(Debugger &debugger, std::vector<ModuleStats> modules; std::lock_guard<std::recursive_mutex> guard( Module::GetAllocationModuleCollectionMutex()); - const size_t num_modules = Module::GetNumberAllocatedModules(); + const uint64_t num_modules = Module::GetNumberAllocatedModules(); + uint32_t num_debug_info_enabled_modules = 0; + uint32_t num_modules_has_debug_info = 0; + uint32_t num_stripped_modules = 0; for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) { Module *module = Module::GetAllocatedModuleAtIndex(image_idx); ModuleStats module_stat; @@ -200,6 +214,10 @@ llvm::json::Value DebuggerStats::ReportStatistics(Debugger &debugger, } SymbolFile *sym_file = module->GetSymbolFile(); if (sym_file) { + + if (sym_file->GetObjectFile() != module->GetObjectFile()) + module_stat.symfile_path = + sym_file->GetObjectFile()->GetFileSpec().GetPath(); module_stat.debug_index_time = sym_file->GetDebugInfoIndexTime().count(); module_stat.debug_parse_time = sym_file->GetDebugInfoParseTime().count(); module_stat.debug_info_size = sym_file->GetDebugInfoSize(); @@ -211,6 +229,18 @@ llvm::json::Value DebuggerStats::ReportStatistics(Debugger &debugger, sym_file->GetDebugInfoIndexWasSavedToCache(); if (module_stat.debug_info_index_saved_to_cache) ++debug_index_saved; + ModuleList symbol_modules = sym_file->GetDebugInfoModules(); + for (const auto &symbol_module: symbol_modules.Modules()) + module_stat.symfile_modules.push_back((intptr_t)symbol_module.get()); + module_stat.symtab_stripped = module->GetObjectFile()->IsStripped(); + if (module_stat.symtab_stripped) + ++num_stripped_modules; + module_stat.debug_info_enabled = sym_file->GetLoadDebugInfoEnabled() && + module_stat.debug_info_size > 0; + if (module_stat.debug_info_enabled) + ++num_debug_info_enabled_modules; + if (module_stat.debug_info_size > 0) + ++num_modules_has_debug_info; } symtab_parse_time += module_stat.symtab_parse_time; symtab_index_time += module_stat.symtab_index_time; @@ -238,6 +268,10 @@ llvm::json::Value DebuggerStats::ReportStatistics(Debugger &debugger, {"totalDebugInfoIndexLoadedFromCache", debug_index_loaded}, {"totalDebugInfoIndexSavedToCache", debug_index_saved}, {"totalDebugInfoByteSize", debug_info_size}, + {"totalModuleCount", num_modules}, + {"totalModuleCountHasDebugInfo", num_modules_has_debug_info}, + {"totalDebugInfoEnabled", num_debug_info_enabled_modules}, + {"totalSymbolTableStripped", num_stripped_modules}, }; return std::move(global_stats); } diff --git a/contrib/llvm-project/lldb/source/Target/StopInfo.cpp b/contrib/llvm-project/lldb/source/Target/StopInfo.cpp index 1de281b1761f..00d30070c8c9 100644 --- a/contrib/llvm-project/lldb/source/Target/StopInfo.cpp +++ b/contrib/llvm-project/lldb/source/Target/StopInfo.cpp @@ -21,6 +21,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlan.h" #include "lldb/Target/UnixSignals.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" @@ -87,7 +88,7 @@ public: : StopInfo(thread, break_id), m_should_stop(false), m_should_stop_is_valid(false), m_should_perform_action(true), m_address(LLDB_INVALID_ADDRESS), m_break_id(LLDB_INVALID_BREAK_ID), - m_was_one_shot(false) { + m_was_all_internal(false), m_was_one_shot(false) { StoreBPInfo(); } @@ -95,7 +96,7 @@ public: : StopInfo(thread, break_id), m_should_stop(should_stop), m_should_stop_is_valid(true), m_should_perform_action(true), m_address(LLDB_INVALID_ADDRESS), m_break_id(LLDB_INVALID_BREAK_ID), - m_was_one_shot(false) { + m_was_all_internal(false), m_was_one_shot(false) { StoreBPInfo(); } @@ -107,11 +108,22 @@ public: BreakpointSiteSP bp_site_sp( thread_sp->GetProcess()->GetBreakpointSiteList().FindByID(m_value)); if (bp_site_sp) { - if (bp_site_sp->GetNumberOfOwners() == 1) { + uint32_t num_owners = bp_site_sp->GetNumberOfOwners(); + if (num_owners == 1) { BreakpointLocationSP bp_loc_sp = bp_site_sp->GetOwnerAtIndex(0); if (bp_loc_sp) { - m_break_id = bp_loc_sp->GetBreakpoint().GetID(); - m_was_one_shot = bp_loc_sp->GetBreakpoint().IsOneShot(); + Breakpoint & bkpt = bp_loc_sp->GetBreakpoint(); + m_break_id = bkpt.GetID(); + m_was_one_shot = bkpt.IsOneShot(); + m_was_all_internal = bkpt.IsInternal(); + } + } else { + m_was_all_internal = true; + for (uint32_t i = 0; i < num_owners; i++) { + if (!bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint().IsInternal()) { + m_was_all_internal = false; + break; + } } } m_address = bp_site_sp->GetLoadAddress(); @@ -145,7 +157,7 @@ public: bp_site_sp->BumpHitCounts(); m_should_stop = bp_site_sp->ShouldStop(&context); } else { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "Process::%s could not find breakpoint site id: %" PRId64 @@ -162,23 +174,7 @@ public: } bool DoShouldNotify(Event *event_ptr) override { - ThreadSP thread_sp(m_thread_wp.lock()); - if (thread_sp) { - BreakpointSiteSP bp_site_sp( - thread_sp->GetProcess()->GetBreakpointSiteList().FindByID(m_value)); - if (bp_site_sp) { - bool all_internal = true; - - for (uint32_t i = 0; i < bp_site_sp->GetNumberOfOwners(); i++) { - if (!bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint().IsInternal()) { - all_internal = false; - break; - } - } - return !all_internal; - } - } - return true; + return !m_was_all_internal; } const char *GetDescription() override { @@ -264,8 +260,7 @@ protected: ThreadSP thread_sp(m_thread_wp.lock()); if (thread_sp) { - Log *log = lldb_private::GetLogIfAnyCategoriesSet( - LIBLLDB_LOG_BREAKPOINTS | LIBLLDB_LOG_STEP); + Log *log = GetLog(LLDBLog::Breakpoints | LLDBLog::Step); if (!thread_sp->IsValid()) { // This shouldn't ever happen, but just in case, don't do more harm. @@ -280,7 +275,13 @@ protected: BreakpointSiteSP bp_site_sp( thread_sp->GetProcess()->GetBreakpointSiteList().FindByID(m_value)); std::unordered_set<break_id_t> precondition_breakpoints; - + // Breakpoints that fail their condition check are not considered to + // have been hit. If the only locations at this site have failed their + // conditions, we should change the stop-info to none. Otherwise, if we + // hit another breakpoint on a different thread which does stop, users + // will see a breakpont hit with a failed condition, which is wrong. + // Use this variable to tell us if that is true. + bool actually_hit_any_locations = false; if (bp_site_sp) { // Let's copy the owners list out of the site and store them in a local // list. That way if one of the breakpoint actions changes the site, @@ -290,6 +291,8 @@ protected: if (num_owners == 0) { m_should_stop = true; + actually_hit_any_locations = true; // We're going to stop, don't + // change the stop info. } else { // We go through each location, and test first its precondition - // this overrides everything. Note, we only do this once per @@ -376,9 +379,10 @@ protected: "StopInfoBreakpoint::PerformAction - in expression, " "continuing: %s.", m_should_stop ? "true" : "false"); - process->GetTarget().GetDebugger().GetAsyncOutputStream()->Printf( - "Warning: hit breakpoint while running function, skipping " - "commands and conditions to prevent recursion.\n"); + Debugger::ReportWarning( + "hit breakpoint while running function, skipping commands and " + "conditions to prevent recursion", + process->GetTarget().GetDebugger().GetID()); return; } @@ -444,27 +448,31 @@ protected: // should stop, then we'll run the callback for the breakpoint. If // the callback says we shouldn't stop that will win. - if (bp_loc_sp->GetConditionText() != nullptr) { + if (bp_loc_sp->GetConditionText() == nullptr) + actually_hit_any_locations = true; + else { Status condition_error; bool condition_says_stop = bp_loc_sp->ConditionSaysStop(exe_ctx, condition_error); if (!condition_error.Success()) { - Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger(); - StreamSP error_sp = debugger.GetAsyncErrorStream(); - error_sp->Printf("Stopped due to an error evaluating condition " - "of breakpoint "); - bp_loc_sp->GetDescription(error_sp.get(), - eDescriptionLevelBrief); - error_sp->Printf(": \"%s\"", bp_loc_sp->GetConditionText()); - error_sp->EOL(); + // If the condition fails to evaluate, we are going to stop + // at it, so the location was hit. + actually_hit_any_locations = true; const char *err_str = - condition_error.AsCString("<Unknown Error>"); + condition_error.AsCString("<unknown error>"); LLDB_LOGF(log, "Error evaluating condition: \"%s\"\n", err_str); - error_sp->PutCString(err_str); - error_sp->EOL(); - error_sp->Flush(); + StreamString strm; + strm << "stopped due to an error evaluating condition of " + "breakpoint "; + bp_loc_sp->GetDescription(&strm, eDescriptionLevelBrief); + strm << ": \"" << bp_loc_sp->GetConditionText() << "\"\n"; + strm << err_str; + + Debugger::ReportError( + strm.GetString().str(), + exe_ctx.GetTargetRef().GetDebugger().GetID()); } else { LLDB_LOGF(log, "Condition evaluated for breakpoint %s on thread " @@ -472,7 +480,9 @@ protected: loc_desc.GetData(), static_cast<unsigned long long>(thread_sp->GetID()), condition_says_stop); - if (!condition_says_stop) { + if (condition_says_stop) + actually_hit_any_locations = true; + else { // We don't want to increment the hit count of breakpoints if // the condition fails. We've already bumped it by the time // we get here, so undo the bump: @@ -564,8 +574,8 @@ protected: } else { m_should_stop = true; m_should_stop_is_valid = true; - Log *log_process( - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + actually_hit_any_locations = true; + Log *log_process(GetLog(LLDBLog::Process)); LLDB_LOGF(log_process, "Process::%s could not find breakpoint site id: %" PRId64 @@ -584,6 +594,12 @@ protected: // show the breakpoint stop, so compute the public stop info immediately // here. thread_sp->CalculatePublicStopInfo(); + } else if (!actually_hit_any_locations) { + // In the end, we didn't actually have any locations that passed their + // "was I hit" checks. So say we aren't stopped. + GetThread()->ResetStopInfo(); + LLDB_LOGF(log, "Process::%s all locations failed condition checks.", + __FUNCTION__); } LLDB_LOGF(log, @@ -604,6 +620,7 @@ private: // in case somebody deletes it between the time the StopInfo is made and the // description is asked for. lldb::break_id_t m_break_id; + bool m_was_all_internal; bool m_was_one_shot; }; @@ -657,8 +674,7 @@ public: StopInfoWatchpoint(Thread &thread, break_id_t watch_id, lldb::addr_t watch_hit_addr) - : StopInfo(thread, watch_id), m_should_stop(false), - m_should_stop_is_valid(false), m_watch_hit_addr(watch_hit_addr) {} + : StopInfo(thread, watch_id), m_watch_hit_addr(watch_hit_addr) {} ~StopInfoWatchpoint() override = default; @@ -696,7 +712,7 @@ protected: StoppointCallbackContext context(event_ptr, exe_ctx, true); m_should_stop = wp_sp->ShouldStop(&context); } else { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "Process::%s could not find watchpoint location id: %" PRId64 @@ -719,7 +735,7 @@ protected: } void PerformAction(Event *event_ptr) override { - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS); + Log *log = GetLog(LLDBLog::Watchpoints); // We're going to calculate if we should stop or not in some way during the // course of this code. Also by default we're going to stop, so set that // here. @@ -861,20 +877,18 @@ protected: } } } else { - StreamSP error_sp = debugger.GetAsyncErrorStream(); - error_sp->Printf( - "Stopped due to an error evaluating condition of watchpoint "); - wp_sp->GetDescription(error_sp.get(), eDescriptionLevelBrief); - error_sp->Printf(": \"%s\"", wp_sp->GetConditionText()); - error_sp->EOL(); - const char *err_str = error.AsCString("<Unknown Error>"); + const char *err_str = error.AsCString("<unknown error>"); LLDB_LOGF(log, "Error evaluating condition: \"%s\"\n", err_str); - error_sp->PutCString(err_str); - error_sp->EOL(); - error_sp->Flush(); - // If the condition fails to be parsed or run, we should stop. - m_should_stop = true; + StreamString strm; + strm << "stopped due to an error evaluating condition of " + "watchpoint "; + wp_sp->GetDescription(&strm, eDescriptionLevelBrief); + strm << ": \"" << wp_sp->GetConditionText() << "\"\n"; + strm << err_str; + + Debugger::ReportError(strm.GetString().str(), + exe_ctx.GetTargetRef().GetDebugger().GetID()); } } @@ -917,8 +931,7 @@ protected: } } else { - Log *log_process( - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log_process(GetLog(LLDBLog::Process)); LLDB_LOGF(log_process, "Process::%s could not find watchpoint id: %" PRId64 "...", @@ -933,8 +946,8 @@ protected: } private: - bool m_should_stop; - bool m_should_stop_is_valid; + bool m_should_stop = false; + bool m_should_stop_is_valid = false; lldb::addr_t m_watch_hit_addr; }; @@ -1124,8 +1137,7 @@ private: class StopInfoExec : public StopInfo { public: - StopInfoExec(Thread &thread) - : StopInfo(thread, LLDB_INVALID_UID), m_performed_action(false) {} + StopInfoExec(Thread &thread) : StopInfo(thread, LLDB_INVALID_UID) {} ~StopInfoExec() override = default; @@ -1151,7 +1163,7 @@ protected: thread_sp->GetProcess()->DidExec(); } - bool m_performed_action; + bool m_performed_action = false; }; // StopInfoFork @@ -1159,8 +1171,8 @@ protected: class StopInfoFork : public StopInfo { public: StopInfoFork(Thread &thread, lldb::pid_t child_pid, lldb::tid_t child_tid) - : StopInfo(thread, child_pid), m_performed_action(false), - m_child_pid(child_pid), m_child_tid(child_tid) {} + : StopInfo(thread, child_pid), m_child_pid(child_pid), + m_child_tid(child_tid) {} ~StopInfoFork() override = default; @@ -1181,7 +1193,7 @@ protected: thread_sp->GetProcess()->DidFork(m_child_pid, m_child_tid); } - bool m_performed_action; + bool m_performed_action = false; private: lldb::pid_t m_child_pid; @@ -1193,8 +1205,8 @@ private: class StopInfoVFork : public StopInfo { public: StopInfoVFork(Thread &thread, lldb::pid_t child_pid, lldb::tid_t child_tid) - : StopInfo(thread, child_pid), m_performed_action(false), - m_child_pid(child_pid), m_child_tid(child_tid) {} + : StopInfo(thread, child_pid), m_child_pid(child_pid), + m_child_tid(child_tid) {} ~StopInfoVFork() override = default; @@ -1215,7 +1227,7 @@ protected: thread_sp->GetProcess()->DidVFork(m_child_pid, m_child_tid); } - bool m_performed_action; + bool m_performed_action = false; private: lldb::pid_t m_child_pid; @@ -1226,8 +1238,7 @@ private: class StopInfoVForkDone : public StopInfo { public: - StopInfoVForkDone(Thread &thread) - : StopInfo(thread, 0), m_performed_action(false) {} + StopInfoVForkDone(Thread &thread) : StopInfo(thread, 0) {} ~StopInfoVForkDone() override = default; @@ -1248,7 +1259,7 @@ protected: thread_sp->GetProcess()->DidVForkDone(); } - bool m_performed_action; + bool m_performed_action = false; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/source/Target/Target.cpp b/contrib/llvm-project/lldb/source/Target/Target.cpp index 6d33db6554d2..65064ecf75b1 100644 --- a/contrib/llvm-project/lldb/source/Target/Target.cpp +++ b/contrib/llvm-project/lldb/source/Target/Target.cpp @@ -51,9 +51,11 @@ #include "lldb/Target/SystemRuntime.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadSpec.h" +#include "lldb/Target/UnixSignals.h" #include "lldb/Utility/Event.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/State.h" #include "lldb/Utility/StreamString.h" @@ -105,13 +107,13 @@ Target::Target(Debugger &debugger, const ArchSpec &target_arch, SetEventName(eBroadcastBitModulesUnloaded, "modules-unloaded"); SetEventName(eBroadcastBitWatchpointChanged, "watchpoint-changed"); SetEventName(eBroadcastBitSymbolsLoaded, "symbols-loaded"); - + CheckInWithManager(); - LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT), - "{0} Target::Target()", static_cast<void *>(this)); + LLDB_LOG(GetLog(LLDBLog::Object), "{0} Target::Target()", + static_cast<void *>(this)); if (target_arch.IsValid()) { - LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET), + LLDB_LOG(GetLog(LLDBLog::Target), "Target::Target created with architecture {0} ({1})", target_arch.GetArchitectureName(), target_arch.GetTriple().getTriple().c_str()); @@ -121,7 +123,7 @@ Target::Target(Debugger &debugger, const ArchSpec &target_arch, } Target::~Target() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); + Log *log = GetLog(LLDBLog::Object); LLDB_LOG(log, "{0} Target::~Target()", static_cast<void *>(this)); DeleteCurrentProcess(); } @@ -146,6 +148,8 @@ void Target::PrimeFromDummyTarget(Target &target) { m_frame_recognizer_manager_up = std::make_unique<StackFrameRecognizerManager>( *target.m_frame_recognizer_manager_up); + + m_dummy_signals = target.m_dummy_signals; } void Target::Dump(Stream *s, lldb::DescriptionLevel description_level) { @@ -184,6 +188,8 @@ void Target::CleanupProcess() { void Target::DeleteCurrentProcess() { if (m_process_sp) { + // We dispose any active tracing sessions on the current process + m_trace_sp.reset(); m_section_load_history.Clear(); if (m_process_sp->IsAlive()) m_process_sp->Destroy(false); @@ -284,6 +290,19 @@ void Target::Destroy() { m_stop_hooks.clear(); m_stop_hook_next_id = 0; m_suppress_stop_hooks = false; + Args signal_args; + ClearDummySignals(signal_args); +} + +llvm::StringRef Target::GetABIName() const { + lldb::ABISP abi_sp; + if (m_process_sp) + abi_sp = m_process_sp->GetABI(); + if (!abi_sp) + abi_sp = ABI::FindPlugin(ProcessSP(), GetArchitecture()); + if (abi_sp) + return abi_sp->GetPluginName(); + return {}; } BreakpointList &Target::GetBreakpointList(bool internal) { @@ -647,7 +666,7 @@ void Target::AddBreakpoint(lldb::BreakpointSP bp_sp, bool internal) { else m_breakpoint_list.Add(bp_sp, true); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); if (log) { StreamString s; bp_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose); @@ -743,8 +762,7 @@ void Target::ApplyNameToBreakpoints(BreakpointName &bp_name) { m_breakpoint_list.FindBreakpointsByName(bp_name.GetName().AsCString()); if (!expected_vector) { - LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS), - "invalid breakpoint name: {}", + LLDB_LOG(GetLog(LLDBLog::Breakpoints), "invalid breakpoint name: {}", llvm::toString(expected_vector.takeError())); return; } @@ -789,7 +807,7 @@ static bool CheckIfWatchpointsSupported(Target *target, Status &error) { WatchpointSP Target::CreateWatchpoint(lldb::addr_t addr, size_t size, const CompilerType *type, uint32_t kind, Status &error) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); LLDB_LOGF(log, "Target::%s (addr = 0x%8.8" PRIx64 " size = %" PRIu64 " type = %u)\n", @@ -873,7 +891,7 @@ WatchpointSP Target::CreateWatchpoint(lldb::addr_t addr, size_t size, } void Target::RemoveAllowedBreakpoints() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); LLDB_LOGF(log, "Target::%s \n", __FUNCTION__); m_breakpoint_list.RemoveAllowed(true); @@ -882,7 +900,7 @@ void Target::RemoveAllowedBreakpoints() { } void Target::RemoveAllBreakpoints(bool internal_also) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); LLDB_LOGF(log, "Target::%s (internal_also = %s)\n", __FUNCTION__, internal_also ? "yes" : "no"); @@ -894,7 +912,7 @@ void Target::RemoveAllBreakpoints(bool internal_also) { } void Target::DisableAllBreakpoints(bool internal_also) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); LLDB_LOGF(log, "Target::%s (internal_also = %s)\n", __FUNCTION__, internal_also ? "yes" : "no"); @@ -904,14 +922,14 @@ void Target::DisableAllBreakpoints(bool internal_also) { } void Target::DisableAllowedBreakpoints() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); LLDB_LOGF(log, "Target::%s", __FUNCTION__); m_breakpoint_list.SetEnabledAllowed(false); } void Target::EnableAllBreakpoints(bool internal_also) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); LLDB_LOGF(log, "Target::%s (internal_also = %s)\n", __FUNCTION__, internal_also ? "yes" : "no"); @@ -921,14 +939,14 @@ void Target::EnableAllBreakpoints(bool internal_also) { } void Target::EnableAllowedBreakpoints() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); LLDB_LOGF(log, "Target::%s", __FUNCTION__); m_breakpoint_list.SetEnabledAllowed(true); } bool Target::RemoveBreakpointByID(break_id_t break_id) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); LLDB_LOGF(log, "Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__, break_id, LLDB_BREAK_ID_IS_INTERNAL(break_id) ? "yes" : "no"); @@ -948,7 +966,7 @@ bool Target::RemoveBreakpointByID(break_id_t break_id) { } bool Target::DisableBreakpointByID(break_id_t break_id) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); LLDB_LOGF(log, "Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__, break_id, LLDB_BREAK_ID_IS_INTERNAL(break_id) ? "yes" : "no"); @@ -966,7 +984,7 @@ bool Target::DisableBreakpointByID(break_id_t break_id) { } bool Target::EnableBreakpointByID(break_id_t break_id) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Log *log = GetLog(LLDBLog::Breakpoints); LLDB_LOGF(log, "Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__, break_id, LLDB_BREAK_ID_IS_INTERNAL(break_id) ? "yes" : "no"); @@ -1144,7 +1162,7 @@ Status Target::CreateBreakpointsFromFile(const FileSpec &file, // Assumption: Caller holds the list mutex lock for m_watchpoint_list for end // to end operations. bool Target::RemoveAllWatchpoints(bool end_to_end) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); LLDB_LOGF(log, "Target::%s\n", __FUNCTION__); if (!end_to_end) { @@ -1173,7 +1191,7 @@ bool Target::RemoveAllWatchpoints(bool end_to_end) { // Assumption: Caller holds the list mutex lock for m_watchpoint_list for end // to end operations. bool Target::DisableAllWatchpoints(bool end_to_end) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); LLDB_LOGF(log, "Target::%s\n", __FUNCTION__); if (!end_to_end) { @@ -1200,7 +1218,7 @@ bool Target::DisableAllWatchpoints(bool end_to_end) { // Assumption: Caller holds the list mutex lock for m_watchpoint_list for end // to end operations. bool Target::EnableAllWatchpoints(bool end_to_end) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); LLDB_LOGF(log, "Target::%s\n", __FUNCTION__); if (!end_to_end) { @@ -1226,7 +1244,7 @@ bool Target::EnableAllWatchpoints(bool end_to_end) { // Assumption: Caller holds the list mutex lock for m_watchpoint_list. bool Target::ClearAllWatchpointHitCounts() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); LLDB_LOGF(log, "Target::%s\n", __FUNCTION__); for (WatchpointSP wp_sp : m_watchpoint_list.Watchpoints()) { @@ -1240,7 +1258,7 @@ bool Target::ClearAllWatchpointHitCounts() { // Assumption: Caller holds the list mutex lock for m_watchpoint_list. bool Target::ClearAllWatchpointHistoricValues() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); LLDB_LOGF(log, "Target::%s\n", __FUNCTION__); for (WatchpointSP wp_sp : m_watchpoint_list.Watchpoints()) { @@ -1255,7 +1273,7 @@ bool Target::ClearAllWatchpointHistoricValues() { // Assumption: Caller holds the list mutex lock for m_watchpoint_list during // these operations. bool Target::IgnoreAllWatchpoints(uint32_t ignore_count) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); LLDB_LOGF(log, "Target::%s\n", __FUNCTION__); if (!ProcessIsValid()) @@ -1272,7 +1290,7 @@ bool Target::IgnoreAllWatchpoints(uint32_t ignore_count) { // Assumption: Caller holds the list mutex lock for m_watchpoint_list. bool Target::DisableWatchpointByID(lldb::watch_id_t watch_id) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); LLDB_LOGF(log, "Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id); if (!ProcessIsValid()) @@ -1291,7 +1309,7 @@ bool Target::DisableWatchpointByID(lldb::watch_id_t watch_id) { // Assumption: Caller holds the list mutex lock for m_watchpoint_list. bool Target::EnableWatchpointByID(lldb::watch_id_t watch_id) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); LLDB_LOGF(log, "Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id); if (!ProcessIsValid()) @@ -1310,7 +1328,7 @@ bool Target::EnableWatchpointByID(lldb::watch_id_t watch_id) { // Assumption: Caller holds the list mutex lock for m_watchpoint_list. bool Target::RemoveWatchpointByID(lldb::watch_id_t watch_id) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); LLDB_LOGF(log, "Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id); WatchpointSP watch_to_remove_sp = m_watchpoint_list.FindByID(watch_id); @@ -1327,7 +1345,7 @@ bool Target::RemoveWatchpointByID(lldb::watch_id_t watch_id) { // Assumption: Caller holds the list mutex lock for m_watchpoint_list. bool Target::IgnoreWatchpointByID(lldb::watch_id_t watch_id, uint32_t ignore_count) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + Log *log = GetLog(LLDBLog::Watchpoints); LLDB_LOGF(log, "Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id); if (!ProcessIsValid()) @@ -1392,7 +1410,7 @@ void Target::DidExec() { void Target::SetExecutableModule(ModuleSP &executable_sp, LoadDependentFiles load_dependent_files) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET)); + Log *log = GetLog(LLDBLog::Target); ClearModules(false); if (executable_sp) { @@ -1457,7 +1475,7 @@ void Target::SetExecutableModule(ModuleSP &executable_sp, } bool Target::SetArchitecture(const ArchSpec &arch_spec, bool set_platform) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET)); + Log *log = GetLog(LLDBLog::Target); bool missing_local_arch = !m_arch.GetSpec().IsValid(); bool replace_local_arch = true; bool compatible_local_arch = false; @@ -1470,11 +1488,11 @@ bool Target::SetArchitecture(const ArchSpec &arch_spec, bool set_platform) { if (other.IsValid()) { auto platform_sp = GetPlatform(); if (!platform_sp || - !platform_sp->IsCompatibleArchitecture(other, false, nullptr)) { + !platform_sp->IsCompatibleArchitecture(other, {}, false, nullptr)) { ArchSpec platform_arch; - auto arch_platform_sp = - Platform::GetPlatformForArchitecture(other, &platform_arch); - if (arch_platform_sp) { + if (PlatformSP arch_platform_sp = + GetDebugger().GetPlatformList().GetOrCreate(other, {}, + &platform_arch)) { SetPlatform(arch_platform_sp); if (platform_arch.IsValid()) other = platform_arch; @@ -1545,7 +1563,7 @@ bool Target::SetArchitecture(const ArchSpec &arch_spec, bool set_platform) { } bool Target::MergeArchitecture(const ArchSpec &arch_spec) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET)); + Log *log = GetLog(LLDBLog::Target); if (arch_spec.IsValid()) { if (m_arch.GetSpec().IsCompatibleMatch(arch_spec)) { // The current target arch is compatible with "arch_spec", see if we can @@ -1642,11 +1660,11 @@ void Target::SymbolsDidLoad(ModuleList &module_list) { void Target::ModulesDidUnload(ModuleList &module_list, bool delete_locations) { if (m_valid && module_list.GetSize()) { UnloadModuleSections(module_list); + BroadcastEvent(eBroadcastBitModulesUnloaded, + new TargetEventData(this->shared_from_this(), module_list)); m_breakpoint_list.UpdateBreakpoints(module_list, false, delete_locations); m_internal_breakpoint_list.UpdateBreakpoints(module_list, false, delete_locations); - BroadcastEvent(eBroadcastBitModulesUnloaded, - new TargetEventData(this->shared_from_this(), module_list)); } } @@ -1684,7 +1702,6 @@ 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 @@ -1720,6 +1737,12 @@ size_t Target::ReadMemory(const Address &addr, void *dst, size_t dst_len, lldb::addr_t *load_addr_ptr) { error.Clear(); + Address fixed_addr = addr; + if (ProcessIsValid()) + if (const ABISP &abi = m_process_sp->GetABI()) + fixed_addr.SetLoadAddress(abi->FixAnyAddress(addr.GetLoadAddress(this)), + this); + // if we end up reading this from process memory, we will fill this with the // actual load address if (load_addr_ptr) @@ -1730,26 +1753,28 @@ size_t Target::ReadMemory(const Address &addr, void *dst, size_t dst_len, addr_t load_addr = LLDB_INVALID_ADDRESS; addr_t file_addr = LLDB_INVALID_ADDRESS; Address resolved_addr; - if (!addr.IsSectionOffset()) { + if (!fixed_addr.IsSectionOffset()) { SectionLoadList §ion_load_list = GetSectionLoadList(); if (section_load_list.IsEmpty()) { // No sections are loaded, so we must assume we are not running yet and // anything we are given is a file address. - file_addr = addr.GetOffset(); // "addr" doesn't have a section, so its - // offset is the file address + file_addr = + fixed_addr.GetOffset(); // "fixed_addr" doesn't have a section, so + // its offset is the file address m_images.ResolveFileAddress(file_addr, resolved_addr); } else { // We have at least one section loaded. This can be because we have // manually loaded some sections with "target modules load ..." or // because we have have a live process that has sections loaded through // the dynamic loader - load_addr = addr.GetOffset(); // "addr" doesn't have a section, so its - // offset is the load address + load_addr = + fixed_addr.GetOffset(); // "fixed_addr" doesn't have a section, so + // its offset is the load address section_load_list.ResolveLoadAddress(load_addr, resolved_addr); } } if (!resolved_addr.IsValid()) - resolved_addr = addr; + resolved_addr = fixed_addr; // 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 @@ -2187,8 +2212,7 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &module_spec, bool notify, // In the meantime, just log that this has happened; just // above we called ReplaceModule on the first one, and Remove // on the rest. - if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET | - LIBLLDB_LOG_MODULES)) { + if (Log *log = GetLog(LLDBLog::Target | LLDBLog::Modules)) { StreamString message; auto dump = [&message](Module &dump_module) -> void { UUID dump_uuid = dump_module.GetUUID(); @@ -2305,8 +2329,7 @@ std::vector<TypeSystem *> Target::GetScratchTypeSystems(bool create_on_demand) { auto type_system_or_err = GetScratchTypeSystemForLanguage(language, create_on_demand); if (!type_system_or_err) - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET), - type_system_or_err.takeError(), + LLDB_LOG_ERROR(GetLog(LLDBLog::Target), type_system_or_err.takeError(), "Language '{}' has expression support but no scratch type " "system available", Language::GetNameForLanguageType(language)); @@ -2322,8 +2345,7 @@ Target::GetPersistentExpressionStateForLanguage(lldb::LanguageType language) { auto type_system_or_err = GetScratchTypeSystemForLanguage(language, true); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET), - std::move(err), + LLDB_LOG_ERROR(GetLog(LLDBLog::Target), std::move(err), "Unable to get persistent expression state for language {}", Language::GetNameForLanguageType(language)); return nullptr; @@ -2421,7 +2443,7 @@ ArchSpec Target::GetDefaultArchitecture() { } void Target::SetDefaultArchitecture(const ArchSpec &arch) { - LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET), + LLDB_LOG(GetLog(LLDBLog::Target), "setting target's default architecture to {0} ({1})", arch.GetArchitectureName(), arch.GetTriple().getTriple()); Target::GetGlobalProperties().SetDefaultArchitecture(arch); @@ -2480,8 +2502,8 @@ ExpressionResults Target::EvaluateExpression( auto type_system_or_err = GetScratchTypeSystemForLanguage(eLanguageTypeC); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET), - std::move(err), "Unable to get scratch type system"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Target), std::move(err), + "Unable to get scratch type system"); } else { persistent_var_sp = type_system_or_err->GetPersistentExpressionState()->GetVariable(expr); @@ -2811,7 +2833,7 @@ bool Target::RunStopHooks() { // We only compute should_stop against the hook results if a hook got to run // which is why we have to do this conjoint test. if ((hooks_ran && !should_stop) || auto_continue) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); Status error = m_process_sp->PrivateResume(); if (error.Success()) { LLDB_LOG(log, "Resuming from RunStopHooks"); @@ -2967,7 +2989,7 @@ void Target::ClearAllLoadedSections() { m_section_load_history.Clear(); } Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) { m_stats.SetLaunchOrAttachTime(); Status error; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET)); + Log *log = GetLog(LLDBLog::Target); LLDB_LOGF(log, "Target::%s() called for %s", __FUNCTION__, launch_info.GetExecutableFile().GetPath().c_str()); @@ -3029,6 +3051,14 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) { if (!launch_info.GetArchitecture().IsValid()) launch_info.GetArchitecture() = GetArchitecture(); + // Hijacking events of the process to be created to be sure that all events + // until the first stop are intercepted (in case if platform doesn't define + // its own hijacking listener or if the process is created by the target + // manually, without the platform). + if (!launch_info.GetHijackListener()) + launch_info.SetHijackListener( + Listener::MakeListener("lldb.Target.Launch.hijack")); + // 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 && @@ -3060,8 +3090,10 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) { } // Since we didn't have a platform launch the process, launch it here. - if (m_process_sp) + if (m_process_sp) { + m_process_sp->HijackProcessEvents(launch_info.GetHijackListener()); error = m_process_sp->Launch(launch_info); + } } if (!m_process_sp && error.Success()) @@ -3070,35 +3102,35 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) { if (!error.Success()) return error; - auto at_exit = - llvm::make_scope_exit([&]() { m_process_sp->RestoreProcessEvents(); }); + bool rebroadcast_first_stop = + !synchronous_execution && + launch_info.GetFlags().Test(eLaunchFlagStopAtEntry); - if (!synchronous_execution && - launch_info.GetFlags().Test(eLaunchFlagStopAtEntry)) - return error; + assert(launch_info.GetHijackListener()); - ListenerSP hijack_listener_sp(launch_info.GetHijackListener()); - if (!hijack_listener_sp) { - hijack_listener_sp = Listener::MakeListener("lldb.Target.Launch.hijack"); - launch_info.SetHijackListener(hijack_listener_sp); - m_process_sp->HijackProcessEvents(hijack_listener_sp); + EventSP first_stop_event_sp; + state = m_process_sp->WaitForProcessToStop(llvm::None, &first_stop_event_sp, + rebroadcast_first_stop, + launch_info.GetHijackListener()); + m_process_sp->RestoreProcessEvents(); + + if (rebroadcast_first_stop) { + assert(first_stop_event_sp); + m_process_sp->BroadcastEvent(first_stop_event_sp); + return error; } - switch (m_process_sp->WaitForProcessToStop(llvm::None, nullptr, false, - hijack_listener_sp, nullptr)) { + switch (state) { case eStateStopped: { if (launch_info.GetFlags().Test(eLaunchFlagStopAtEntry)) break; - if (synchronous_execution) { + if (synchronous_execution) // Now we have handled the stop-from-attach, and we are just // switching to a synchronous resume. So we should switch to the // SyncResume hijacker. - m_process_sp->RestoreProcessEvents(); m_process_sp->ResumeSynchronous(stream); - } else { - m_process_sp->RestoreProcessEvents(); + else error = m_process_sp->PrivateResume(); - } if (!error.Success()) { Status error2; error2.SetErrorStringWithFormat( @@ -3252,7 +3284,7 @@ Status Target::Attach(ProcessAttachInfo &attach_info, Stream *stream) { } void Target::FinalizeFileActions(ProcessLaunchInfo &info) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); // Finalize the file actions, and if none were given, default to opening up a // pseudo terminal @@ -3330,6 +3362,130 @@ void Target::FinalizeFileActions(ProcessLaunchInfo &info) { } } +void Target::AddDummySignal(llvm::StringRef name, LazyBool pass, LazyBool notify, + LazyBool stop) { + if (name.empty()) + return; + // Don't add a signal if all the actions are trivial: + if (pass == eLazyBoolCalculate && notify == eLazyBoolCalculate + && stop == eLazyBoolCalculate) + return; + + auto& elem = m_dummy_signals[name]; + elem.pass = pass; + elem.notify = notify; + elem.stop = stop; +} + +bool Target::UpdateSignalFromDummy(UnixSignalsSP signals_sp, + const DummySignalElement &elem) { + if (!signals_sp) + return false; + + int32_t signo + = signals_sp->GetSignalNumberFromName(elem.first().str().c_str()); + if (signo == LLDB_INVALID_SIGNAL_NUMBER) + return false; + + if (elem.second.pass == eLazyBoolYes) + signals_sp->SetShouldSuppress(signo, false); + else if (elem.second.pass == eLazyBoolNo) + signals_sp->SetShouldSuppress(signo, true); + + if (elem.second.notify == eLazyBoolYes) + signals_sp->SetShouldNotify(signo, true); + else if (elem.second.notify == eLazyBoolNo) + signals_sp->SetShouldNotify(signo, false); + + if (elem.second.stop == eLazyBoolYes) + signals_sp->SetShouldStop(signo, true); + else if (elem.second.stop == eLazyBoolNo) + signals_sp->SetShouldStop(signo, false); + return true; +} + +bool Target::ResetSignalFromDummy(UnixSignalsSP signals_sp, + const DummySignalElement &elem) { + if (!signals_sp) + return false; + int32_t signo + = signals_sp->GetSignalNumberFromName(elem.first().str().c_str()); + if (signo == LLDB_INVALID_SIGNAL_NUMBER) + return false; + bool do_pass = elem.second.pass != eLazyBoolCalculate; + bool do_stop = elem.second.stop != eLazyBoolCalculate; + bool do_notify = elem.second.notify != eLazyBoolCalculate; + signals_sp->ResetSignal(signo, do_stop, do_notify, do_pass); + return true; +} + +void Target::UpdateSignalsFromDummy(UnixSignalsSP signals_sp, + StreamSP warning_stream_sp) { + if (!signals_sp) + return; + + for (const auto &elem : m_dummy_signals) { + if (!UpdateSignalFromDummy(signals_sp, elem)) + warning_stream_sp->Printf("Target signal '%s' not found in process\n", + elem.first().str().c_str()); + } +} + +void Target::ClearDummySignals(Args &signal_names) { + ProcessSP process_sp = GetProcessSP(); + // The simplest case, delete them all with no process to update. + if (signal_names.GetArgumentCount() == 0 && !process_sp) { + m_dummy_signals.clear(); + return; + } + UnixSignalsSP signals_sp; + if (process_sp) + signals_sp = process_sp->GetUnixSignals(); + + for (const Args::ArgEntry &entry : signal_names) { + const char *signal_name = entry.c_str(); + auto elem = m_dummy_signals.find(signal_name); + // If we didn't find it go on. + // FIXME: Should I pipe error handling through here? + if (elem == m_dummy_signals.end()) { + continue; + } + if (signals_sp) + ResetSignalFromDummy(signals_sp, *elem); + m_dummy_signals.erase(elem); + } +} + +void Target::PrintDummySignals(Stream &strm, Args &signal_args) { + strm.Printf("NAME PASS STOP NOTIFY\n"); + strm.Printf("=========== ======= ======= =======\n"); + + auto str_for_lazy = [] (LazyBool lazy) -> const char * { + switch (lazy) { + case eLazyBoolCalculate: return "not set"; + case eLazyBoolYes: return "true "; + case eLazyBoolNo: return "false "; + } + llvm_unreachable("Fully covered switch above!"); + }; + size_t num_args = signal_args.GetArgumentCount(); + for (const auto &elem : m_dummy_signals) { + bool print_it = false; + for (size_t idx = 0; idx < num_args; idx++) { + if (elem.first() == signal_args.GetArgumentAtIndex(idx)) { + print_it = true; + break; + } + } + if (print_it) { + strm.Printf("%-11s ", elem.first().str().c_str()); + strm.Printf("%s %s %s\n", str_for_lazy(elem.second.pass), + str_for_lazy(elem.second.stop), + str_for_lazy(elem.second.notify)); + } + } +} + // Target::StopHook Target::StopHook::StopHook(lldb::TargetSP target_sp, lldb::user_id_t uid) : UserID(uid), m_target_sp(target_sp), m_specifier_sp(), @@ -3645,6 +3801,22 @@ static constexpr OptionEnumValueElement g_import_std_module_value_types[] = { }, }; +static constexpr OptionEnumValueElement + g_dynamic_class_info_helper_value_types[] = { + { + eDynamicClassInfoHelperAuto, + "auto", + "Automatically determine the most appropriate method for the " + "target OS.", + }, + {eDynamicClassInfoHelperRealizedClassesStruct, "RealizedClassesStruct", + "Prefer using the realized classes struct."}, + {eDynamicClassInfoHelperCopyRealizedClassList, "CopyRealizedClassList", + "Prefer using the CopyRealizedClassList API."}, + {eDynamicClassInfoHelperGetRealizedClassList, "GetRealizedClassList", + "Prefer using the GetRealizedClassList API."}, +}; + static constexpr OptionEnumValueElement g_hex_immediate_style_values[] = { { Disassembler::eHexStyleC, @@ -3807,6 +3979,8 @@ TargetProperties::TargetProperties(Target *target) m_collection_sp->SetValueChangedCallback( ePropertyDisableSTDIO, [this] { DisableSTDIOValueChangedCallback(); }); + m_collection_sp->SetValueChangedCallback( + ePropertySaveObjectsDir, [this] { CheckJITObjectsDir(); }); m_experimental_properties_up = std::make_unique<TargetExperimentalProperties>(); m_collection_sp->AppendProperty( @@ -3828,6 +4002,8 @@ TargetProperties::TargetProperties(Target *target) m_collection_sp->AppendProperty( ConstString("process"), ConstString("Settings specific to processes."), true, Process::GetGlobalProperties().GetValueProperties()); + m_collection_sp->SetValueChangedCallback( + ePropertySaveObjectsDir, [this] { CheckJITObjectsDir(); }); } } @@ -4139,6 +4315,13 @@ ImportStdModule TargetProperties::GetImportStdModule() const { nullptr, idx, g_target_properties[idx].default_uint_value); } +DynamicClassInfoHelper TargetProperties::GetDynamicClassInfoHelper() const { + const uint32_t idx = ePropertyDynamicClassInfoHelper; + return (DynamicClassInfoHelper) + m_collection_sp->GetPropertyAtIndexAsEnumeration( + nullptr, idx, g_target_properties[idx].default_uint_value); +} + bool TargetProperties::GetEnableAutoApplyFixIts() const { const uint32_t idx = ePropertyAutoApplyFixIts; return m_collection_sp->GetPropertyAtIndexAsBoolean( @@ -4157,10 +4340,42 @@ bool TargetProperties::GetEnableNotifyAboutFixIts() const { nullptr, idx, g_target_properties[idx].default_uint_value != 0); } -bool TargetProperties::GetEnableSaveObjects() const { - const uint32_t idx = ePropertySaveObjects; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_target_properties[idx].default_uint_value != 0); +FileSpec TargetProperties::GetSaveJITObjectsDir() const { + const uint32_t idx = ePropertySaveObjectsDir; + return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx); +} + +void TargetProperties::CheckJITObjectsDir() { + FileSpec new_dir = GetSaveJITObjectsDir(); + if (!new_dir) + return; + + const FileSystem &instance = FileSystem::Instance(); + bool exists = instance.Exists(new_dir); + bool is_directory = instance.IsDirectory(new_dir); + std::string path = new_dir.GetPath(true); + bool writable = llvm::sys::fs::can_write(path); + if (exists && is_directory && writable) + return; + + m_collection_sp->GetPropertyAtIndex(nullptr, true, ePropertySaveObjectsDir) + ->GetValue() + ->Clear(); + + std::string buffer; + llvm::raw_string_ostream os(buffer); + os << "JIT object dir '" << path << "' "; + if (!exists) + os << "does not exist"; + else if (!is_directory) + os << "is not a directory"; + else if (!writable) + os << "is not writable"; + + llvm::Optional<lldb::user_id_t> debugger_id = llvm::None; + if (m_target) + debugger_id = m_target->GetDebugger().GetID(); + Debugger::ReportError(os.str(), debugger_id); } bool TargetProperties::GetEnableSyntheticValue() const { @@ -4181,6 +4396,15 @@ uint32_t TargetProperties::GetMaximumNumberOfChildrenToDisplay() const { nullptr, idx, g_target_properties[idx].default_uint_value); } +std::pair<uint32_t, bool> +TargetProperties::GetMaximumDepthOfChildrenToDisplay() const { + const uint32_t idx = ePropertyMaxChildrenDepth; + auto *option_value = + m_collection_sp->GetPropertyAtIndexAsOptionValueUInt64(nullptr, idx); + bool is_default = !option_value->OptionWasSet(); + return {option_value->GetCurrentValue(), is_default}; +} + uint32_t TargetProperties::GetMaximumSizeOfStringSummary() const { const uint32_t idx = ePropertyMaxSummaryLength; return m_collection_sp->GetPropertyAtIndexAsSInt64( diff --git a/contrib/llvm-project/lldb/source/Target/TargetList.cpp b/contrib/llvm-project/lldb/source/Target/TargetList.cpp index 595799cfc92a..214e98ee91ed 100644 --- a/contrib/llvm-project/lldb/source/Target/TargetList.cpp +++ b/contrib/llvm-project/lldb/source/Target/TargetList.cpp @@ -79,8 +79,9 @@ Status TargetList::CreateTargetInternal( const OptionGroupPlatform *platform_options, TargetSP &target_sp) { Status error; + PlatformList &platform_list = debugger.GetPlatformList(); // Let's start by looking at the selected platform. - PlatformSP platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); + PlatformSP platform_sp = platform_list.GetSelectedPlatform(); // This variable corresponds to the architecture specified by the triple // string. If that string was empty the currently selected platform will @@ -120,6 +121,14 @@ Status TargetList::CreateTargetInternal( if (!user_exe_path.empty()) { ModuleSpec module_spec(FileSpec(user_exe_path, FileSpec::Style::native)); FileSystem::Instance().Resolve(module_spec.GetFileSpec()); + + // Try to resolve the exe based on PATH and/or platform-specific suffixes, + // but only if using the host platform. + if (platform_sp->IsHost() && + !FileSystem::Instance().Exists(module_spec.GetFileSpec())) + FileSystem::Instance().ResolveExecutableLocation( + module_spec.GetFileSpec()); + // Resolve the executable in case we are given a path to a application // bundle like a .app bundle on MacOSX. Host::ResolveExecutableInBundle(module_spec.GetFileSpec()); @@ -171,80 +180,30 @@ Status TargetList::CreateTargetInternal( } else { // Fat binary. No architecture specified, check if there is // only one platform for all of the architectures. - PlatformSP host_platform_sp = Platform::GetHostPlatform(); - std::vector<PlatformSP> platforms; - for (size_t i = 0; i < num_specs; ++i) { - ModuleSpec module_spec; - if (module_specs.GetModuleSpecAtIndex(i, module_spec)) { - // First consider the platform specified by the user, if any, and - // the selected platform otherwise. - if (platform_sp) { - if (platform_sp->IsCompatibleArchitecture( - module_spec.GetArchitecture(), false, nullptr)) { - platforms.push_back(platform_sp); - continue; - } - } - - // Now consider the host platform if it is different from the - // specified/selected platform. - if (host_platform_sp && - (!platform_sp || - host_platform_sp->GetName() != platform_sp->GetName())) { - if (host_platform_sp->IsCompatibleArchitecture( - module_spec.GetArchitecture(), false, nullptr)) { - platforms.push_back(host_platform_sp); - continue; - } - } - - // Finally find a platform that matches the architecture in the - // executable file. - PlatformSP fallback_platform_sp( - Platform::GetPlatformForArchitecture( - module_spec.GetArchitecture(), nullptr)); - if (fallback_platform_sp) { - platforms.push_back(fallback_platform_sp); - } - } - } - - Platform *platform_ptr = nullptr; - bool more_than_one_platforms = false; - for (const auto &the_platform_sp : platforms) { - if (platform_ptr) { - if (platform_ptr->GetName() != the_platform_sp->GetName()) { - more_than_one_platforms = true; - platform_ptr = nullptr; - break; - } - } else { - platform_ptr = the_platform_sp.get(); - } - } - - if (platform_ptr) { - // All platforms for all modules in the executable match, so we can - // select this platform. - platform_sp = platforms.front(); - } else if (!more_than_one_platforms) { - // No platforms claim to support this file. + std::vector<PlatformSP> candidates; + std::vector<ArchSpec> archs; + for (const ModuleSpec &spec : module_specs.ModuleSpecs()) + archs.push_back(spec.GetArchitecture()); + if (PlatformSP platform_for_archs_sp = + platform_list.GetOrCreate(archs, {}, candidates)) { + platform_sp = platform_for_archs_sp; + } else if (candidates.empty()) { error.SetErrorString("no matching platforms found for this file"); return error; } else { // More than one platform claims to support this file. StreamString error_strm; - std::set<Platform *> platform_set; + std::set<llvm::StringRef> platform_set; error_strm.Printf( "more than one platform supports this executable ("); - for (const auto &the_platform_sp : platforms) { - if (platform_set.find(the_platform_sp.get()) == - platform_set.end()) { - if (!platform_set.empty()) - error_strm.PutCString(", "); - error_strm.PutCString(the_platform_sp->GetName().GetCString()); - platform_set.insert(the_platform_sp.get()); - } + for (const auto &candidate : candidates) { + llvm::StringRef platform_name = candidate->GetName(); + if (platform_set.count(platform_name)) + continue; + if (!platform_set.empty()) + error_strm.PutCString(", "); + error_strm.PutCString(platform_name); + platform_set.insert(platform_name); } error_strm.Printf("), specify an architecture to disambiguate"); error.SetErrorString(error_strm.GetString()); @@ -257,20 +216,20 @@ Status TargetList::CreateTargetInternal( // If we have a valid architecture, make sure the current platform is // compatible with that architecture. if (!prefer_platform_arch && arch.IsValid()) { - if (!platform_sp->IsCompatibleArchitecture(arch, false, nullptr)) { - platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch); + if (!platform_sp->IsCompatibleArchitecture(arch, {}, false, nullptr)) { + platform_sp = platform_list.GetOrCreate(arch, {}, &platform_arch); if (platform_sp) - debugger.GetPlatformList().SetSelectedPlatform(platform_sp); + platform_list.SetSelectedPlatform(platform_sp); } } else if (platform_arch.IsValid()) { // If "arch" isn't valid, yet "platform_arch" is, it means we have an // executable file with a single architecture which should be used. ArchSpec fixed_platform_arch; - if (!platform_sp->IsCompatibleArchitecture(platform_arch, false, nullptr)) { - platform_sp = Platform::GetPlatformForArchitecture(platform_arch, - &fixed_platform_arch); + if (!platform_sp->IsCompatibleArchitecture(platform_arch, {}, false, nullptr)) { + platform_sp = + platform_list.GetOrCreate(platform_arch, {}, &fixed_platform_arch); if (platform_sp) - debugger.GetPlatformList().SetSelectedPlatform(platform_sp); + platform_list.SetSelectedPlatform(platform_sp); } } @@ -298,8 +257,9 @@ Status TargetList::CreateTargetInternal(Debugger &debugger, if (arch.IsValid()) { if (!platform_sp || - !platform_sp->IsCompatibleArchitecture(arch, false, nullptr)) - platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch); + !platform_sp->IsCompatibleArchitecture(arch, {}, false, nullptr)) + platform_sp = + debugger.GetPlatformList().GetOrCreate(specified_arch, {}, &arch); } if (!platform_sp) diff --git a/contrib/llvm-project/lldb/source/Target/TargetProperties.td b/contrib/llvm-project/lldb/source/Target/TargetProperties.td index 063ba0a6c25a..acee09ca0469 100644 --- a/contrib/llvm-project/lldb/source/Target/TargetProperties.td +++ b/contrib/llvm-project/lldb/source/Target/TargetProperties.td @@ -54,6 +54,10 @@ let Definition = "target" in { EnumValues<"OptionEnumValues(g_import_std_module_value_types)">, Desc<"Import the 'std' C++ module to improve expression parsing involving " " C++ standard library types.">; + def DynamicClassInfoHelper: Property<"objc-dynamic-class-extractor", "Enum">, + DefaultEnumValue<"eDynamicClassInfoHelperAuto">, + EnumValues<"OptionEnumValues(g_dynamic_class_info_helper_value_types)">, + Desc<"Configure how LLDB parses dynamic Objective-C class metadata. By default LLDB will choose the most appropriate method for the target OS.">; def AutoApplyFixIts: Property<"auto-apply-fixits", "Boolean">, DefaultTrue, Desc<"Automatically apply fix-it hints to expressions.">; @@ -63,15 +67,18 @@ let Definition = "target" in { def NotifyAboutFixIts: Property<"notify-about-fixits", "Boolean">, DefaultTrue, Desc<"Print the fixed expression text.">; - def SaveObjects: Property<"save-jit-objects", "Boolean">, - DefaultFalse, - Desc<"Save intermediate object files generated by the LLVM JIT">; + def SaveObjectsDir: Property<"save-jit-objects-dir", "FileSpec">, + DefaultStringValue<"">, + Desc<"If specified, the directory to save intermediate object files generated by the LLVM JIT">; def MaxZeroPaddingInFloatFormat: Property<"max-zero-padding-in-float-format", "UInt64">, DefaultUnsignedValue<6>, Desc<"The maximum number of zeroes to insert when displaying a very small float before falling back to scientific notation.">; def MaxChildrenCount: Property<"max-children-count", "SInt64">, DefaultUnsignedValue<256>, Desc<"Maximum number of children to expand in any level of depth.">; + def MaxChildrenDepth: Property<"max-children-depth", "UInt64">, + DefaultUnsignedValue<0xFFFFFFFF>, + Desc<"Maximum depth to expand children.">; def MaxSummaryLength: Property<"max-string-summary-length", "SInt64">, DefaultUnsignedValue<1024>, Desc<"Maximum number of characters to show when using %s in summary strings.">; @@ -223,7 +230,7 @@ let Definition = "process" in { def StopOnExec: Property<"stop-on-exec", "Boolean">, Global, DefaultTrue, - Desc<"If true, stop when a shared library is loaded or unloaded.">; + Desc<"If true, stop when the inferior exec's.">; def UtilityExpressionTimeout: Property<"utility-expression-timeout", "UInt64">, DefaultUnsignedValue<15>, Desc<"The time in seconds to wait for LLDB-internal utility expressions.">; @@ -274,6 +281,6 @@ let Definition = "thread" in { DefaultFalse, Desc<"If true, this thread will single-step and log execution.">; def MaxBacktraceDepth: Property<"max-backtrace-depth", "UInt64">, - DefaultUnsignedValue<300000>, + DefaultUnsignedValue<600000>, Desc<"Maximum number of frames to backtrace.">; } diff --git a/contrib/llvm-project/lldb/source/Target/Thread.cpp b/contrib/llvm-project/lldb/source/Target/Thread.cpp index bde6dad554e7..3803748be297 100644 --- a/contrib/llvm-project/lldb/source/Target/Thread.cpp +++ b/contrib/llvm-project/lldb/source/Target/Thread.cpp @@ -44,6 +44,7 @@ #include "lldb/Target/ThreadPlanStepUntil.h" #include "lldb/Target/ThreadSpec.h" #include "lldb/Target/UnwindLLDB.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/State.h" @@ -229,7 +230,7 @@ Thread::Thread(Process &process, lldb::tid_t tid, bool use_invalid_index_id) m_unwinder_up(), m_destroy_called(false), m_override_should_notify(eLazyBoolCalculate), m_extended_info_fetched(false), m_extended_info() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); + Log *log = GetLog(LLDBLog::Object); LLDB_LOGF(log, "%p Thread::Thread(tid = 0x%4.4" PRIx64 ")", static_cast<void *>(this), GetID()); @@ -237,7 +238,7 @@ Thread::Thread(Process &process, lldb::tid_t tid, bool use_invalid_index_id) } Thread::~Thread() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); + Log *log = GetLog(LLDBLog::Object); LLDB_LOGF(log, "%p Thread::~Thread(tid = 0x%4.4" PRIx64 ")", static_cast<void *>(this), GetID()); /// If you hit this assert, it means your derived class forgot to call @@ -446,7 +447,7 @@ void Thread::SetStopInfo(const lldb::StopInfoSP &stop_info_sp) { m_stop_info_stop_id = process_sp->GetStopID(); else m_stop_info_stop_id = UINT32_MAX; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); LLDB_LOGF(log, "%p: tid = 0x%" PRIx64 ": stop info = %s (stop_id = %u)", static_cast<void *>(this), GetID(), stop_info_sp ? stop_info_sp->GetDescription() : "<NULL>", @@ -577,7 +578,7 @@ std::string Thread::GetStopDescriptionRaw() { } void Thread::SelectMostRelevantFrame() { - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD); + Log *log = GetLog(LLDBLog::Thread); auto frames_list_sp = GetStackFrameList(); @@ -731,7 +732,7 @@ bool Thread::ShouldStop(Event *event_ptr) { bool should_stop = true; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (GetResumeState() == eStateSuspended) { LLDB_LOGF(log, @@ -956,7 +957,7 @@ Vote Thread::ShouldReportStop(Event *event_ptr) { StateType thread_state = GetResumeState(); StateType temp_thread_state = GetTemporaryResumeState(); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (thread_state == eStateSuspended || thread_state == eStateInvalid) { LLDB_LOGF(log, @@ -988,7 +989,7 @@ Vote Thread::ShouldReportStop(Event *event_ptr) { // the last plan, regardless of whether it is private or not. LLDB_LOGF(log, "Thread::ShouldReportStop() tid = 0x%4.4" PRIx64 - ": returning vote for complete stack's back plan", + ": returning vote for complete stack's back plan", GetID()); return GetPlans().GetCompletedPlan(false)->ShouldReportStop(event_ptr); } else { @@ -1020,7 +1021,7 @@ Vote Thread::ShouldReportRun(Event *event_ptr) { return eVoteNoOpinion; } - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (GetPlans().AnyCompletedPlans()) { // Pass skip_private = false to GetCompletedPlan, since we want to ask // the last plan, regardless of whether it is private or not. @@ -1067,7 +1068,7 @@ ThreadPlanStack &Thread::GetPlans() const { void Thread::PushPlan(ThreadPlanSP thread_plan_sp) { assert(thread_plan_sp && "Don't push an empty thread plan."); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (log) { StreamString s; thread_plan_sp->GetDescription(&s, lldb::eDescriptionLevelFull); @@ -1080,7 +1081,7 @@ void Thread::PushPlan(ThreadPlanSP thread_plan_sp) { } void Thread::PopPlan() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); ThreadPlanSP popped_plan_sp = GetPlans().PopPlan(); if (log) { LLDB_LOGF(log, "Popping plan: \"%s\", tid = 0x%4.4" PRIx64 ".", @@ -1089,8 +1090,8 @@ void Thread::PopPlan() { } void Thread::DiscardPlan() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); - ThreadPlanSP discarded_plan_sp = GetPlans().PopPlan(); + Log *log = GetLog(LLDBLog::Step); + ThreadPlanSP discarded_plan_sp = GetPlans().DiscardPlan(); LLDB_LOGF(log, "Discarding plan: \"%s\", tid = 0x%4.4" PRIx64 ".", discarded_plan_sp->GetName(), @@ -1192,7 +1193,7 @@ void Thread::DiscardThreadPlansUpToPlan(lldb::ThreadPlanSP &up_to_plan_sp) { } void Thread::DiscardThreadPlansUpToPlan(ThreadPlan *up_to_plan_ptr) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); LLDB_LOGF(log, "Discarding thread plans for thread tid = 0x%4.4" PRIx64 ", up to %p", @@ -1201,7 +1202,7 @@ void Thread::DiscardThreadPlansUpToPlan(ThreadPlan *up_to_plan_ptr) { } void Thread::DiscardThreadPlans(bool force) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (log) { LLDB_LOGF(log, "Discarding thread plans for thread (tid = 0x%4.4" PRIx64 @@ -1952,7 +1953,7 @@ Status Thread::StepOver(bool source_step, return error; } -Status Thread::StepOut() { +Status Thread::StepOut(uint32_t frame_idx) { Status error; Process *process = GetProcess().get(); if (StateIsStoppedState(process->GetState(), true)) { @@ -1962,7 +1963,7 @@ Status Thread::StepOut() { ThreadPlanSP new_plan_sp(QueueThreadPlanForStepOut( abort_other_plans, nullptr, first_instruction, stop_other_threads, - eVoteYes, eVoteNoOpinion, 0, error)); + eVoteYes, eVoteNoOpinion, frame_idx, error)); new_plan_sp->SetIsControllingPlan(true); new_plan_sp->SetOkayToDiscard(false); diff --git a/contrib/llvm-project/lldb/source/Target/ThreadList.cpp b/contrib/llvm-project/lldb/source/Target/ThreadList.cpp index df2cc8ef6328..7359bfcd3cfc 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadList.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadList.cpp @@ -16,6 +16,7 @@ #include "lldb/Target/ThreadList.h" #include "lldb/Target/ThreadPlan.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/State.h" @@ -225,7 +226,7 @@ ThreadSP ThreadList::FindThreadByIndexID(uint32_t index_id, bool can_update) { bool ThreadList::ShouldStop(Event *event_ptr) { // Running events should never stop, obviously... - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); // The ShouldStop method of the threads can do a whole lot of work, figuring // out whether the thread plan conditions are met. So we don't want to keep @@ -360,7 +361,7 @@ Vote ThreadList::ShouldReportStop(Event *event_ptr) { m_process->UpdateThreadListIfNeeded(); collection::iterator pos, end = m_threads.end(); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); LLDB_LOGF(log, "ThreadList::%s %" PRIu64 " threads", __FUNCTION__, (uint64_t)m_threads.size()); @@ -416,7 +417,7 @@ Vote ThreadList::ShouldReportRun(Event *event_ptr) { // Run through the threads and ask whether we should report this event. The // rule is NO vote wins over everything, a YES vote wins over no opinion. - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); for (pos = m_threads.begin(); pos != end; ++pos) { if ((*pos)->GetResumeState() != eStateSuspended) { @@ -460,7 +461,7 @@ void ThreadList::RefreshStateAfterStop() { m_process->UpdateThreadListIfNeeded(); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (log && log->GetVerbose()) LLDB_LOGF(log, "Turning off notification of new threads while single stepping " @@ -514,13 +515,13 @@ bool ThreadList::WillResume() { } if (wants_solo_run) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (log && log->GetVerbose()) LLDB_LOGF(log, "Turning on notification of new threads while single " "stepping a thread."); m_process->StartNoticingNewThreads(); } else { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (log && log->GetVerbose()) LLDB_LOGF(log, "Turning off notification of new threads while single " "stepping a thread."); diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlan.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlan.cpp index 3b42831f1fbf..9913ecb591fa 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlan.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlan.cpp @@ -12,6 +12,7 @@ #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/State.h" @@ -76,7 +77,7 @@ bool ThreadPlan::MischiefManaged() { } Vote ThreadPlan::ShouldReportStop(Event *event_ptr) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (m_report_stop_vote == eVoteNoOpinion) { ThreadPlan *prev_plan = GetPreviousPlan(); @@ -116,7 +117,7 @@ bool ThreadPlan::WillResume(StateType resume_state, bool current_plan) { m_cached_plan_explains_stop = eLazyBoolCalculate; if (current_plan) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (log) { RegisterContext *reg_ctx = GetThread().GetRegisterContext().get(); @@ -195,7 +196,7 @@ bool ThreadPlanNull::ValidatePlan(Stream *error) { ", ptid = 0x%" PRIx64 ")", LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID()); #else - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); if (log) log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", @@ -211,7 +212,7 @@ bool ThreadPlanNull::ShouldStop(Event *event_ptr) { ", ptid = 0x%" PRIx64 ")", LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID()); #else - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); if (log) log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", @@ -227,7 +228,7 @@ bool ThreadPlanNull::WillStop() { ", ptid = 0x%" PRIx64 ")", LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID()); #else - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); if (log) log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", @@ -243,7 +244,7 @@ bool ThreadPlanNull::DoPlanExplainsStop(Event *event_ptr) { ", ptid = 0x%" PRIx64 ")", LLVM_PRETTY_FUNCTION, GetThread().GetID(), GetThread().GetProtocolID()); #else - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); if (log) log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", @@ -261,7 +262,7 @@ bool ThreadPlanNull::MischiefManaged() { ", ptid = 0x%" PRIx64 ")", LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID()); #else - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); if (log) log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", @@ -278,7 +279,7 @@ lldb::StateType ThreadPlanNull::GetPlanRunState() { ", ptid = 0x%" PRIx64 ")", LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID()); #else - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); if (log) log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanBase.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanBase.cpp index 46ae9c32a0de..dfd2157e70d4 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanBase.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanBase.cpp @@ -16,6 +16,7 @@ #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/StopInfo.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Stream.h" @@ -73,7 +74,7 @@ bool ThreadPlanBase::ShouldStop(Event *event_ptr) { m_report_stop_vote = eVoteYes; m_report_run_vote = eVoteYes; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); StopInfoSP stop_info_sp = GetPrivateStopInfo(); if (stop_info_sp) { diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanCallFunction.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanCallFunction.cpp index 0336a9daf10a..a9f774aa6109 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanCallFunction.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanCallFunction.cpp @@ -21,6 +21,7 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlanRunToAddress.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Stream.h" @@ -46,7 +47,7 @@ bool ThreadPlanCallFunction::ConstructorSetup( if (!abi) return false; - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); SetBreakpoints(); @@ -143,7 +144,7 @@ ThreadPlanCallFunction::~ThreadPlanCallFunction() { } void ThreadPlanCallFunction::ReportRegisterState(const char *message) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (log && log->GetVerbose()) { StreamString strm; RegisterContext *reg_ctx = GetThread().GetRegisterContext().get(); @@ -166,7 +167,7 @@ void ThreadPlanCallFunction::ReportRegisterState(const char *message) { } void ThreadPlanCallFunction::DoTakedown(bool success) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (!m_valid) { // Don't call DoTakedown if we were never valid to begin with. @@ -242,8 +243,7 @@ Vote ThreadPlanCallFunction::ShouldReportStop(Event *event_ptr) { } bool ThreadPlanCallFunction::DoPlanExplainsStop(Event *event_ptr) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP | - LIBLLDB_LOG_PROCESS)); + Log *log(GetLog(LLDBLog::Step | LLDBLog::Process)); m_real_stop_info_sp = GetPrivateStopInfo(); // If our subplan knows why we stopped, even if it's done (which would @@ -382,7 +382,7 @@ void ThreadPlanCallFunction::DidPush() { bool ThreadPlanCallFunction::WillStop() { return true; } bool ThreadPlanCallFunction::MischiefManaged() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (IsPlanComplete()) { LLDB_LOGF(log, "ThreadPlanCallFunction(%p): Completed call function plan.", @@ -433,7 +433,7 @@ bool ThreadPlanCallFunction::BreakpointsExplainStop() { (m_objc_language_runtime && m_objc_language_runtime->ExceptionBreakpointsExplainStop( stop_info_sp))) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); LLDB_LOGF(log, "ThreadPlanCallFunction::BreakpointsExplainStop - Hit an " "exception breakpoint, setting plan complete."); diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanCallUserExpression.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanCallUserExpression.cpp index d833a4d7ed27..65758599dcee 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanCallUserExpression.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanCallUserExpression.cpp @@ -8,7 +8,6 @@ #include "lldb/Target/ThreadPlanCallUserExpression.h" - #include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Address.h" @@ -23,6 +22,7 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlanRunToAddress.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Stream.h" @@ -66,7 +66,7 @@ void ThreadPlanCallUserExpression::DidPop() { } bool ThreadPlanCallUserExpression::MischiefManaged() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (IsPlanComplete()) { LLDB_LOGF(log, "ThreadPlanCallFunction(%p): Completed call function plan.", diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanPython.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanPython.cpp index a8a36ae65c46..bc2a7a02e99c 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanPython.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanPython.cpp @@ -17,6 +17,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlan.h" #include "lldb/Target/ThreadPlanPython.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/State.h" @@ -70,7 +71,7 @@ void ThreadPlanPython::DidPush() { } bool ThreadPlanPython::ShouldStop(Event *event_ptr) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); LLDB_LOGF(log, "%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION, m_class_name.c_str()); @@ -89,7 +90,7 @@ bool ThreadPlanPython::ShouldStop(Event *event_ptr) { } bool ThreadPlanPython::IsPlanStale() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); LLDB_LOGF(log, "%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION, m_class_name.c_str()); @@ -108,7 +109,7 @@ bool ThreadPlanPython::IsPlanStale() { } bool ThreadPlanPython::DoPlanExplainsStop(Event *event_ptr) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); LLDB_LOGF(log, "%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION, m_class_name.c_str()); @@ -127,7 +128,7 @@ bool ThreadPlanPython::DoPlanExplainsStop(Event *event_ptr) { } bool ThreadPlanPython::MischiefManaged() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); LLDB_LOGF(log, "%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION, m_class_name.c_str()); bool mischief_managed = true; @@ -142,7 +143,7 @@ bool ThreadPlanPython::MischiefManaged() { } lldb::StateType ThreadPlanPython::GetPlanRunState() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); LLDB_LOGF(log, "%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION, m_class_name.c_str()); lldb::StateType run_state = eStateRunning; @@ -164,7 +165,7 @@ void ThreadPlanPython::GetDescription(Stream *s, lldb::DescriptionLevel level) { } bool ThreadPlanPython::WillStop() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); + Log *log = GetLog(LLDBLog::Thread); LLDB_LOGF(log, "%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION, m_class_name.c_str()); return true; diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanRunToAddress.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanRunToAddress.cpp index cb4a58b1cf25..a2ac8c3d0966 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanRunToAddress.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanRunToAddress.cpp @@ -11,6 +11,7 @@ #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Stream.h" @@ -169,7 +170,7 @@ StateType ThreadPlanRunToAddress::GetPlanRunState() { return eStateRunning; } bool ThreadPlanRunToAddress::WillStop() { return true; } bool ThreadPlanRunToAddress::MischiefManaged() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (AtOurAddress()) { // Remove the breakpoint diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanShouldStopHere.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanShouldStopHere.cpp index 7774e027c056..e72f8d8f51a2 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanShouldStopHere.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanShouldStopHere.cpp @@ -10,6 +10,7 @@ #include "lldb/Symbol/Symbol.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" using namespace lldb; @@ -41,7 +42,7 @@ bool ThreadPlanShouldStopHere::InvokeShouldStopHereCallback( if (m_callbacks.should_stop_here_callback) { should_stop_here = m_callbacks.should_stop_here_callback( m_owner, m_flags, operation, status, m_baton); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (log) { lldb::addr_t current_addr = m_owner->GetThread().GetRegisterContext()->GetPC(0); @@ -62,7 +63,7 @@ bool ThreadPlanShouldStopHere::DefaultShouldStopHereCallback( if (!frame) return true; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if ((operation == eFrameCompareOlder && flags.Test(eStepOutAvoidNoDebug)) || (operation == eFrameCompareYounger && flags.Test(eStepInAvoidNoDebug)) || @@ -98,7 +99,7 @@ ThreadPlanSP ThreadPlanShouldStopHere::DefaultStepFromHereCallback( ThreadPlanSP return_plan_sp; // If we are stepping through code at line number 0, then we need to step // over this range. Otherwise we will step out. - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); StackFrame *frame = current_plan->GetThread().GetStackFrameAtIndex(0).get(); if (!frame) diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanStack.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanStack.cpp index 80634647f9e0..ac7b44cef37d 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanStack.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanStack.cpp @@ -400,6 +400,7 @@ void ThreadPlanStackMap::Update(ThreadList ¤t_threads, bool delete_missing, bool check_for_new) { + std::lock_guard<std::recursive_mutex> guard(m_stack_map_mutex); // Now find all the new threads and add them to the map: if (check_for_new) { for (auto thread : current_threads.Threads()) { @@ -434,6 +435,7 @@ void ThreadPlanStackMap::DumpPlans(Stream &strm, lldb::DescriptionLevel desc_level, bool internal, bool condense_if_trivial, bool skip_unreported) { + std::lock_guard<std::recursive_mutex> guard(m_stack_map_mutex); for (auto &elem : m_plans_list) { lldb::tid_t tid = elem.first; uint32_t index_id = 0; @@ -470,6 +472,7 @@ bool ThreadPlanStackMap::DumpPlansForTID(Stream &strm, lldb::tid_t tid, bool internal, bool condense_if_trivial, bool skip_unreported) { + std::lock_guard<std::recursive_mutex> guard(m_stack_map_mutex); uint32_t index_id = 0; ThreadSP thread_sp = m_process.GetThreadList().FindThreadByID(tid); @@ -509,6 +512,7 @@ bool ThreadPlanStackMap::DumpPlansForTID(Stream &strm, lldb::tid_t tid, bool ThreadPlanStackMap::PrunePlansForTID(lldb::tid_t tid) { // We only remove the plans for unreported TID's. + std::lock_guard<std::recursive_mutex> guard(m_stack_map_mutex); ThreadSP thread_sp = m_process.GetThreadList().FindThreadByID(tid); if (thread_sp) return false; diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepInRange.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepInRange.cpp index 69b4b918d467..17f2100b804f 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepInRange.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepInRange.cpp @@ -18,6 +18,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlanStepOut.h" #include "lldb/Target/ThreadPlanStepThrough.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Stream.h" @@ -125,7 +126,7 @@ void ThreadPlanStepInRange::GetDescription(Stream *s, } bool ThreadPlanStepInRange::ShouldStop(Event *event_ptr) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (log) { StreamString s; @@ -269,7 +270,7 @@ bool ThreadPlanStepInRange::ShouldStop(Event *event_ptr) { if (bytes_to_skip != 0) { func_start_address.Slide(bytes_to_skip); - log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP); + log = GetLog(LLDBLog::Step); LLDB_LOGF(log, "Pushing past prologue "); m_sub_plan_sp = thread.QueueThreadPlanForRunToAddress( @@ -339,17 +340,13 @@ bool ThreadPlanStepInRange::FrameMatchesAvoidCriteria() { sc.GetFunctionName(Mangled::ePreferDemangledWithoutArguments) .GetCString(); if (frame_function_name) { - llvm::SmallVector<llvm::StringRef, 2> matches; - bool return_value = - avoid_regexp_to_use->Execute(frame_function_name, &matches); - if (return_value && matches.size() > 1) { - std::string match = matches[1].str(); - LLDB_LOGF(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP), - "Stepping out of function \"%s\" because it matches " - "the avoid regexp \"%s\" - match substring: \"%s\".", + bool return_value = avoid_regexp_to_use->Execute(frame_function_name); + if (return_value) { + LLDB_LOGF(GetLog(LLDBLog::Step), + "Stepping out of function \"%s\" because it matches the " + "avoid regexp \"%s\".", frame_function_name, - avoid_regexp_to_use->GetText().str().c_str(), - match.c_str()); + avoid_regexp_to_use->GetText().str().c_str()); } return return_value; } @@ -363,7 +360,7 @@ bool ThreadPlanStepInRange::DefaultShouldStopHereCallback( Status &status, void *baton) { bool should_stop_here = true; StackFrame *frame = current_plan->GetThread().GetStackFrameAtIndex(0).get(); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); // First see if the ThreadPlanShouldStopHere default implementation thinks we // should get out of here: @@ -445,7 +442,7 @@ bool ThreadPlanStepInRange::DoPlanExplainsStop(Event *event_ptr) { return_value = true; } } else if (IsUsuallyUnexplainedStopReason(reason)) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (log) log->PutCString("ThreadPlanStepInRange got asked if it explains the " "stop for some reason other than step."); @@ -468,7 +465,7 @@ bool ThreadPlanStepInRange::DoWillResume(lldb::StateType resume_state, // See if we are about to step over a virtual inlined call. bool step_without_resume = thread.DecrementCurrentInlinedDepth(); if (step_without_resume) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); LLDB_LOGF(log, "ThreadPlanStepInRange::DoWillResume: returning false, " "inline_depth: %d", diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepInstruction.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepInstruction.cpp index e34e41e8bce8..42bee79c42bb 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepInstruction.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepInstruction.cpp @@ -9,9 +9,9 @@ #include "lldb/Target/ThreadPlanStepInstruction.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" -#include "lldb/Target/RegisterContext.h" #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Stream.h" @@ -96,7 +96,7 @@ bool ThreadPlanStepInstruction::DoPlanExplainsStop(Event *event_ptr) { } bool ThreadPlanStepInstruction::IsPlanStale() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); Thread &thread = GetThread(); StackID cur_frame_id = thread.GetStackFrameAtIndex(0)->GetStackID(); if (cur_frame_id == m_stack_id) { @@ -128,7 +128,7 @@ bool ThreadPlanStepInstruction::IsPlanStale() { bool ThreadPlanStepInstruction::ShouldStop(Event *event_ptr) { Thread &thread = GetThread(); if (m_step_over) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); StackFrameSP cur_frame_sp = thread.GetStackFrameAtIndex(0); if (!cur_frame_sp) { LLDB_LOGF( @@ -244,7 +244,7 @@ bool ThreadPlanStepInstruction::WillStop() { return true; } bool ThreadPlanStepInstruction::MischiefManaged() { if (IsPlanComplete()) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); LLDB_LOGF(log, "Completed single instruction step plan."); ThreadPlan::MischiefManaged(); return true; diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepOut.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepOut.cpp index 86ccac2ec499..7bf1d2a8b579 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepOut.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepOut.cpp @@ -21,6 +21,7 @@ #include "lldb/Target/Target.h" #include "lldb/Target/ThreadPlanStepOverRange.h" #include "lldb/Target/ThreadPlanStepThrough.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include <memory> @@ -43,7 +44,7 @@ ThreadPlanStepOut::ThreadPlanStepOut( m_return_addr(LLDB_INVALID_ADDRESS), m_stop_others(stop_others), m_immediate_step_from_function(nullptr), m_calculate_return_value(gather_return_value) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); SetFlagsToDefault(); SetupAvoidNoDebug(step_out_avoids_code_without_debug_info); @@ -423,7 +424,7 @@ bool ThreadPlanStepOut::MischiefManaged() { // reason and we're now stopping for some other reason altogether, then // we're done with this step out operation. - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (log) LLDB_LOGF(log, "Completed step out plan."); if (m_return_bp_id != LLDB_INVALID_BREAK_ID) { @@ -447,7 +448,7 @@ bool ThreadPlanStepOut::QueueInlinedStepPlan(bool queue_now) { if (!immediate_return_from_sp) return false; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (log) { StreamString s; immediate_return_from_sp->Dump(&s, true, false); diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp index f007b0fa9371..f88a2b895931 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp @@ -10,6 +10,7 @@ #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Stream.h" @@ -51,7 +52,7 @@ bool ThreadPlanStepOverBreakpoint::DoPlanExplainsStop(Event *event_ptr) { if (stop_info_sp) { StopReason reason = stop_info_sp->GetStopReason(); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); LLDB_LOG(log, "Step over breakpoint stopped for reason: {0}.", Thread::StopReasonAsString(reason)); @@ -134,7 +135,7 @@ bool ThreadPlanStepOverBreakpoint::MischiefManaged() { // didn't get a chance to run. return false; } else { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); LLDB_LOGF(log, "Completed step over breakpoint plan."); // Otherwise, re-enable the breakpoint we were stepping over, and we're // done. diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepOverRange.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepOverRange.cpp index 1bf3d5352c5b..b1cb070e0a3d 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepOverRange.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepOverRange.cpp @@ -17,6 +17,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlanStepOut.h" #include "lldb/Target/ThreadPlanStepThrough.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Stream.h" @@ -124,7 +125,7 @@ bool ThreadPlanStepOverRange::IsEquivalentContext( } bool ThreadPlanStepOverRange::ShouldStop(Event *event_ptr) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); Thread &thread = GetThread(); if (log) { @@ -341,7 +342,7 @@ bool ThreadPlanStepOverRange::DoPlanExplainsStop(Event *event_ptr) { // breakpoint. Note, unlike the step in range plan, we don't mark ourselves // complete if we hit an unexplained breakpoint/crash. - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); StopInfoSP stop_info_sp = GetPrivateStopInfo(); bool return_value; @@ -375,7 +376,7 @@ bool ThreadPlanStepOverRange::DoWillResume(lldb::StateType resume_state, // step over that. bool in_inlined_stack = thread.DecrementCurrentInlinedDepth(); if (in_inlined_stack) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); LLDB_LOGF(log, "ThreadPlanStepInRange::DoWillResume: adjusting range to " "the frame at inlined depth %d.", diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepRange.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepRange.cpp index 896e647bbb52..0d5144d7a46b 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepRange.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepRange.cpp @@ -19,6 +19,7 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlanRunToAddress.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Stream.h" @@ -65,7 +66,7 @@ bool ThreadPlanStepRange::ValidatePlan(Stream *error) { } Vote ThreadPlanStepRange::ShouldReportStop(Event *event_ptr) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); const Vote vote = IsPlanComplete() ? eVoteYes : eVoteNo; LLDB_LOGF(log, "ThreadPlanStepRange::ShouldReportStop() returning vote %i\n", @@ -98,7 +99,7 @@ void ThreadPlanStepRange::DumpRanges(Stream *s) { } bool ThreadPlanStepRange::InRange() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); bool ret_value = false; Thread &thread = GetThread(); lldb::addr_t pc_load_addr = thread.GetRegisterContext()->GetPC(); @@ -293,7 +294,7 @@ InstructionList *ThreadPlanStepRange::GetInstructionsForAddress( void ThreadPlanStepRange::ClearNextBranchBreakpoint() { if (m_next_branch_bp_sp) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); LLDB_LOGF(log, "Removing next branch breakpoint: %d.", m_next_branch_bp_sp->GetID()); GetTarget().RemoveBreakpointByID(m_next_branch_bp_sp->GetID()); @@ -307,7 +308,7 @@ bool ThreadPlanStepRange::SetNextBranchBreakpoint() { if (m_next_branch_bp_sp) return true; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); // Stepping through ranges using breakpoints doesn't work yet, but with this // off we fall back to instruction single stepping. if (!m_use_fast_step) @@ -386,7 +387,7 @@ bool ThreadPlanStepRange::SetNextBranchBreakpoint() { bool ThreadPlanStepRange::NextRangeBreakpointExplainsStop( lldb::StopInfoSP stop_info_sp) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (!m_next_branch_bp_sp) return false; @@ -453,7 +454,7 @@ bool ThreadPlanStepRange::MischiefManaged() { } if (done) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); LLDB_LOGF(log, "Completed step through range plan."); ClearNextBranchBreakpoint(); ThreadPlan::MischiefManaged(); @@ -464,7 +465,7 @@ bool ThreadPlanStepRange::MischiefManaged() { } bool ThreadPlanStepRange::IsPlanStale() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); FrameComparison frame_order = CompareCurrentFrameToStartFrame(); if (frame_order == eFrameCompareOlder) { diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepThrough.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepThrough.cpp index 6fc0312222fb..e15635e40700 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepThrough.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepThrough.cpp @@ -13,6 +13,7 @@ #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Stream.h" @@ -60,7 +61,7 @@ ThreadPlanStepThrough::ThreadPlanStepThrough(Thread &thread, m_backstop_bkpt_id = return_bp->GetID(); return_bp->SetBreakpointKind("step-through-backstop"); } - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (log) { LLDB_LOGF(log, "Setting backstop breakpoint %d at address: 0x%" PRIx64, m_backstop_bkpt_id, m_backstop_addr); @@ -94,7 +95,7 @@ void ThreadPlanStepThrough::LookForPlanToStepThroughFromCurrentPC() { } } - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (log) { lldb::addr_t current_address = GetThread().GetRegisterContext()->GetPC(0); if (m_sub_plan_sp) { @@ -227,7 +228,7 @@ void ThreadPlanStepThrough::ClearBackstopBreakpoint() { } bool ThreadPlanStepThrough::MischiefManaged() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (!IsPlanComplete()) { return false; @@ -252,7 +253,7 @@ bool ThreadPlanStepThrough::HitOurBackstopBreakpoint() { StackID cur_frame_zero_id = thread.GetStackFrameAtIndex(0)->GetStackID(); if (cur_frame_zero_id == m_return_stack_id) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); if (log) log->PutCString("ThreadPlanStepThrough hit backstop breakpoint."); return true; diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepUntil.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepUntil.cpp index 650fa624cd52..f63e97d3c402 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepUntil.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepUntil.cpp @@ -14,6 +14,7 @@ #include "lldb/Target/RegisterContext.h" #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" using namespace lldb; @@ -315,7 +316,7 @@ bool ThreadPlanStepUntil::MischiefManaged() { // here. bool done = false; if (IsPlanComplete()) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); LLDB_LOGF(log, "Completed step until plan."); Clear(); diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanTracer.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanTracer.cpp index 754ce655729c..f2346fc237ce 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanTracer.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanTracer.cpp @@ -25,6 +25,7 @@ #include "lldb/Target/ThreadPlan.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/State.h" @@ -106,10 +107,8 @@ TypeFromUser ThreadPlanAssemblyTracer::GetIntPointerType() { auto type_system_or_err = target_sp->GetScratchTypeSystemForLanguage(eLanguageTypeC); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR( - lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TYPES), - std::move(err), - "Unable to get integer pointer type from TypeSystem"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Types), std::move(err), + "Unable to get integer pointer type from TypeSystem"); } else { m_intptr_type = TypeFromUser( type_system_or_err->GetBuiltinTypeForEncodingAndBitSize( diff --git a/contrib/llvm-project/lldb/source/Target/Trace.cpp b/contrib/llvm-project/lldb/source/Target/Trace.cpp index 38b3a7cb006d..ac832734b8d0 100644 --- a/contrib/llvm-project/lldb/source/Target/Trace.cpp +++ b/contrib/llvm-project/lldb/source/Target/Trace.cpp @@ -17,40 +17,72 @@ #include "lldb/Target/Process.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Stream.h" using namespace lldb; using namespace lldb_private; using namespace llvm; -// Helper structs used to extract the type of a trace session json without -// having to parse the entire object. +// Helper structs used to extract the type of a JSON trace bundle description +// object without having to parse the entire object. -struct JSONSimplePluginSettings { +struct JSONSimpleTraceBundleDescription { std::string type; }; -struct JSONSimpleTraceSession { - JSONSimplePluginSettings trace; -}; - namespace llvm { namespace json { -bool fromJSON(const Value &value, JSONSimplePluginSettings &plugin_settings, +bool fromJSON(const Value &value, JSONSimpleTraceBundleDescription &bundle, Path path) { json::ObjectMapper o(value, path); - return o && o.map("type", plugin_settings.type); -} - -bool fromJSON(const Value &value, JSONSimpleTraceSession &session, Path path) { - json::ObjectMapper o(value, path); - return o && o.map("trace", session.trace); + return o && o.map("type", bundle.type); } } // namespace json } // namespace llvm +/// Helper functions for fetching data in maps and returning Optionals or +/// pointers instead of iterators for simplicity. It's worth mentioning that the +/// Optionals version can't return the inner data by reference because of +/// limitations in move constructors. +/// \{ +template <typename K, typename V> +static Optional<V> Lookup(DenseMap<K, V> &map, K k) { + auto it = map.find(k); + if (it == map.end()) + return None; + return it->second; +} + +template <typename K, typename V> +static V *LookupAsPtr(DenseMap<K, V> &map, K k) { + auto it = map.find(k); + if (it == map.end()) + return nullptr; + return &it->second; +} + +/// Similar to the methods above but it looks for an item in a map of maps. +template <typename K1, typename K2, typename V> +static Optional<V> Lookup(DenseMap<K1, DenseMap<K2, V>> &map, K1 k1, K2 k2) { + auto it = map.find(k1); + if (it == map.end()) + return None; + return Lookup(it->second, k2); +} + +/// Similar to the methods above but it looks for an item in a map of maps. +template <typename K1, typename K2, typename V> +static V *LookupAsPtr(DenseMap<K1, DenseMap<K2, V>> &map, K1 k1, K2 k2) { + auto it = map.find(k1); + if (it == map.end()) + return nullptr; + return LookupAsPtr(it->second, k2); +} +/// \} + static Error createInvalidPlugInError(StringRef plugin_name) { return createStringError( std::errc::invalid_argument, @@ -59,19 +91,42 @@ static Error createInvalidPlugInError(StringRef plugin_name) { } 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)) +Trace::LoadPostMortemTraceFromFile(Debugger &debugger, + const FileSpec &trace_description_file) { + + auto buffer_or_error = + MemoryBuffer::getFile(trace_description_file.GetPath()); + if (!buffer_or_error) { + return createStringError(std::errc::invalid_argument, + "could not open input file: %s - %s.", + trace_description_file.GetPath().c_str(), + buffer_or_error.getError().message().c_str()); + } + + Expected<json::Value> session_file = + json::parse(buffer_or_error.get()->getBuffer().str()); + if (!session_file) { + return session_file.takeError(); + } + + return Trace::FindPluginForPostMortemProcess( + debugger, *session_file, + trace_description_file.GetDirectory().AsCString()); +} + +Expected<lldb::TraceSP> Trace::FindPluginForPostMortemProcess( + Debugger &debugger, const json::Value &trace_bundle_description, + StringRef bundle_dir) { + JSONSimpleTraceBundleDescription json_bundle; + json::Path::Root root("traceBundle"); + if (!json::fromJSON(trace_bundle_description, json_bundle, root)) return root.getError(); if (auto create_callback = - PluginManager::GetTraceCreateCallback(json_session.trace.type)) - return create_callback(trace_session_file, session_file_dir, debugger); + PluginManager::GetTraceCreateCallback(json_bundle.type)) + return create_callback(trace_bundle_description, bundle_dir, debugger); - return createInvalidPlugInError(json_session.trace.type); + return createInvalidPlugInError(json_bundle.type); } Expected<lldb::TraceSP> Trace::FindPluginForLiveProcess(llvm::StringRef name, @@ -97,121 +152,375 @@ Expected<StringRef> Trace::FindPluginSchema(StringRef name) { Error Trace::Start(const llvm::json::Value &request) { if (!m_live_process) - return createStringError(inconvertibleErrorCode(), - "Tracing requires a live process."); + return createStringError( + inconvertibleErrorCode(), + "Attempted to start tracing without a live process."); return m_live_process->TraceStart(request); } Error Trace::Stop() { if (!m_live_process) - return createStringError(inconvertibleErrorCode(), - "Tracing requires a live process."); + return createStringError( + inconvertibleErrorCode(), + "Attempted to stop tracing without a live process."); return m_live_process->TraceStop(TraceStopRequest(GetPluginName())); } Error Trace::Stop(llvm::ArrayRef<lldb::tid_t> tids) { if (!m_live_process) - return createStringError(inconvertibleErrorCode(), - "Tracing requires a live process."); + return createStringError( + inconvertibleErrorCode(), + "Attempted to stop tracing without a live process."); return m_live_process->TraceStop(TraceStopRequest(GetPluginName(), tids)); } Expected<std::string> Trace::GetLiveProcessState() { if (!m_live_process) - return createStringError(inconvertibleErrorCode(), - "Tracing requires a live process."); + return createStringError( + inconvertibleErrorCode(), + "Attempted to fetch live trace information without a live process."); return m_live_process->TraceGetState(GetPluginName()); } -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<uint64_t> Trace::GetLiveThreadBinaryDataSize(lldb::tid_t tid, + llvm::StringRef kind) { + Storage &storage = GetUpdatedStorage(); + return Lookup(storage.live_thread_data, tid, ConstString(kind)); } -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; +Optional<uint64_t> Trace::GetLiveCpuBinaryDataSize(lldb::cpu_id_t cpu_id, + llvm::StringRef kind) { + Storage &storage = GetUpdatedStorage(); + return Lookup(storage.live_cpu_data_sizes, cpu_id, ConstString(kind)); } -Expected<ArrayRef<uint8_t>> -Trace::GetLiveThreadBinaryData(lldb::tid_t tid, llvm::StringRef kind) { +Optional<uint64_t> Trace::GetLiveProcessBinaryDataSize(llvm::StringRef kind) { + Storage &storage = GetUpdatedStorage(); + return Lookup(storage.live_process_data, ConstString(kind)); +} + +Expected<std::vector<uint8_t>> +Trace::GetLiveTraceBinaryData(const TraceGetBinaryDataRequest &request, + uint64_t expected_size) { if (!m_live_process) - return createStringError(inconvertibleErrorCode(), - "Tracing requires a live process."); - llvm::Optional<size_t> size = GetLiveThreadBinaryDataSize(tid, kind); + return createStringError( + inconvertibleErrorCode(), + formatv("Attempted to fetch live trace data without a live process. " + "Data kind = {0}, tid = {1}, cpu id = {2}.", + request.kind, request.tid, request.cpu_id)); + + Expected<std::vector<uint8_t>> data = + m_live_process->TraceGetBinaryData(request); + + if (!data) + return data.takeError(); + + if (data->size() != expected_size) + return createStringError( + inconvertibleErrorCode(), + formatv("Got incomplete live trace data. Data kind = {0}, expected " + "size = {1}, actual size = {2}, tid = {3}, cpu id = {4}", + request.kind, expected_size, data->size(), request.tid, + request.cpu_id)); + + return data; +} + +Expected<std::vector<uint8_t>> +Trace::GetLiveThreadBinaryData(lldb::tid_t tid, llvm::StringRef kind) { + llvm::Optional<uint64_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().str(), kind.str(), tid, + /*cpu_id=*/None}; + return GetLiveTraceBinaryData(request, *size); +} + +Expected<std::vector<uint8_t>> +Trace::GetLiveCpuBinaryData(lldb::cpu_id_t cpu_id, llvm::StringRef kind) { + if (!m_live_process) + return createStringError( + inconvertibleErrorCode(), + "Attempted to fetch live cpu data without a live process."); + llvm::Optional<uint64_t> size = GetLiveCpuBinaryDataSize(cpu_id, kind); + if (!size) + return createStringError( + inconvertibleErrorCode(), + "Tracing data \"%s\" is not available for cpu_id %" PRIu64 ".", + kind.data(), cpu_id); + TraceGetBinaryDataRequest request{GetPluginName().str(), kind.str(), - static_cast<int64_t>(tid), 0, - static_cast<int64_t>(*size)}; + /*tid=*/None, cpu_id}; return m_live_process->TraceGetBinaryData(request); } -Expected<ArrayRef<uint8_t>> +Expected<std::vector<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); + llvm::Optional<uint64_t> size = GetLiveProcessBinaryDataSize(kind); if (!size) return createStringError( inconvertibleErrorCode(), "Tracing data \"%s\" is not available for the process.", kind.data()); - TraceGetBinaryDataRequest request{GetPluginName().str(), kind.str(), None, 0, - static_cast<int64_t>(*size)}; - return m_live_process->TraceGetBinaryData(request); + TraceGetBinaryDataRequest request{GetPluginName().str(), kind.str(), + /*tid=*/None, /*cpu_id*/ None}; + return GetLiveTraceBinaryData(request, *size); +} + +Trace::Storage &Trace::GetUpdatedStorage() { + RefreshLiveProcessState(); + return m_storage; } -void Trace::RefreshLiveProcessState() { +const char *Trace::RefreshLiveProcessState() { if (!m_live_process) - return; + return nullptr; uint32_t new_stop_id = m_live_process->GetStopID(); if (new_stop_id == m_stop_id) - return; + return nullptr; - m_stop_id = new_stop_id; - m_live_thread_data.clear(); + Log *log = GetLog(LLDBLog::Target); + LLDB_LOG(log, "Trace::RefreshLiveProcessState invoked"); - 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; + m_stop_id = new_stop_id; + m_storage = Trace::Storage(); + + auto do_refresh = [&]() -> Error { + Expected<std::string> json_string = GetLiveProcessState(); + if (!json_string) + return json_string.takeError(); + + Expected<TraceGetStateResponse> live_process_state = + json::parse<TraceGetStateResponse>(*json_string, + "TraceGetStateResponse"); + if (!live_process_state) + return live_process_state.takeError(); + + if (live_process_state->warnings) { + for (std::string &warning : *live_process_state->warnings) + LLDB_LOG(log, "== Warning when fetching the trace state: {0}", warning); + } + + for (const TraceThreadState &thread_state : + live_process_state->traced_threads) { + for (const TraceBinaryData &item : thread_state.binary_data) + m_storage.live_thread_data[thread_state.tid].insert( + {ConstString(item.kind), item.size}); + } + + LLDB_LOG(log, "== Found {0} threads being traced", + live_process_state->traced_threads.size()); + + if (live_process_state->cpus) { + m_storage.cpus.emplace(); + for (const TraceCpuState &cpu_state : *live_process_state->cpus) { + m_storage.cpus->push_back(cpu_state.id); + for (const TraceBinaryData &item : cpu_state.binary_data) + m_storage.live_cpu_data_sizes[cpu_state.id].insert( + {ConstString(item.kind), item.size}); + } + LLDB_LOG(log, "== Found {0} cpu cpus being traced", + live_process_state->cpus->size()); + } + + for (const TraceBinaryData &item : live_process_state->process_binary_data) + m_storage.live_process_data.insert({ConstString(item.kind), item.size}); + + return DoRefreshLiveProcessState(std::move(*live_process_state), + *json_string); + }; + + if (Error err = do_refresh()) { + m_storage.live_refresh_error = toString(std::move(err)); + return m_storage.live_refresh_error->c_str(); } - 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; - } + return nullptr; +} + +Trace::Trace(ArrayRef<ProcessSP> postmortem_processes, + Optional<std::vector<lldb::cpu_id_t>> postmortem_cpus) { + for (ProcessSP process_sp : postmortem_processes) + m_storage.postmortem_processes.push_back(process_sp.get()); + m_storage.cpus = postmortem_cpus; +} - for (const TraceBinaryData &item : live_process_state->processBinaryData) - m_live_process_data[item.kind] = item.size; +Process *Trace::GetLiveProcess() { return m_live_process; } - DoRefreshLiveProcessState(std::move(live_process_state)); +ArrayRef<Process *> Trace::GetPostMortemProcesses() { + return m_storage.postmortem_processes; +} + +std::vector<Process *> Trace::GetAllProcesses() { + if (Process *proc = GetLiveProcess()) + return {proc}; + return GetPostMortemProcesses(); } uint32_t Trace::GetStopID() { RefreshLiveProcessState(); return m_stop_id; } + +llvm::Expected<FileSpec> +Trace::GetPostMortemThreadDataFile(lldb::tid_t tid, llvm::StringRef kind) { + Storage &storage = GetUpdatedStorage(); + if (Optional<FileSpec> file = + Lookup(storage.postmortem_thread_data, tid, ConstString(kind))) + return *file; + else + return createStringError( + inconvertibleErrorCode(), + formatv("The thread with tid={0} doesn't have the tracing data {1}", + tid, kind)); +} + +llvm::Expected<FileSpec> Trace::GetPostMortemCpuDataFile(lldb::cpu_id_t cpu_id, + llvm::StringRef kind) { + Storage &storage = GetUpdatedStorage(); + if (Optional<FileSpec> file = + Lookup(storage.postmortem_cpu_data, cpu_id, ConstString(kind))) + return *file; + else + return createStringError( + inconvertibleErrorCode(), + formatv("The cpu with id={0} doesn't have the tracing data {1}", cpu_id, + kind)); +} + +void Trace::SetPostMortemThreadDataFile(lldb::tid_t tid, llvm::StringRef kind, + FileSpec file_spec) { + Storage &storage = GetUpdatedStorage(); + storage.postmortem_thread_data[tid].insert({ConstString(kind), file_spec}); +} + +void Trace::SetPostMortemCpuDataFile(lldb::cpu_id_t cpu_id, + llvm::StringRef kind, FileSpec file_spec) { + Storage &storage = GetUpdatedStorage(); + storage.postmortem_cpu_data[cpu_id].insert({ConstString(kind), file_spec}); +} + +llvm::Error +Trace::OnLiveThreadBinaryDataRead(lldb::tid_t tid, llvm::StringRef kind, + OnBinaryDataReadCallback callback) { + Expected<std::vector<uint8_t>> data = GetLiveThreadBinaryData(tid, kind); + if (!data) + return data.takeError(); + return callback(*data); +} + +llvm::Error Trace::OnLiveCpuBinaryDataRead(lldb::cpu_id_t cpu_id, + llvm::StringRef kind, + OnBinaryDataReadCallback callback) { + Storage &storage = GetUpdatedStorage(); + if (std::vector<uint8_t> *cpu_data = + LookupAsPtr(storage.live_cpu_data, cpu_id, ConstString(kind))) + return callback(*cpu_data); + + Expected<std::vector<uint8_t>> data = GetLiveCpuBinaryData(cpu_id, kind); + if (!data) + return data.takeError(); + auto it = storage.live_cpu_data[cpu_id].insert( + {ConstString(kind), std::move(*data)}); + return callback(it.first->second); +} + +llvm::Error Trace::OnDataFileRead(FileSpec file, + OnBinaryDataReadCallback callback) { + ErrorOr<std::unique_ptr<MemoryBuffer>> trace_or_error = + MemoryBuffer::getFile(file.GetPath()); + if (std::error_code err = trace_or_error.getError()) + return createStringError( + inconvertibleErrorCode(), "Failed fetching trace-related file %s. %s", + file.GetCString(), toString(errorCodeToError(err)).c_str()); + + MemoryBuffer &data = **trace_or_error; + ArrayRef<uint8_t> array_ref( + reinterpret_cast<const uint8_t *>(data.getBufferStart()), + data.getBufferSize()); + return callback(array_ref); +} + +llvm::Error +Trace::OnPostMortemThreadBinaryDataRead(lldb::tid_t tid, llvm::StringRef kind, + OnBinaryDataReadCallback callback) { + if (Expected<FileSpec> file = GetPostMortemThreadDataFile(tid, kind)) + return OnDataFileRead(*file, callback); + else + return file.takeError(); +} + +llvm::Error +Trace::OnPostMortemCpuBinaryDataRead(lldb::cpu_id_t cpu_id, + llvm::StringRef kind, + OnBinaryDataReadCallback callback) { + if (Expected<FileSpec> file = GetPostMortemCpuDataFile(cpu_id, kind)) + return OnDataFileRead(*file, callback); + else + return file.takeError(); +} + +llvm::Error Trace::OnThreadBinaryDataRead(lldb::tid_t tid, llvm::StringRef kind, + OnBinaryDataReadCallback callback) { + if (m_live_process) + return OnLiveThreadBinaryDataRead(tid, kind, callback); + else + return OnPostMortemThreadBinaryDataRead(tid, kind, callback); +} + +llvm::Error +Trace::OnAllCpusBinaryDataRead(llvm::StringRef kind, + OnCpusBinaryDataReadCallback callback) { + DenseMap<cpu_id_t, ArrayRef<uint8_t>> buffers; + Storage &storage = GetUpdatedStorage(); + if (!storage.cpus) + return Error::success(); + + std::function<Error(std::vector<cpu_id_t>::iterator)> process_cpu = + [&](std::vector<cpu_id_t>::iterator cpu_id) -> Error { + if (cpu_id == storage.cpus->end()) + return callback(buffers); + + return OnCpuBinaryDataRead(*cpu_id, kind, + [&](ArrayRef<uint8_t> data) -> Error { + buffers.try_emplace(*cpu_id, data); + auto next_id = cpu_id; + next_id++; + return process_cpu(next_id); + }); + }; + return process_cpu(storage.cpus->begin()); +} + +llvm::Error Trace::OnCpuBinaryDataRead(lldb::cpu_id_t cpu_id, + llvm::StringRef kind, + OnBinaryDataReadCallback callback) { + if (m_live_process) + return OnLiveCpuBinaryDataRead(cpu_id, kind, callback); + else + return OnPostMortemCpuBinaryDataRead(cpu_id, kind, callback); +} + +ArrayRef<lldb::cpu_id_t> Trace::GetTracedCpus() { + Storage &storage = GetUpdatedStorage(); + if (storage.cpus) + return *storage.cpus; + return {}; +} + +std::vector<Process *> Trace::GetTracedProcesses() { + std::vector<Process *> processes; + Storage &storage = GetUpdatedStorage(); + + for (Process *proc : storage.postmortem_processes) + processes.push_back(proc); + + if (m_live_process) + processes.push_back(m_live_process); + return processes; +} diff --git a/contrib/llvm-project/lldb/source/Target/TraceCursor.cpp b/contrib/llvm-project/lldb/source/Target/TraceCursor.cpp index d0f69642cb90..1c3fabc4dec0 100644 --- a/contrib/llvm-project/lldb/source/Target/TraceCursor.cpp +++ b/contrib/llvm-project/lldb/source/Target/TraceCursor.cpp @@ -9,6 +9,7 @@ #include "lldb/Target/TraceCursor.h" #include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Trace.h" using namespace lldb; using namespace lldb_private; @@ -21,15 +22,31 @@ ExecutionContextRef &TraceCursor::GetExecutionContextRef() { return m_exe_ctx_ref; } -void TraceCursor::SetGranularity( - lldb::TraceInstructionControlFlowType granularity) { - m_granularity = granularity; +void TraceCursor::SetForwards(bool forwards) { m_forwards = forwards; } + +bool TraceCursor::IsForwards() const { return m_forwards; } + +bool TraceCursor::IsError() const { + return GetItemKind() == lldb::eTraceItemKindError; } -void TraceCursor::SetIgnoreErrors(bool ignore_errors) { - m_ignore_errors = ignore_errors; +bool TraceCursor::IsEvent() const { + return GetItemKind() == lldb::eTraceItemKindEvent; } -void TraceCursor::SetForwards(bool forwards) { m_forwards = forwards; } +bool TraceCursor::IsInstruction() const { + return GetItemKind() == lldb::eTraceItemKindInstruction; +} -bool TraceCursor::IsForwards() const { return m_forwards; } +const char *TraceCursor::GetEventTypeAsString() const { + return EventKindToString(GetEventType()); +} + +const char *TraceCursor::EventKindToString(lldb::TraceEvent event_kind) { + switch (event_kind) { + case lldb::eTraceEventDisabledHW: + return "hardware disabled tracing"; + case lldb::eTraceEventDisabledSW: + return "software disabled tracing"; + } +} diff --git a/contrib/llvm-project/lldb/source/Target/TraceDumper.cpp b/contrib/llvm-project/lldb/source/Target/TraceDumper.cpp new file mode 100644 index 000000000000..6a5fd0268e02 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Target/TraceDumper.cpp @@ -0,0 +1,389 @@ +//===-- TraceDumper.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/TraceDumper.h" + +#include "lldb/Core/Module.h" +#include "lldb/Symbol/CompileUnit.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; + +/// \return +/// The given string or \b None if it's empty. +static Optional<const char *> ToOptionalString(const char *s) { + if (!s) + return None; + return s; +} +/// \return +/// The module name (basename if the module is a file, or the actual name if +/// it's a virtual module), or \b nullptr if no name nor module was found. +static const char *GetModuleName(const TraceDumper::TraceItem &item) { + if (!item.symbol_info || !item.symbol_info->sc.module_sp) + return nullptr; + return item.symbol_info->sc.module_sp->GetFileSpec() + .GetFilename() + .AsCString(); +} + +// 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 SymbolInfo +/// 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 TraceDumper::SymbolInfo &prev_insn, + const TraceDumper::SymbolInfo &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; +} + +class OutputWriterCLI : public TraceDumper::OutputWriter { +public: + OutputWriterCLI(Stream &s, const TraceDumperOptions &options, Thread &thread) + : m_s(s), m_options(options) { + m_s.Format("thread #{0}: tid = {1}\n", thread.GetIndexID(), thread.GetID()); + }; + + void NoMoreData() override { m_s << " no more data\n"; } + + void TraceItem(const TraceDumper::TraceItem &item) override { + if (item.symbol_info) { + if (!item.prev_symbol_info || + !IsSameInstructionSymbolContext(*item.prev_symbol_info, + *item.symbol_info)) { + m_s << " "; + const char *module_name = GetModuleName(item); + if (!module_name) + m_s << "(none)"; + else if (!item.symbol_info->sc.function && !item.symbol_info->sc.symbol) + m_s.Format("{0}`(none)", module_name); + else + item.symbol_info->sc.DumpStopContext( + &m_s, item.symbol_info->exe_ctx.GetTargetPtr(), + item.symbol_info->address, + /*show_fullpaths=*/false, + /*show_module=*/true, /*show_inlined_frames=*/false, + /*show_function_arguments=*/true, + /*show_function_name=*/true); + m_s << "\n"; + } + } + + if (item.error && !m_was_prev_instruction_an_error) + m_s << " ...missing instructions\n"; + + m_s.Format(" {0}: ", item.id); + + if (m_options.show_tsc) { + m_s << "[tsc="; + + if (item.tsc) + m_s.Format("{0}", *item.tsc); + else + m_s << "unavailable"; + + m_s << "] "; + } + + if (item.event) { + m_s << "(event) " << TraceCursor::EventKindToString(*item.event); + } else if (item.error) { + m_s << "(error) " << *item.error; + } else { + m_s.Format("{0:x+16}", item.load_address); + if (item.symbol_info) { + m_s << " "; + item.symbol_info->instruction->Dump(&m_s, /*max_opcode_byte_size=*/0, + /*show_address=*/false, + /*show_bytes=*/false, + &item.symbol_info->exe_ctx, + &item.symbol_info->sc, + /*prev_sym_ctx=*/nullptr, + /*disassembly_addr_format=*/nullptr, + /*max_address_text_size=*/0); + } + } + + m_was_prev_instruction_an_error = (bool)item.error; + m_s << "\n"; + } + +private: + Stream &m_s; + TraceDumperOptions m_options; + bool m_was_prev_instruction_an_error = false; +}; + +class OutputWriterJSON : public TraceDumper::OutputWriter { + /* schema: + error_message: string + | { + "id": decimal, + "tsc"?: string decimal, + "event": string + } | { + "id": decimal, + "tsc"?: string decimal, + "error": string, + | { + "id": decimal, + "tsc"?: string decimal, + "module"?: string, + "symbol"?: string, + "line"?: decimal, + "column"?: decimal, + "source"?: string, + "mnemonic"?: string, + } + */ +public: + OutputWriterJSON(Stream &s, const TraceDumperOptions &options) + : m_s(s), m_options(options), + m_j(m_s.AsRawOstream(), + /*IndentSize=*/options.pretty_print_json ? 2 : 0) { + m_j.arrayBegin(); + }; + + ~OutputWriterJSON() { m_j.arrayEnd(); } + + void TraceItem(const TraceDumper::TraceItem &item) override { + m_j.object([&] { + m_j.attribute("id", item.id); + if (m_options.show_tsc) + m_j.attribute( + "tsc", + item.tsc ? Optional<std::string>(std::to_string(*item.tsc)) : None); + + if (item.event) { + m_j.object([&] { + m_j.attribute("event", TraceCursor::EventKindToString(*item.event)); + }); + return; + } + + if (item.error) { + m_j.attribute("error", *item.error); + return; + } + + // we know we are seeing an actual instruction + m_j.attribute("loadAddress", formatv("{0:x}", item.load_address)); + if (item.symbol_info) { + m_j.attribute("module", ToOptionalString(GetModuleName(item))); + m_j.attribute("symbol", + ToOptionalString( + item.symbol_info->sc.GetFunctionName().AsCString())); + m_j.attribute( + "mnemonic", + ToOptionalString(item.symbol_info->instruction->GetMnemonic( + &item.symbol_info->exe_ctx))); + + if (IsLineEntryValid(item.symbol_info->sc.line_entry)) { + m_j.attribute( + "source", + ToOptionalString( + item.symbol_info->sc.line_entry.file.GetPath().c_str())); + m_j.attribute("line", item.symbol_info->sc.line_entry.line); + m_j.attribute("column", item.symbol_info->sc.line_entry.column); + } + } + }); + } + +private: + Stream &m_s; + TraceDumperOptions m_options; + json::OStream m_j; +}; + +static std::unique_ptr<TraceDumper::OutputWriter> +CreateWriter(Stream &s, const TraceDumperOptions &options, Thread &thread) { + if (options.json) + return std::unique_ptr<TraceDumper::OutputWriter>( + new OutputWriterJSON(s, options)); + else + return std::unique_ptr<TraceDumper::OutputWriter>( + new OutputWriterCLI(s, options, thread)); +} + +TraceDumper::TraceDumper(lldb::TraceCursorUP &&cursor_up, Stream &s, + const TraceDumperOptions &options) + : m_cursor_up(std::move(cursor_up)), m_options(options), + m_writer_up(CreateWriter( + s, m_options, *m_cursor_up->GetExecutionContextRef().GetThreadSP())) { + + if (m_options.id) + m_cursor_up->GoToId(*m_options.id); + else if (m_options.forwards) + m_cursor_up->Seek(0, TraceCursor::SeekType::Beginning); + else + m_cursor_up->Seek(0, TraceCursor::SeekType::End); + + m_cursor_up->SetForwards(m_options.forwards); + if (m_options.skip) { + m_cursor_up->Seek((m_options.forwards ? 1 : -1) * *m_options.skip, + TraceCursor::SeekType::Current); + } +} + +TraceDumper::TraceItem TraceDumper::CreatRawTraceItem() { + TraceItem item; + item.id = m_cursor_up->GetId(); + + if (m_options.show_tsc) + item.tsc = m_cursor_up->GetCounter(lldb::eTraceCounterTSC); + return item; +} + +/// Find the symbol context for the given address reusing the previous +/// instruction's symbol context when possible. +static SymbolContext +CalculateSymbolContext(const Address &address, + const TraceDumper::SymbolInfo &prev_symbol_info) { + AddressRange range; + if (prev_symbol_info.sc.GetAddressRange(eSymbolContextEverything, 0, + /*inline_block_range*/ false, + range) && + range.Contains(address)) + return prev_symbol_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. +static std::tuple<DisassemblerSP, InstructionSP> +CalculateDisass(const TraceDumper::SymbolInfo &symbol_info, + const TraceDumper::SymbolInfo &prev_symbol_info, + const ExecutionContext &exe_ctx) { + if (prev_symbol_info.disassembler) { + if (InstructionSP instruction = + prev_symbol_info.disassembler->GetInstructionList() + .GetInstructionAtAddress(symbol_info.address)) + return std::make_tuple(prev_symbol_info.disassembler, instruction); + } + + if (symbol_info.sc.function) { + if (DisassemblerSP disassembler = + symbol_info.sc.function->GetInstructions(exe_ctx, nullptr)) { + if (InstructionSP instruction = + disassembler->GetInstructionList().GetInstructionAtAddress( + symbol_info.address)) + return std::make_tuple(disassembler, instruction); + } + } + // We fallback to a single instruction disassembler + Target &target = exe_ctx.GetTargetRef(); + const ArchSpec arch = target.GetArchitecture(); + AddressRange range(symbol_info.address, arch.GetMaximumOpcodeByteSize()); + DisassemblerSP disassembler = + Disassembler::DisassembleRange(arch, /*plugin_name*/ nullptr, + /*flavor*/ nullptr, target, range); + return std::make_tuple( + disassembler, + disassembler ? disassembler->GetInstructionList().GetInstructionAtAddress( + symbol_info.address) + : InstructionSP()); +} + +Optional<lldb::user_id_t> TraceDumper::DumpInstructions(size_t count) { + ThreadSP thread_sp = m_cursor_up->GetExecutionContextRef().GetThreadSP(); + + SymbolInfo prev_symbol_info; + Optional<lldb::user_id_t> last_id; + + ExecutionContext exe_ctx; + thread_sp->GetProcess()->GetTarget().CalculateExecutionContext(exe_ctx); + + for (size_t insn_seen = 0; insn_seen < count && m_cursor_up->HasValue(); + m_cursor_up->Next()) { + + last_id = m_cursor_up->GetId(); + TraceItem item = CreatRawTraceItem(); + + if (m_cursor_up->IsEvent()) { + if (!m_options.show_events) + continue; + item.event = m_cursor_up->GetEventType(); + } else if (m_cursor_up->IsError()) { + item.error = m_cursor_up->GetError(); + } else { + insn_seen++; + item.load_address = m_cursor_up->GetLoadAddress(); + + if (!m_options.raw) { + SymbolInfo symbol_info; + symbol_info.exe_ctx = exe_ctx; + symbol_info.address.SetLoadAddress(item.load_address, + exe_ctx.GetTargetPtr()); + symbol_info.sc = + CalculateSymbolContext(symbol_info.address, prev_symbol_info); + std::tie(symbol_info.disassembler, symbol_info.instruction) = + CalculateDisass(symbol_info, prev_symbol_info, exe_ctx); + item.prev_symbol_info = prev_symbol_info; + item.symbol_info = symbol_info; + prev_symbol_info = symbol_info; + } + } + m_writer_up->TraceItem(item); + } + if (!m_cursor_up->HasValue()) + m_writer_up->NoMoreData(); + return last_id; +} diff --git a/contrib/llvm-project/lldb/source/Target/TraceInstructionDumper.cpp b/contrib/llvm-project/lldb/source/Target/TraceInstructionDumper.cpp deleted file mode 100644 index d58d2dff7383..000000000000 --- a/contrib/llvm-project/lldb/source/Target/TraceInstructionDumper.cpp +++ /dev/null @@ -1,292 +0,0 @@ -//===-- 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_fullpaths=*/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, /*max_opcode_byte_size=*/0, /*show_address=*/false, - /*show_bytes=*/false, &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/UnixSignals.cpp b/contrib/llvm-project/lldb/source/Target/UnixSignals.cpp index 26ff0bbd3825..4ae848a98edd 100644 --- a/contrib/llvm-project/lldb/source/Target/UnixSignals.cpp +++ b/contrib/llvm-project/lldb/source/Target/UnixSignals.cpp @@ -22,7 +22,9 @@ UnixSignals::Signal::Signal(const char *name, bool default_suppress, const char *description, const char *alias) : m_name(name), m_alias(alias), m_description(), m_suppress(default_suppress), m_stop(default_stop), - m_notify(default_notify) { + m_notify(default_notify), + m_default_suppress(default_suppress), m_default_stop(default_stop), + m_default_notify(default_notify) { if (description) m_description.assign(description); } @@ -298,14 +300,14 @@ UnixSignals::GetFilteredSignals(llvm::Optional<bool> should_suppress, // If any of filtering conditions are not met, we move on to the next // signal. - if (should_suppress.hasValue() && + if (should_suppress && signal_suppress != should_suppress.getValue()) continue; - if (should_stop.hasValue() && signal_stop != should_stop.getValue()) + if (should_stop && signal_stop != should_stop.getValue()) continue; - if (should_notify.hasValue() && signal_notify != should_notify.getValue()) + if (should_notify && signal_notify != should_notify.getValue()) continue; result.push_back(signo); @@ -330,3 +332,23 @@ json::Value UnixSignals::GetHitCountStatistics() const { } return std::move(json_signals); } + +void UnixSignals::Signal::Reset(bool reset_stop, bool reset_notify, + bool reset_suppress) { + if (reset_stop) + m_stop = m_default_stop; + if (reset_notify) + m_notify = m_default_notify; + if (reset_suppress) + m_suppress = m_default_suppress; +} + +bool UnixSignals::ResetSignal(int32_t signo, bool reset_stop, + bool reset_notify, bool reset_suppress) { + auto elem = m_signals.find(signo); + if (elem == m_signals.end()) + return false; + (*elem).second.Reset(reset_stop, reset_notify, reset_suppress); + return true; +} + diff --git a/contrib/llvm-project/lldb/source/Target/UnwindLLDB.cpp b/contrib/llvm-project/lldb/source/Target/UnwindLLDB.cpp index 77dd19b04ebd..1d8bf2f88ae6 100644 --- a/contrib/llvm-project/lldb/source/Target/UnwindLLDB.cpp +++ b/contrib/llvm-project/lldb/source/Target/UnwindLLDB.cpp @@ -17,6 +17,7 @@ #include "lldb/Target/RegisterContextUnwind.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" using namespace lldb; @@ -101,7 +102,7 @@ bool UnwindLLDB::AddFirstFrame() { return true; unwind_done: - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + Log *log = GetLog(LLDBLog::Unwind); if (log) { LLDB_LOGF(log, "th%d Unwind of this thread is complete.", m_thread.GetIndexID()); @@ -119,7 +120,7 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) { if (m_unwind_complete) return nullptr; - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + Log *log = GetLog(LLDBLog::Unwind); CursorSP prev_frame = m_frames.back(); uint32_t cur_idx = m_frames.size(); @@ -315,7 +316,7 @@ void UnwindLLDB::UpdateUnwindPlanForFirstFrameIfInvalid(ABI *abi) { } bool UnwindLLDB::AddOneMoreFrame(ABI *abi) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + Log *log = GetLog(LLDBLog::Unwind); // Frame zero is a little different if (m_frames.empty()) diff --git a/contrib/llvm-project/lldb/source/Utility/ArchSpec.cpp b/contrib/llvm-project/lldb/source/Utility/ArchSpec.cpp index 74a437042345..a99aed82bc88 100644 --- a/contrib/llvm-project/lldb/source/Utility/ArchSpec.cpp +++ b/contrib/llvm-project/lldb/source/Utility/ArchSpec.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StringList.h" @@ -357,10 +358,10 @@ static const ArchDefinitionEntry g_elf_arch_entries[] = { 0xFFFFFFFFu, 0xFFFFFFFFu}, // Intel MCU // FIXME: is this correct? {ArchSpec::eCore_ppc_generic, llvm::ELF::EM_PPC, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // PowerPC - {ArchSpec::eCore_ppc64le_generic, llvm::ELF::EM_PPC64, LLDB_INVALID_CPUTYPE, - 0xFFFFFFFFu, 0xFFFFFFFFu}, // PowerPC64le - {ArchSpec::eCore_ppc64_generic, llvm::ELF::EM_PPC64, LLDB_INVALID_CPUTYPE, - 0xFFFFFFFFu, 0xFFFFFFFFu}, // PowerPC64 + {ArchSpec::eCore_ppc64le_generic, llvm::ELF::EM_PPC64, + ArchSpec::eCore_ppc64le_generic, 0xFFFFFFFFu, 0xFFFFFFFFu}, // PowerPC64le + {ArchSpec::eCore_ppc64_generic, llvm::ELF::EM_PPC64, + ArchSpec::eCore_ppc64_generic, 0xFFFFFFFFu, 0xFFFFFFFFu}, // PowerPC64 {ArchSpec::eCore_arm_generic, llvm::ELF::EM_ARM, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // ARM {ArchSpec::eCore_arm_aarch64, llvm::ELF::EM_AARCH64, LLDB_INVALID_CPUTYPE, @@ -399,8 +400,8 @@ static const ArchDefinitionEntry g_elf_arch_entries[] = { LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // HEXAGON {ArchSpec::eCore_arc, llvm::ELF::EM_ARC_COMPACT2, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // ARC - {ArchSpec::eCore_avr, llvm::ELF::EM_AVR, LLDB_INVALID_CPUTYPE, - 0xFFFFFFFFu, 0xFFFFFFFFu}, // AVR + {ArchSpec::eCore_avr, llvm::ELF::EM_AVR, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, + 0xFFFFFFFFu}, // AVR {ArchSpec::eCore_riscv32, llvm::ELF::EM_RISCV, ArchSpec::eRISCVSubType_riscv32, 0xFFFFFFFFu, 0xFFFFFFFFu}, // riscv32 {ArchSpec::eCore_riscv64, llvm::ELF::EM_RISCV, @@ -902,7 +903,7 @@ bool ArchSpec::SetArchitecture(ArchitectureType arch_type, uint32_t cpu, m_triple.setArch(core_def->machine); } } else { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET | LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_PLATFORM)); + Log *log(GetLog(LLDBLog::Target | LLDBLog::Process | LLDBLog::Platform)); LLDB_LOGF(log, "Unable to find a core definition for cpu 0x%" PRIx32 " sub %" PRId32, @@ -978,7 +979,16 @@ bool ArchSpec::IsEqualTo(const ArchSpec &rhs, bool exact_match) const { const llvm::Triple::VendorType lhs_triple_vendor = lhs_triple.getVendor(); const llvm::Triple::VendorType rhs_triple_vendor = rhs_triple.getVendor(); - if (lhs_triple_vendor != rhs_triple_vendor) { + + const llvm::Triple::OSType lhs_triple_os = lhs_triple.getOS(); + const llvm::Triple::OSType rhs_triple_os = rhs_triple.getOS(); + + bool both_windows = lhs_triple.isOSWindows() && rhs_triple.isOSWindows(); + + // On Windows, the vendor field doesn't have any practical effect, but + // it is often set to either "pc" or "w64". + if ((lhs_triple_vendor != rhs_triple_vendor) && + (exact_match || !both_windows)) { const bool rhs_vendor_specified = rhs.TripleVendorWasSpecified(); const bool lhs_vendor_specified = TripleVendorWasSpecified(); // Both architectures had the vendor specified, so if they aren't equal @@ -992,8 +1002,6 @@ bool ArchSpec::IsEqualTo(const ArchSpec &rhs, bool exact_match) const { return false; } - const llvm::Triple::OSType lhs_triple_os = lhs_triple.getOS(); - const llvm::Triple::OSType rhs_triple_os = rhs_triple.getOS(); const llvm::Triple::EnvironmentType lhs_triple_env = lhs_triple.getEnvironment(); const llvm::Triple::EnvironmentType rhs_triple_env = @@ -1031,6 +1039,9 @@ bool ArchSpec::IsEqualTo(const ArchSpec &rhs, bool exact_match) const { return true; } + if (!exact_match && both_windows) + return true; // The Windows environments (MSVC vs GNU) are compatible + return IsCompatibleEnvironment(lhs_triple_env, rhs_triple_env); } @@ -1395,23 +1406,18 @@ bool lldb_private::operator==(const ArchSpec &lhs, const ArchSpec &rhs) { } bool ArchSpec::IsFullySpecifiedTriple() const { - const auto &user_specified_triple = GetTriple(); - - bool user_triple_fully_specified = false; - - if ((user_specified_triple.getOS() != llvm::Triple::UnknownOS) || - TripleOSWasSpecified()) { - if ((user_specified_triple.getVendor() != llvm::Triple::UnknownVendor) || - TripleVendorWasSpecified()) { - const unsigned unspecified = 0; - if (!user_specified_triple.isOSDarwin() || - user_specified_triple.getOSMajorVersion() != unspecified) { - user_triple_fully_specified = true; - } - } - } + if (!TripleOSWasSpecified()) + return false; + + if (!TripleVendorWasSpecified()) + return false; - return user_triple_fully_specified; + const unsigned unspecified = 0; + const llvm::Triple &triple = GetTriple(); + if (triple.isOSDarwin() && triple.getOSMajorVersion() == unspecified) + return false; + + return true; } void ArchSpec::PiecewiseTripleCompare( diff --git a/contrib/llvm-project/lldb/source/Utility/Args.cpp b/contrib/llvm-project/lldb/source/Utility/Args.cpp index 0334659ab7dd..3978f9422653 100644 --- a/contrib/llvm-project/lldb/source/Utility/Args.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Args.cpp @@ -384,10 +384,10 @@ std::string Args::GetShellSafeArgument(const FileSpec &shell, llvm::StringRef m_escapables; }; - static ShellDescriptor g_Shells[] = {{ConstString("bash"), " '\"<>()&"}, - {ConstString("tcsh"), " '\"<>()&$"}, + static ShellDescriptor g_Shells[] = {{ConstString("bash"), " '\"<>()&;"}, + {ConstString("tcsh"), " '\"<>()&;"}, {ConstString("zsh"), " '\"<>()&;\\|"}, - {ConstString("sh"), " '\"<>()&"}}; + {ConstString("sh"), " '\"<>()&;"}}; // safe minimal set llvm::StringRef escapables = " '\""; diff --git a/contrib/llvm-project/lldb/source/Utility/Broadcaster.cpp b/contrib/llvm-project/lldb/source/Utility/Broadcaster.cpp index 6e0672496321..31530f8a6443 100644 --- a/contrib/llvm-project/lldb/source/Utility/Broadcaster.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Broadcaster.cpp @@ -7,11 +7,9 @@ //===----------------------------------------------------------------------===// #include "lldb/Utility/Broadcaster.h" - #include "lldb/Utility/Event.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Listener.h" -#include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" @@ -28,7 +26,7 @@ using namespace lldb_private; Broadcaster::Broadcaster(BroadcasterManagerSP manager_sp, const char *name) : m_broadcaster_sp(std::make_shared<BroadcasterImpl>(*this)), m_manager_sp(std::move(manager_sp)), m_broadcaster_name(name) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); + Log *log = GetLog(LLDBLog::Object); LLDB_LOG(log, "{0} Broadcaster::Broadcaster(\"{1}\")", static_cast<void *>(this), GetBroadcasterName()); } @@ -38,7 +36,7 @@ Broadcaster::BroadcasterImpl::BroadcasterImpl(Broadcaster &broadcaster) m_hijacking_listeners(), m_hijacking_masks() {} Broadcaster::~Broadcaster() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); + Log *log = GetLog(LLDBLog::Object); LLDB_LOG(log, "{0} Broadcaster::~Broadcaster(\"{1}\")", static_cast<void *>(this), GetBroadcasterName()); @@ -210,7 +208,11 @@ void Broadcaster::BroadcasterImpl::PrivateBroadcastEvent(EventSP &event_sp, hijacking_listener_sp.reset(); } - if (Log *log = lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EVENTS)) { + Log *log = GetLog(LLDBLog::Events); + if (!log && event_sp->GetData()) + log = event_sp->GetData()->GetLogChannel(); + + if (log) { StreamString event_description; event_sp->Dump(&event_description); LLDB_LOGF(log, @@ -261,7 +263,7 @@ bool Broadcaster::BroadcasterImpl::HijackBroadcaster( const lldb::ListenerSP &listener_sp, uint32_t event_mask) { std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex); - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EVENTS)); + Log *log = GetLog(LLDBLog::Events); LLDB_LOG( log, "{0} Broadcaster(\"{1}\")::HijackBroadcaster (listener(\"{2}\")={3})", @@ -292,7 +294,7 @@ void Broadcaster::BroadcasterImpl::RestoreBroadcaster() { if (!m_hijacking_listeners.empty()) { ListenerSP listener_sp = m_hijacking_listeners.back(); - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EVENTS)); + Log *log = GetLog(LLDBLog::Events); LLDB_LOG(log, "{0} Broadcaster(\"{1}\")::RestoreBroadcaster (about to pop " "listener(\"{2}\")={3})", diff --git a/contrib/llvm-project/lldb/source/Utility/DataBufferHeap.cpp b/contrib/llvm-project/lldb/source/Utility/DataBufferHeap.cpp index 3aa0b6b0ac40..ea84a36f1697 100644 --- a/contrib/llvm-project/lldb/source/Utility/DataBufferHeap.cpp +++ b/contrib/llvm-project/lldb/source/Utility/DataBufferHeap.cpp @@ -26,18 +26,16 @@ DataBufferHeap::DataBufferHeap(const void *src, lldb::offset_t src_len) CopyData(src, src_len); } +DataBufferHeap::DataBufferHeap(const DataBuffer &data_buffer) : m_data() { + CopyData(data_buffer.GetBytes(), data_buffer.GetByteSize()); +} + // Virtual destructor since this class inherits from a pure virtual base class. DataBufferHeap::~DataBufferHeap() = default; -// Return a pointer to the bytes owned by this object, or nullptr if the object -// contains no bytes. -uint8_t *DataBufferHeap::GetBytes() { - return (m_data.empty() ? nullptr : m_data.data()); -} - // Return a const pointer to the bytes owned by this object, or nullptr if the // object contains no bytes. -const uint8_t *DataBufferHeap::GetBytes() const { +const uint8_t *DataBufferHeap::GetBytesImpl() const { return (m_data.empty() ? nullptr : m_data.data()); } @@ -47,7 +45,8 @@ uint64_t DataBufferHeap::GetByteSize() const { return m_data.size(); } // Sets the number of bytes that this object should be able to contain. This // can be used prior to copying data into the buffer. uint64_t DataBufferHeap::SetByteSize(uint64_t new_size) { - m_data.resize(new_size); + if (new_size < m_data.max_size()) + m_data.resize(new_size); return m_data.size(); } @@ -68,3 +67,8 @@ void DataBufferHeap::Clear() { buffer_t empty; m_data.swap(empty); } + +char DataBuffer::ID; +char WritableDataBuffer::ID; +char DataBufferUnowned::ID; +char DataBufferHeap::ID; diff --git a/contrib/llvm-project/lldb/source/Utility/DataBufferLLVM.cpp b/contrib/llvm-project/lldb/source/Utility/DataBufferLLVM.cpp index c5aeddd683f4..376fe0689ecf 100644 --- a/contrib/llvm-project/lldb/source/Utility/DataBufferLLVM.cpp +++ b/contrib/llvm-project/lldb/source/Utility/DataBufferLLVM.cpp @@ -14,8 +14,7 @@ using namespace lldb_private; -DataBufferLLVM::DataBufferLLVM( - std::unique_ptr<llvm::WritableMemoryBuffer> MemBuffer) +DataBufferLLVM::DataBufferLLVM(std::unique_ptr<llvm::MemoryBuffer> MemBuffer) : Buffer(std::move(MemBuffer)) { assert(Buffer != nullptr && "Cannot construct a DataBufferLLVM with a null buffer"); @@ -23,14 +22,30 @@ DataBufferLLVM::DataBufferLLVM( DataBufferLLVM::~DataBufferLLVM() = default; -uint8_t *DataBufferLLVM::GetBytes() { - return reinterpret_cast<uint8_t *>(Buffer->getBufferStart()); +const uint8_t *DataBufferLLVM::GetBytesImpl() const { + return reinterpret_cast<const uint8_t *>(Buffer->getBufferStart()); +} + +lldb::offset_t DataBufferLLVM::GetByteSize() const { + return Buffer->getBufferSize(); +} + +WritableDataBufferLLVM::WritableDataBufferLLVM( + std::unique_ptr<llvm::WritableMemoryBuffer> MemBuffer) + : Buffer(std::move(MemBuffer)) { + assert(Buffer != nullptr && + "Cannot construct a WritableDataBufferLLVM with a null buffer"); } -const uint8_t *DataBufferLLVM::GetBytes() const { +WritableDataBufferLLVM::~WritableDataBufferLLVM() = default; + +const uint8_t *WritableDataBufferLLVM::GetBytesImpl() const { return reinterpret_cast<const uint8_t *>(Buffer->getBufferStart()); } -lldb::offset_t DataBufferLLVM::GetByteSize() const { +lldb::offset_t WritableDataBufferLLVM::GetByteSize() const { return Buffer->getBufferSize(); } + +char DataBufferLLVM::ID; +char WritableDataBufferLLVM::ID; diff --git a/contrib/llvm-project/lldb/source/Utility/DataExtractor.cpp b/contrib/llvm-project/lldb/source/Utility/DataExtractor.cpp index bdd79fd9b411..a0cd945b7445 100644 --- a/contrib/llvm-project/lldb/source/Utility/DataExtractor.cpp +++ b/contrib/llvm-project/lldb/source/Utility/DataExtractor.cpp @@ -142,8 +142,7 @@ DataExtractor::DataExtractor(const void *data, offset_t length, DataExtractor::DataExtractor(const DataBufferSP &data_sp, ByteOrder endian, uint32_t addr_size, uint32_t target_byte_size /*=1*/) - : m_start(nullptr), m_end(nullptr), m_byte_order(endian), - m_addr_size(addr_size), m_data_sp(), + : m_byte_order(endian), m_addr_size(addr_size), m_data_sp(), m_target_byte_size(target_byte_size) { assert(addr_size >= 1 && addr_size <= 8); SetData(data_sp); @@ -156,9 +155,8 @@ DataExtractor::DataExtractor(const DataBufferSP &data_sp, ByteOrder endian, // "data". DataExtractor::DataExtractor(const DataExtractor &data, offset_t offset, offset_t length, uint32_t target_byte_size /*=1*/) - : m_start(nullptr), m_end(nullptr), m_byte_order(data.m_byte_order), - m_addr_size(data.m_addr_size), m_data_sp(), - m_target_byte_size(target_byte_size) { + : m_byte_order(data.m_byte_order), m_addr_size(data.m_addr_size), + m_data_sp(), m_target_byte_size(target_byte_size) { assert(m_addr_size >= 1 && m_addr_size <= 8); if (data.ValidOffset(offset)) { offset_t bytes_available = data.GetByteSize() - offset; @@ -1044,5 +1042,5 @@ void DataExtractor::Checksum(llvm::SmallVectorImpl<uint8_t> &dest, md5.final(result); dest.clear(); - dest.append(result.Bytes.begin(), result.Bytes.end()); + dest.append(result.begin(), result.end()); } diff --git a/contrib/llvm-project/lldb/source/Utility/FileSpec.cpp b/contrib/llvm-project/lldb/source/Utility/FileSpec.cpp index 24f8c2b1c23f..c0dbc29bcd1f 100644 --- a/contrib/llvm-project/lldb/source/Utility/FileSpec.cpp +++ b/contrib/llvm-project/lldb/source/Utility/FileSpec.cpp @@ -311,7 +311,8 @@ llvm::Optional<FileSpec::Style> FileSpec::GuessPathStyle(llvm::StringRef absolut if (absolute_path.startswith(R"(\\)")) return Style::windows; if (absolute_path.size() >= 3 && llvm::isAlpha(absolute_path[0]) && - absolute_path.substr(1, 2) == R"(:\)") + (absolute_path.substr(1, 2) == R"(:\)" || + absolute_path.substr(1, 2) == R"(:/)")) return Style::windows; return llvm::None; } @@ -356,7 +357,7 @@ size_t FileSpec::GetPath(char *path, size_t path_max_len, std::string FileSpec::GetPath(bool denormalize) const { llvm::SmallString<64> result; GetPath(result, denormalize); - return std::string(result.begin(), result.end()); + return static_cast<std::string>(result); } const char *FileSpec::GetCString(bool denormalize) const { diff --git a/contrib/llvm-project/lldb/source/Utility/Instrumentation.cpp b/contrib/llvm-project/lldb/source/Utility/Instrumentation.cpp index 861789810e1a..581f657aea80 100644 --- a/contrib/llvm-project/lldb/source/Utility/Instrumentation.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Instrumentation.cpp @@ -6,6 +6,7 @@ //===----------------------------------------------------------------------===// #include "lldb/Utility/Instrumentation.h" +#include "lldb/Utility/LLDBLog.h" #include "llvm/Support/Signposts.h" #include <cstdio> @@ -24,13 +25,13 @@ static llvm::ManagedStatic<llvm::SignpostEmitter> g_api_signposts; Instrumenter::Instrumenter(llvm::StringRef pretty_func, std::string &&pretty_args) - : m_pretty_func(pretty_func), m_local_boundary(false) { + : m_pretty_func(pretty_func) { if (!g_global_boundary) { g_global_boundary = true; m_local_boundary = true; g_api_signposts->startInterval(this, m_pretty_func); } - LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API), "[{0}] {1} ({2})", + LLDB_LOG(GetLog(LLDBLog::API), "[{0}] {1} ({2})", m_local_boundary ? "external" : "internal", m_pretty_func, pretty_args); } diff --git a/contrib/llvm-project/lldb/source/Utility/Logging.cpp b/contrib/llvm-project/lldb/source/Utility/LLDBLog.cpp index 67d5d3af2640..71c534a9cfc1 100644 --- a/contrib/llvm-project/lldb/source/Utility/Logging.cpp +++ b/contrib/llvm-project/lldb/source/Utility/LLDBLog.cpp @@ -1,4 +1,4 @@ -//===-- Logging.cpp -------------------------------------------------------===// +//===-- LLDBLog.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,11 +6,9 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Utility/Logging.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" - #include "llvm/ADT/ArrayRef.h" - #include <cstdarg> using namespace lldb_private; @@ -62,6 +60,9 @@ static constexpr Log::Category g_categories[] = { {{"types"}, {"log type system related activities"}, LLDBLog::Types}, {{"unwind"}, {"log stack unwind activities"}, LLDBLog::Unwind}, {{"watch"}, {"log watchpoint related activities"}, LLDBLog::Watchpoints}, + {{"on-demand"}, + {"log symbol on-demand related activities"}, + LLDBLog::OnDemand}, }; static Log::Channel g_log_channel(g_categories, @@ -79,11 +80,3 @@ template <> Log::Channel &lldb_private::LogChannelFor<LLDBLog>() { void lldb_private::InitializeLldbChannel() { Log::Register("lldb", g_log_channel); } - -Log *lldb_private::GetLogIfAllCategoriesSet(LLDBLog mask) { - return GetLog(mask); -} - -Log *lldb_private::GetLogIfAnyCategoriesSet(LLDBLog mask) { - return GetLog(mask); -} diff --git a/contrib/llvm-project/lldb/source/Utility/Listener.cpp b/contrib/llvm-project/lldb/source/Utility/Listener.cpp index d2a4f3293963..d756e70deda4 100644 --- a/contrib/llvm-project/lldb/source/Utility/Listener.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Listener.cpp @@ -7,13 +7,10 @@ //===----------------------------------------------------------------------===// #include "lldb/Utility/Listener.h" - #include "lldb/Utility/Broadcaster.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Event.h" -#include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" - +#include "lldb/Utility/LLDBLog.h" #include "llvm/ADT/Optional.h" #include <algorithm> @@ -40,14 +37,14 @@ public: Listener::Listener(const char *name) : m_name(name), m_broadcasters(), m_broadcasters_mutex(), m_events(), m_events_mutex() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); + Log *log = GetLog(LLDBLog::Object); if (log != nullptr) LLDB_LOGF(log, "%p Listener::Listener('%s')", static_cast<void *>(this), m_name.c_str()); } Listener::~Listener() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); + Log *log = GetLog(LLDBLog::Object); Clear(); @@ -56,7 +53,7 @@ Listener::~Listener() { } void Listener::Clear() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); + Log *log = GetLog(LLDBLog::Object); std::lock_guard<std::recursive_mutex> broadcasters_guard( m_broadcasters_mutex); broadcaster_collection::iterator pos, end = m_broadcasters.end(); @@ -97,7 +94,7 @@ uint32_t Listener::StartListeningForEvents(Broadcaster *broadcaster, uint32_t acquired_mask = broadcaster->AddListener(this->shared_from_this(), event_mask); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS)); + Log *log = GetLog(LLDBLog::Events); if (log != nullptr) LLDB_LOGF(log, "%p Listener::StartListeningForEvents (broadcaster = %p, " @@ -128,7 +125,7 @@ uint32_t Listener::StartListeningForEvents(Broadcaster *broadcaster, uint32_t acquired_mask = broadcaster->AddListener(this->shared_from_this(), event_mask); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS)); + Log *log = GetLog(LLDBLog::Events); if (log != nullptr) { void **pointer = reinterpret_cast<void **>(&callback); LLDB_LOGF(log, @@ -200,7 +197,7 @@ void Listener::BroadcasterManagerWillDestruct(BroadcasterManagerSP manager_sp) { } void Listener::AddEvent(EventSP &event_sp) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS)); + Log *log = GetLog(LLDBLog::Events); if (log != nullptr) LLDB_LOGF(log, "%p Listener('%s')::AddEvent (event_sp = {%p})", static_cast<void *>(this), m_name.c_str(), @@ -270,7 +267,7 @@ bool Listener::FindNextEventInternal( // Mutex::Locker // and pass the locker as the first argument. m_events_mutex is no longer // recursive. - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS)); + Log *log = GetLog(LLDBLog::Events); if (m_events.empty()) return false; @@ -348,7 +345,7 @@ bool Listener::GetEventInternal( const ConstString *broadcaster_names, // nullptr for any event uint32_t num_broadcaster_names, uint32_t event_type_mask, EventSP &event_sp) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS)); + Log *log = GetLog(LLDBLog::Events); LLDB_LOG(log, "this = {0}, timeout = {1} for {2}", this, timeout, m_name); std::unique_lock<std::mutex> lock(m_events_mutex); @@ -366,12 +363,12 @@ bool Listener::GetEventInternal( result = m_events_condition.wait_for(lock, *timeout); if (result == std::cv_status::timeout) { - log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS); + log = GetLog(LLDBLog::Events); LLDB_LOGF(log, "%p Listener::GetEventInternal() timed out for %s", static_cast<void *>(this), m_name.c_str()); return false; } else if (result != std::cv_status::no_timeout) { - log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS); + log = GetLog(LLDBLog::Events); LLDB_LOGF(log, "%p Listener::GetEventInternal() unknown error for %s", static_cast<void *>(this), m_name.c_str()); return false; diff --git a/contrib/llvm-project/lldb/source/Utility/Log.cpp b/contrib/llvm-project/lldb/source/Utility/Log.cpp index d229538073d1..67edb15ba684 100644 --- a/contrib/llvm-project/lldb/source/Utility/Log.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Log.cpp @@ -13,6 +13,7 @@ #include "llvm/ADT/Twine.h" #include "llvm/ADT/iterator.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/Chrono.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Path.h" @@ -34,6 +35,11 @@ using namespace lldb_private; +char LogHandler::ID; +char StreamLogHandler::ID; +char CallbackLogHandler::ID; +char RotatingLogHandler::ID; + llvm::ManagedStatic<Log::ChannelMap> Log::g_channel_map; void Log::ForEachCategory( @@ -84,14 +90,14 @@ uint32_t Log::GetFlags(llvm::raw_ostream &stream, const ChannelMap::value_type & return flags; } -void Log::Enable(const std::shared_ptr<llvm::raw_ostream> &stream_sp, +void Log::Enable(const std::shared_ptr<LogHandler> &handler_sp, uint32_t options, uint32_t flags) { llvm::sys::ScopedWriter lock(m_mutex); MaskType mask = m_mask.fetch_or(flags, std::memory_order_relaxed); if (mask | flags) { m_options.store(options, std::memory_order_relaxed); - m_stream_sp = stream_sp; + m_handler = handler_sp; m_channel.log_ptr.store(this, std::memory_order_relaxed); } } @@ -101,11 +107,21 @@ void Log::Disable(uint32_t flags) { MaskType mask = m_mask.fetch_and(~flags, std::memory_order_relaxed); if (!(mask & ~flags)) { - m_stream_sp.reset(); + m_handler.reset(); m_channel.log_ptr.store(nullptr, std::memory_order_relaxed); } } +bool Log::Dump(llvm::raw_ostream &output_stream) { + llvm::sys::ScopedReader lock(m_mutex); + if (RotatingLogHandler *handler = + llvm::dyn_cast_or_null<RotatingLogHandler>(m_handler.get())) { + handler->Dump(output_stream); + return true; + } + return false; +} + const Flags Log::GetOptions() const { return m_options.load(std::memory_order_relaxed); } @@ -178,10 +194,6 @@ void Log::Warning(const char *format, ...) { Printf("warning: %s", Content.c_str()); } -void Log::Initialize() { - InitializeLldbChannel(); -} - void Log::Register(llvm::StringRef name, Channel &channel) { auto iter = g_channel_map->try_emplace(name, channel); assert(iter.second == true); @@ -195,10 +207,10 @@ void Log::Unregister(llvm::StringRef name) { g_channel_map->erase(iter); } -bool Log::EnableLogChannel( - const std::shared_ptr<llvm::raw_ostream> &log_stream_sp, - uint32_t log_options, llvm::StringRef channel, - llvm::ArrayRef<const char *> categories, llvm::raw_ostream &error_stream) { +bool Log::EnableLogChannel(const std::shared_ptr<LogHandler> &log_handler_sp, + uint32_t log_options, llvm::StringRef channel, + llvm::ArrayRef<const char *> categories, + llvm::raw_ostream &error_stream) { auto iter = g_channel_map->find(channel); if (iter == g_channel_map->end()) { error_stream << llvm::formatv("Invalid log channel '{0}'.\n", channel); @@ -207,7 +219,7 @@ bool Log::EnableLogChannel( uint32_t flags = categories.empty() ? iter->second.m_channel.default_flags : GetFlags(error_stream, *iter, categories); - iter->second.Enable(log_stream_sp, log_options, flags); + iter->second.Enable(log_handler_sp, log_options, flags); return true; } @@ -226,6 +238,22 @@ bool Log::DisableLogChannel(llvm::StringRef channel, return true; } +bool Log::DumpLogChannel(llvm::StringRef channel, + llvm::raw_ostream &output_stream, + llvm::raw_ostream &error_stream) { + auto iter = g_channel_map->find(channel); + if (iter == g_channel_map->end()) { + error_stream << llvm::formatv("Invalid log channel '{0}'.\n", channel); + return false; + } + if (!iter->second.Dump(output_stream)) { + error_stream << llvm::formatv( + "log channel '{0}' does not support dumping.\n", channel); + return false; + } + return true; +} + bool Log::ListChannelCategories(llvm::StringRef channel, llvm::raw_ostream &stream) { auto ch = g_channel_map->find(channel); @@ -318,20 +346,10 @@ void Log::WriteHeader(llvm::raw_ostream &OS, llvm::StringRef file, void Log::WriteMessage(const std::string &message) { // Make a copy of our stream shared pointer in case someone disables our log // while we are logging and releases the stream - auto stream_sp = GetStream(); - if (!stream_sp) + auto handler_sp = GetHandler(); + if (!handler_sp) return; - - Flags options = GetOptions(); - if (options.Test(LLDB_LOG_OPTION_THREADSAFE)) { - static std::recursive_mutex g_LogThreadedMutex; - std::lock_guard<std::recursive_mutex> guard(g_LogThreadedMutex); - *stream_sp << message; - stream_sp->flush(); - } else { - *stream_sp << message; - stream_sp->flush(); - } + handler_sp->Emit(message); } void Log::Format(llvm::StringRef file, llvm::StringRef function, @@ -342,3 +360,66 @@ void Log::Format(llvm::StringRef file, llvm::StringRef function, message << payload << "\n"; WriteMessage(message.str()); } + +StreamLogHandler::StreamLogHandler(int fd, bool should_close, + size_t buffer_size) + : m_stream(fd, should_close, buffer_size == 0) { + if (buffer_size > 0) + m_stream.SetBufferSize(buffer_size); +} + +StreamLogHandler::~StreamLogHandler() { Flush(); } + +void StreamLogHandler::Flush() { + std::lock_guard<std::mutex> guard(m_mutex); + m_stream.flush(); +} + +void StreamLogHandler::Emit(llvm::StringRef message) { + if (m_stream.GetBufferSize() > 0) { + std::lock_guard<std::mutex> guard(m_mutex); + m_stream << message; + } else { + m_stream << message; + } +} + +CallbackLogHandler::CallbackLogHandler(lldb::LogOutputCallback callback, + void *baton) + : m_callback(callback), m_baton(baton) {} + +void CallbackLogHandler::Emit(llvm::StringRef message) { + m_callback(message.data(), m_baton); +} + +RotatingLogHandler::RotatingLogHandler(size_t size) + : m_messages(std::make_unique<std::string[]>(size)), m_size(size) {} + +void RotatingLogHandler::Emit(llvm::StringRef message) { + std::lock_guard<std::mutex> guard(m_mutex); + ++m_total_count; + const size_t index = m_next_index; + m_next_index = NormalizeIndex(index + 1); + m_messages[index] = message.str(); +} + +size_t RotatingLogHandler::NormalizeIndex(size_t i) const { return i % m_size; } + +size_t RotatingLogHandler::GetNumMessages() const { + return m_total_count < m_size ? m_total_count : m_size; +} + +size_t RotatingLogHandler::GetFirstMessageIndex() const { + return m_total_count < m_size ? 0 : m_next_index; +} + +void RotatingLogHandler::Dump(llvm::raw_ostream &stream) const { + std::lock_guard<std::mutex> guard(m_mutex); + const size_t start_idx = GetFirstMessageIndex(); + const size_t stop_idx = start_idx + GetNumMessages(); + for (size_t i = start_idx; i < stop_idx; ++i) { + const size_t idx = NormalizeIndex(i); + stream << m_messages[idx]; + } + stream.flush(); +} diff --git a/contrib/llvm-project/lldb/source/Utility/ProcessInfo.cpp b/contrib/llvm-project/lldb/source/Utility/ProcessInfo.cpp index c9759bbe513e..3b094294ffaa 100644 --- a/contrib/llvm-project/lldb/source/Utility/ProcessInfo.cpp +++ b/contrib/llvm-project/lldb/source/Utility/ProcessInfo.cpp @@ -26,8 +26,8 @@ ProcessInfo::ProcessInfo() ProcessInfo::ProcessInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) - : m_executable(name), m_arguments(), m_environment(), m_uid(UINT32_MAX), - m_gid(UINT32_MAX), m_arch(arch), m_pid(pid) {} + : m_executable(name), m_arguments(), m_environment(), m_arch(arch), + m_pid(pid) {} void ProcessInfo::Clear() { m_executable.Clear(); @@ -144,19 +144,19 @@ void ProcessInstanceInfo::Dump(Stream &s, UserIDResolver &resolver) const { if (UserIDIsValid()) { s.Format(" uid = {0,-5} ({1})\n", GetUserID(), - resolver.GetUserName(GetUserID()).getValueOr("")); + resolver.GetUserName(GetUserID()).value_or("")); } if (GroupIDIsValid()) { s.Format(" gid = {0,-5} ({1})\n", GetGroupID(), - resolver.GetGroupName(GetGroupID()).getValueOr("")); + resolver.GetGroupName(GetGroupID()).value_or("")); } if (EffectiveUserIDIsValid()) { s.Format(" euid = {0,-5} ({1})\n", GetEffectiveUserID(), - resolver.GetUserName(GetEffectiveUserID()).getValueOr("")); + resolver.GetUserName(GetEffectiveUserID()).value_or("")); } if (EffectiveGroupIDIsValid()) { s.Format(" egid = {0,-5} ({1})\n", GetEffectiveGroupID(), - resolver.GetGroupName(GetEffectiveGroupID()).getValueOr("")); + resolver.GetGroupName(GetEffectiveGroupID()).value_or("")); } } diff --git a/contrib/llvm-project/lldb/source/Utility/Reproducer.cpp b/contrib/llvm-project/lldb/source/Utility/Reproducer.cpp index 1e71dba472ed..3641c933c38a 100644 --- a/contrib/llvm-project/lldb/source/Utility/Reproducer.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Reproducer.cpp @@ -136,7 +136,6 @@ Generator::~Generator() { if (!m_done) { if (m_auto_generate) { Keep(); - llvm::cantFail(Finalize(GetRoot())); } else { Discard(); } @@ -229,149 +228,3 @@ bool Loader::HasFile(StringRef file) { auto it = std::lower_bound(m_files.begin(), m_files.end(), file.str()); return (it != m_files.end()) && (*it == file); } - -void Verifier::Verify( - llvm::function_ref<void(llvm::StringRef)> error_callback, - llvm::function_ref<void(llvm::StringRef)> warning_callback, - llvm::function_ref<void(llvm::StringRef)> note_callack) const { - if (!m_loader) { - error_callback("invalid loader"); - return; - } - - FileSpec vfs_mapping = m_loader->GetFile<FileProvider::Info>(); - ErrorOr<std::unique_ptr<MemoryBuffer>> buffer = - vfs::getRealFileSystem()->getBufferForFile(vfs_mapping.GetPath()); - if (!buffer) { - error_callback("unable to read files: " + buffer.getError().message()); - return; - } - - IntrusiveRefCntPtr<vfs::FileSystem> vfs = vfs::getVFSFromYAML( - std::move(buffer.get()), nullptr, vfs_mapping.GetPath()); - if (!vfs) { - error_callback("unable to initialize the virtual file system"); - return; - } - - auto &redirecting_vfs = static_cast<vfs::RedirectingFileSystem &>(*vfs); - redirecting_vfs.setFallthrough(false); - - { - llvm::Expected<std::string> working_dir = - GetDirectoryFrom<WorkingDirectoryProvider>(m_loader); - if (working_dir) { - if (!vfs->exists(*working_dir)) - warning_callback("working directory '" + *working_dir + "' not in VFS"); - vfs->setCurrentWorkingDirectory(*working_dir); - } else { - warning_callback("no working directory in reproducer: " + - toString(working_dir.takeError())); - } - } - - { - llvm::Expected<std::string> home_dir = - GetDirectoryFrom<HomeDirectoryProvider>(m_loader); - if (home_dir) { - if (!vfs->exists(*home_dir)) - warning_callback("home directory '" + *home_dir + "' not in VFS"); - } else { - warning_callback("no home directory in reproducer: " + - toString(home_dir.takeError())); - } - } - - { - Expected<std::string> symbol_files = - m_loader->LoadBuffer<SymbolFileProvider>(); - if (symbol_files) { - std::vector<SymbolFileProvider::Entry> entries; - llvm::yaml::Input yin(*symbol_files); - yin >> entries; - for (const auto &entry : entries) { - if (!entry.module_path.empty() && !vfs->exists(entry.module_path)) { - warning_callback("'" + entry.module_path + "': module path for " + - entry.uuid + " not in VFS"); - } - if (!entry.symbol_path.empty() && !vfs->exists(entry.symbol_path)) { - warning_callback("'" + entry.symbol_path + "': symbol path for " + - entry.uuid + " not in VFS"); - } - } - } else { - llvm::consumeError(symbol_files.takeError()); - } - } - - // Missing files in the VFS are notes rather than warnings. Because the VFS - // is a snapshot, temporary files could have been removed between when they - // were recorded and when the reproducer was generated. - std::vector<llvm::StringRef> roots = redirecting_vfs.getRoots(); - for (llvm::StringRef root : roots) { - std::error_code ec; - vfs::recursive_directory_iterator iter(*vfs, root, ec); - vfs::recursive_directory_iterator end; - for (; iter != end && !ec; iter.increment(ec)) { - ErrorOr<vfs::Status> status = vfs->status(iter->path()); - if (!status) - note_callack("'" + iter->path().str() + - "': " + status.getError().message()); - } - } -} - -static llvm::Error addPaths(StringRef path, - function_ref<void(StringRef)> callback) { - auto buffer = llvm::MemoryBuffer::getFile(path); - if (!buffer) - return errorCodeToError(buffer.getError()); - - SmallVector<StringRef, 0> paths; - (*buffer)->getBuffer().split(paths, '\0'); - for (StringRef p : paths) { - if (!p.empty() && llvm::sys::fs::exists(p)) - callback(p); - } - - return errorCodeToError(llvm::sys::fs::remove(path)); -} - -llvm::Error repro::Finalize(Loader *loader) { - if (!loader) - return make_error<StringError>("invalid loader", - llvm::inconvertibleErrorCode()); - - FileSpec reproducer_root = loader->GetRoot(); - std::string files_path = - reproducer_root.CopyByAppendingPathComponent("files.txt").GetPath(); - std::string dirs_path = - reproducer_root.CopyByAppendingPathComponent("dirs.txt").GetPath(); - - FileCollector collector( - reproducer_root.CopyByAppendingPathComponent("root").GetPath(), - reproducer_root.GetPath()); - - if (Error e = - addPaths(files_path, [&](StringRef p) { collector.addFile(p); })) - return e; - - if (Error e = - addPaths(dirs_path, [&](StringRef p) { collector.addDirectory(p); })) - return e; - - FileSpec mapping = - reproducer_root.CopyByAppendingPathComponent(FileProvider::Info::file); - if (auto ec = collector.copyFiles(/*StopOnError=*/false)) - return errorCodeToError(ec); - collector.writeMapping(mapping.GetPath()); - - return llvm::Error::success(); -} - -llvm::Error repro::Finalize(const FileSpec &root) { - Loader loader(root); - if (Error e = loader.LoadIndex()) - return e; - return Finalize(&loader); -} diff --git a/contrib/llvm-project/lldb/source/Utility/ReproducerProvider.cpp b/contrib/llvm-project/lldb/source/Utility/ReproducerProvider.cpp index 5145819b717c..0d1581abda64 100644 --- a/contrib/llvm-project/lldb/source/Utility/ReproducerProvider.cpp +++ b/contrib/llvm-project/lldb/source/Utility/ReproducerProvider.cpp @@ -45,40 +45,6 @@ void VersionProvider::Keep() { os << m_version << "\n"; } -FlushingFileCollector::FlushingFileCollector(llvm::StringRef files_path, - llvm::StringRef dirs_path, - std::error_code &ec) { - auto clear = llvm::make_scope_exit([this]() { - m_files_os.reset(); - m_dirs_os.reset(); - }); - m_files_os.emplace(files_path, ec, llvm::sys::fs::OF_Append); - if (ec) - return; - m_dirs_os.emplace(dirs_path, ec, llvm::sys::fs::OF_Append); - if (ec) - return; - clear.release(); -} - -void FlushingFileCollector::addFileImpl(StringRef file) { - if (m_files_os) { - *m_files_os << file << '\0'; - m_files_os->flush(); - } -} - -llvm::vfs::directory_iterator -FlushingFileCollector::addDirectoryImpl(const Twine &dir, - IntrusiveRefCntPtr<vfs::FileSystem> vfs, - std::error_code &dir_ec) { - if (m_dirs_os) { - *m_dirs_os << dir << '\0'; - m_dirs_os->flush(); - } - return vfs->dir_begin(dir, dir_ec); -} - void FileProvider::RecordInterestingDirectory(const llvm::Twine &dir) { if (m_collector) m_collector->addFile(dir); @@ -89,6 +55,13 @@ void FileProvider::RecordInterestingDirectoryRecursive(const llvm::Twine &dir) { m_collector->addDirectory(dir); } +void FileProvider::Keep() { + if (m_collector) { + FileSpec file = GetRoot().CopyByAppendingPathComponent(Info::file); + m_collector->writeMapping(file.GetPath()); + } +} + llvm::Expected<std::unique_ptr<ProcessInfoRecorder>> ProcessInfoRecorder::Create(const FileSpec &filename) { std::error_code ec; diff --git a/contrib/llvm-project/lldb/source/Utility/SelectHelper.cpp b/contrib/llvm-project/lldb/source/Utility/SelectHelper.cpp index 059f810e2194..a25bdfdaee8e 100644 --- a/contrib/llvm-project/lldb/source/Utility/SelectHelper.cpp +++ b/contrib/llvm-project/lldb/source/Utility/SelectHelper.cpp @@ -84,7 +84,7 @@ bool SelectHelper::FDIsSetError(lldb::socket_t fd) const { static void updateMaxFd(llvm::Optional<lldb::socket_t> &vold, lldb::socket_t vnew) { - if (!vold.hasValue()) + if (!vold) vold = vnew; else vold = std::max(*vold, vnew); @@ -123,7 +123,7 @@ lldb_private::Status SelectHelper::Select() { updateMaxFd(max_fd, fd); } - if (!max_fd.hasValue()) { + if (!max_fd) { error.SetErrorString("no valid file descriptors"); return error; } @@ -161,15 +161,15 @@ lldb_private::Status SelectHelper::Select() { fd_set write_fdset; fd_set error_fdset; - if (max_read_fd.hasValue()) { + if (max_read_fd) { FD_ZERO(&read_fdset); read_fdset_ptr = &read_fdset; } - if (max_write_fd.hasValue()) { + if (max_write_fd) { FD_ZERO(&write_fdset); write_fdset_ptr = &write_fdset; } - if (max_error_fd.hasValue()) { + if (max_error_fd) { FD_ZERO(&error_fdset); error_fdset_ptr = &error_fdset; } @@ -195,7 +195,7 @@ lldb_private::Status SelectHelper::Select() { while (true) { using namespace std::chrono; // Setup out relative timeout based on the end time if we have one - if (m_end_time.hasValue()) { + if (m_end_time) { tv_ptr = &tv; const auto remaining_dur = duration_cast<microseconds>( m_end_time.getValue() - steady_clock::now()); diff --git a/contrib/llvm-project/lldb/source/Utility/Status.cpp b/contrib/llvm-project/lldb/source/Utility/Status.cpp index e6d381421f28..4498961d83e7 100644 --- a/contrib/llvm-project/lldb/source/Utility/Status.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Status.cpp @@ -51,8 +51,7 @@ Status::Status(std::error_code EC) : eErrorTypeGeneric), m_string(EC.message()) {} -Status::Status(const char *format, ...) - : m_code(0), m_type(eErrorTypeInvalid), m_string() { +Status::Status(const char *format, ...) : m_string() { va_list args; va_start(args, format); SetErrorToGenericError(); diff --git a/contrib/llvm-project/lldb/source/Utility/Stream.cpp b/contrib/llvm-project/lldb/source/Utility/Stream.cpp index a1e2de9da4d9..af28a49a1f0c 100644 --- a/contrib/llvm-project/lldb/source/Utility/Stream.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Stream.cpp @@ -25,7 +25,7 @@ using namespace lldb_private; Stream::Stream(uint32_t flags, uint32_t addr_size, ByteOrder byte_order, bool colors) : m_flags(flags), m_addr_size(addr_size), m_byte_order(byte_order), - m_indent_level(0), m_forwarder(*this, colors) {} + m_forwarder(*this, colors) {} Stream::Stream(bool colors) : m_flags(0), m_byte_order(endian::InlHostByteOrder()), @@ -344,8 +344,8 @@ size_t Stream::PutRawBytes(const void *s, size_t src_len, for (size_t i = 0; i < src_len; ++i) _PutHex8(src[i], false); } else { - for (size_t i = src_len - 1; i < src_len; --i) - _PutHex8(src[i], false); + for (size_t i = src_len; i > 0; --i) + _PutHex8(src[i - 1], false); } if (!binary_was_set) m_flags.Clear(eBinary); @@ -357,6 +357,7 @@ size_t Stream::PutBytesAsRawHex8(const void *s, size_t src_len, ByteOrder src_byte_order, ByteOrder dst_byte_order) { ByteDelta delta(*this); + if (src_byte_order == eByteOrderInvalid) src_byte_order = m_byte_order; @@ -370,8 +371,8 @@ size_t Stream::PutBytesAsRawHex8(const void *s, size_t src_len, for (size_t i = 0; i < src_len; ++i) _PutHex8(src[i], false); } else { - for (size_t i = src_len - 1; i < src_len; --i) - _PutHex8(src[i], false); + for (size_t i = src_len; i > 0; --i) + _PutHex8(src[i - 1], false); } if (binary_is_set) m_flags.Set(eBinary); diff --git a/contrib/llvm-project/lldb/source/Utility/StreamCallback.cpp b/contrib/llvm-project/lldb/source/Utility/StreamCallback.cpp deleted file mode 100644 index c10f678d7a28..000000000000 --- a/contrib/llvm-project/lldb/source/Utility/StreamCallback.cpp +++ /dev/null @@ -1,22 +0,0 @@ -//===-- StreamCallback.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/Utility/StreamCallback.h" - -#include <string> - -using namespace lldb_private; - -StreamCallback::StreamCallback(lldb::LogOutputCallback callback, void *baton) - : llvm::raw_ostream(true), m_callback(callback), m_baton(baton) {} - -void StreamCallback::write_impl(const char *Ptr, size_t Size) { - m_callback(std::string(Ptr, Size).c_str(), m_baton); -} - -uint64_t StreamCallback::current_pos() const { return 0; } diff --git a/contrib/llvm-project/lldb/source/Utility/StringExtractor.cpp b/contrib/llvm-project/lldb/source/Utility/StringExtractor.cpp index d082c86f8463..c7e4ac794284 100644 --- a/contrib/llvm-project/lldb/source/Utility/StringExtractor.cpp +++ b/contrib/llvm-project/lldb/source/Utility/StringExtractor.cpp @@ -28,13 +28,11 @@ static inline int xdigit_to_sint(char ch) { // StringExtractor constructor StringExtractor::StringExtractor() : m_packet() {} -StringExtractor::StringExtractor(llvm::StringRef packet_str) - : m_packet(), m_index(0) { +StringExtractor::StringExtractor(llvm::StringRef packet_str) : m_packet() { m_packet.assign(packet_str.begin(), packet_str.end()); } -StringExtractor::StringExtractor(const char *packet_cstr) - : m_packet(), m_index(0) { +StringExtractor::StringExtractor(const char *packet_cstr) : m_packet() { if (packet_cstr) m_packet.assign(packet_cstr); } diff --git a/contrib/llvm-project/lldb/source/Utility/StringExtractorGDBRemote.cpp b/contrib/llvm-project/lldb/source/Utility/StringExtractorGDBRemote.cpp index d6bbf7171916..07954408f6d0 100644 --- a/contrib/llvm-project/lldb/source/Utility/StringExtractorGDBRemote.cpp +++ b/contrib/llvm-project/lldb/source/Utility/StringExtractorGDBRemote.cpp @@ -126,6 +126,8 @@ StringExtractorGDBRemote::GetServerPacketType() const { return eServerPacketType_QSetWorkingDir; if (PACKET_STARTS_WITH("QSetLogging:")) return eServerPacketType_QSetLogging; + if (PACKET_STARTS_WITH("QSetIgnoredExceptions")) + return eServerPacketType_QSetIgnoredExceptions; if (PACKET_STARTS_WITH("QSetMaxPacketSize:")) return eServerPacketType_QSetMaxPacketSize; if (PACKET_STARTS_WITH("QSetMaxPayloadSize:")) @@ -148,6 +150,11 @@ StringExtractorGDBRemote::GetServerPacketType() const { return eServerPacketType_QMemTags; break; + case 'N': + if (PACKET_STARTS_WITH("QNonStop:")) + return eServerPacketType_QNonStop; + break; + case 'R': if (PACKET_STARTS_WITH("QRestoreRegisterState:")) return eServerPacketType_QRestoreRegisterState; @@ -365,8 +372,16 @@ StringExtractorGDBRemote::GetServerPacketType() const { return eServerPacketType_vCont; if (PACKET_MATCHES("vCont?")) return eServerPacketType_vCont_actions; + if (PACKET_STARTS_WITH("vKill;")) + return eServerPacketType_vKill; if (PACKET_STARTS_WITH("vRun;")) return eServerPacketType_vRun; + if (PACKET_MATCHES("vStopped")) + return eServerPacketType_vStopped; + if (PACKET_MATCHES("vCtrlC")) + return eServerPacketType_vCtrlC; + break; + } break; case '_': @@ -624,7 +639,7 @@ 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::pid_t pid = LLDB_INVALID_PROCESS_ID; lldb::tid_t tid; if (view.consume_front("p")) { @@ -660,5 +675,5 @@ StringExtractorGDBRemote::GetPidTid(lldb::pid_t default_pid) { // update m_index m_index += initial_length - view.size(); - return {{pid, tid}}; + return {{pid != LLDB_INVALID_PROCESS_ID ? pid : default_pid, tid}}; } diff --git a/contrib/llvm-project/lldb/source/Utility/TraceGDBRemotePackets.cpp b/contrib/llvm-project/lldb/source/Utility/TraceGDBRemotePackets.cpp index 5c1326a5f353..9879b7b2cb79 100644 --- a/contrib/llvm-project/lldb/source/Utility/TraceGDBRemotePackets.cpp +++ b/contrib/llvm-project/lldb/source/Utility/TraceGDBRemotePackets.cpp @@ -48,7 +48,7 @@ TraceStopRequest::TraceStopRequest(llvm::StringRef type, : type(type) { tids.emplace(); for (lldb::tid_t tid : tids_) - tids->push_back(static_cast<int64_t>(tid)); + tids->push_back(tid); } bool TraceStopRequest::IsProcessTracing() const { return !(bool)tids; } @@ -87,24 +87,48 @@ json::Value toJSON(const TraceBinaryData &packet) { 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); + o.map("binaryData", packet.binary_data); } json::Value toJSON(const TraceThreadState &packet) { return json::Value( - Object{{"tid", packet.tid}, {"binaryData", packet.binaryData}}); + Object{{"tid", packet.tid}, {"binaryData", packet.binary_data}}); } 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); + return o && o.map("tracedThreads", packet.traced_threads) && + o.map("processBinaryData", packet.process_binary_data) && + o.map("cpus", packet.cpus) && o.map("warnings", packet.warnings); } json::Value toJSON(const TraceGetStateResponse &packet) { - return json::Value(Object{{"tracedThreads", packet.tracedThreads}, - {"processBinaryData", packet.processBinaryData}}); + return json::Value(Object{{"tracedThreads", packet.traced_threads}, + {"processBinaryData", packet.process_binary_data}, + {"cpus", packet.cpus}, + {"warnings", packet.warnings}}); +} + +void TraceGetStateResponse::AddWarning(StringRef warning) { + if (!warnings) + warnings.emplace(); + warnings->push_back(warning.data()); +} + +bool fromJSON(const json::Value &value, TraceCpuState &packet, + json::Path path) { + ObjectMapper o(value, path); + uint64_t cpu_id; + if (!(o && o.map("id", cpu_id) && o.map("binaryData", packet.binary_data))) + return false; + packet.id = static_cast<lldb::cpu_id_t>(cpu_id); + return true; +} + +json::Value toJSON(const TraceCpuState &packet) { + return json::Value( + Object{{"id", packet.id}, {"binaryData", packet.binary_data}}); } /// \} @@ -113,17 +137,21 @@ json::Value toJSON(const TraceGetStateResponse &packet) { 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}}); + {"cpuId", packet.cpu_id}}); } 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); + Optional<uint64_t> cpu_id; + if (!(o && o.map("type", packet.type) && o.map("kind", packet.kind) && + o.map("tid", packet.tid) && o.map("cpuId", cpu_id))) + return false; + + if (cpu_id) + packet.cpu_id = static_cast<lldb::cpu_id_t>(*cpu_id); + return true; } /// \} diff --git a/contrib/llvm-project/lldb/source/Utility/TraceIntelPTGDBRemotePackets.cpp b/contrib/llvm-project/lldb/source/Utility/TraceIntelPTGDBRemotePackets.cpp index dbb93d8d1c5c..1ad74cacc4c3 100644 --- a/contrib/llvm-project/lldb/source/Utility/TraceIntelPTGDBRemotePackets.cpp +++ b/contrib/llvm-project/lldb/source/Utility/TraceIntelPTGDBRemotePackets.cpp @@ -13,33 +13,108 @@ using namespace llvm::json; namespace lldb_private { +const char *IntelPTDataKinds::kProcFsCpuInfo = "procfsCpuInfo"; +const char *IntelPTDataKinds::kIptTrace = "iptTrace"; +const char *IntelPTDataKinds::kPerfContextSwitchTrace = + "perfContextSwitchTrace"; + +bool TraceIntelPTStartRequest::IsPerCpuTracing() const { + return per_cpu_tracing.value_or(false); +} + +json::Value toJSON(const JSONUINT64 &uint64, bool hex) { + if (hex) + return json::Value(formatv("{0:x+}", uint64.value)); + else + return json::Value(formatv("{0}", uint64.value)); +} + +bool fromJSON(const json::Value &value, JSONUINT64 &uint64, Path path) { + if (Optional<uint64_t> val = value.getAsUINT64()) { + uint64.value = *val; + return true; + } else if (Optional<StringRef> val = value.getAsString()) { + if (!val->getAsInteger(/*radix=*/0, uint64.value)) + return true; + path.report("invalid string number"); + } + path.report("invalid number or string number"); + return false; +} + 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"); + if (!(o && fromJSON(value, (TraceStartRequest &)packet, path) && + o.map("enableTsc", packet.enable_tsc) && + o.map("psbPeriod", packet.psb_period) && + o.map("iptTraceSize", packet.ipt_trace_size))) return false; + + if (packet.IsProcessTracing()) { + if (!o.map("processBufferSizeLimit", packet.process_buffer_size_limit) || + !o.map("perCpuTracing", packet.per_cpu_tracing)) + 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); + json::Object &obj = *base.getAsObject(); + obj.try_emplace("iptTraceSize", packet.ipt_trace_size); + obj.try_emplace("processBufferSizeLimit", packet.process_buffer_size_limit); + obj.try_emplace("psbPeriod", packet.psb_period); + obj.try_emplace("enableTsc", packet.enable_tsc); + obj.try_emplace("perCpuTracing", packet.per_cpu_tracing); + return base; +} + +uint64_t LinuxPerfZeroTscConversion::ToNanos(uint64_t tsc) const { + uint64_t quot = tsc >> time_shift; + uint64_t rem_flag = (((uint64_t)1 << time_shift) - 1); + uint64_t rem = tsc & rem_flag; + return time_zero.value + quot * time_mult + ((rem * time_mult) >> time_shift); +} + +uint64_t LinuxPerfZeroTscConversion::ToTSC(uint64_t nanos) const { + uint64_t time = nanos - time_zero.value; + uint64_t quot = time / time_mult; + uint64_t rem = time % time_mult; + return (quot << time_shift) + (rem << time_shift) / time_mult; +} + +json::Value toJSON(const LinuxPerfZeroTscConversion &packet) { + return json::Value(json::Object{ + {"timeMult", packet.time_mult}, + {"timeShift", packet.time_shift}, + {"timeZero", toJSON(packet.time_zero, /*hex=*/false)}, + }); +} + +bool fromJSON(const json::Value &value, LinuxPerfZeroTscConversion &packet, + json::Path path) { + ObjectMapper o(value, path); + uint64_t time_mult, time_shift; + if (!(o && o.map("timeMult", time_mult) && o.map("timeShift", time_shift) && + o.map("timeZero", packet.time_zero))) + return false; + packet.time_mult = time_mult; + packet.time_shift = time_shift; + return true; +} + +bool fromJSON(const json::Value &value, TraceIntelPTGetStateResponse &packet, + json::Path path) { + ObjectMapper o(value, path); + return o && fromJSON(value, (TraceGetStateResponse &)packet, path) && + o.map("tscPerfZeroConversion", packet.tsc_perf_zero_conversion); +} + +json::Value toJSON(const TraceIntelPTGetStateResponse &packet) { + json::Value base = toJSON((const TraceGetStateResponse &)packet); + base.getAsObject()->insert( + {"tscPerfZeroConversion", packet.tsc_perf_zero_conversion}); return base; } diff --git a/contrib/llvm-project/lldb/source/Utility/UriParser.cpp b/contrib/llvm-project/lldb/source/Utility/UriParser.cpp index cfb9009898d2..b7771d57aefd 100644 --- a/contrib/llvm-project/lldb/source/Utility/UriParser.cpp +++ b/contrib/llvm-project/lldb/source/Utility/UriParser.cpp @@ -20,7 +20,7 @@ llvm::raw_ostream &lldb_private::operator<<(llvm::raw_ostream &OS, const URI &U) { OS << U.scheme << "://[" << U.hostname << ']'; if (U.port) - OS << ':' << U.port.getValue(); + OS << ':' << *U.port; return OS << U.path; } diff --git a/contrib/llvm-project/lldb/source/Utility/XcodeSDK.cpp b/contrib/llvm-project/lldb/source/Utility/XcodeSDK.cpp index 4f64042e3643..371b86437fa2 100644 --- a/contrib/llvm-project/lldb/source/Utility/XcodeSDK.cpp +++ b/contrib/llvm-project/lldb/source/Utility/XcodeSDK.cpp @@ -54,10 +54,7 @@ XcodeSDK::XcodeSDK(XcodeSDK::Info info) : m_name(GetName(info.type).str()) { } } -XcodeSDK &XcodeSDK::operator=(const XcodeSDK &other) { - m_name = other.m_name; - return *this; -} +XcodeSDK &XcodeSDK::operator=(const XcodeSDK &other) = default; bool XcodeSDK::operator==(const XcodeSDK &other) { return m_name == other.m_name; diff --git a/contrib/llvm-project/lldb/tools/driver/Driver.cpp b/contrib/llvm-project/lldb/tools/driver/Driver.cpp index 233e0dd977d3..16fa2f1393d5 100644 --- a/contrib/llvm-project/lldb/tools/driver/Driver.cpp +++ b/contrib/llvm-project/lldb/tools/driver/Driver.cpp @@ -86,6 +86,8 @@ static void reset_stdin_termios(); static bool g_old_stdin_termios_is_valid = false; static struct termios g_old_stdin_termios; +static bool disable_color(const raw_ostream &OS) { return false; } + static Driver *g_driver = nullptr; // In the Driver::MainLoop, we change the terminal settings. This function is @@ -186,6 +188,12 @@ SBError Driver::ProcessArgs(const opt::InputArgList &args, bool &exiting) { m_debugger.SkipLLDBInitFiles(false); m_debugger.SkipAppInitFiles(false); + if (args.hasArg(OPT_no_use_colors)) { + m_debugger.SetUseColor(false); + WithColor::setAutoDetectFunction(disable_color); + m_option_data.m_debug_mode = true; + } + if (args.hasArg(OPT_version)) { m_option_data.m_print_version = true; } @@ -227,11 +235,6 @@ SBError Driver::ProcessArgs(const opt::InputArgList &args, bool &exiting) { m_debugger.GetInstanceName()); } - if (args.hasArg(OPT_no_use_colors)) { - m_debugger.SetUseColor(false); - m_option_data.m_debug_mode = true; - } - if (auto *arg = args.getLastArg(OPT_file)) { auto arg_value = arg->getValue(); SBFileSpec file(arg_value); @@ -452,9 +455,14 @@ int Driver::MainLoop() { SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter(); - // Before we handle any options from the command line, we parse the - // REPL init file or the default file in the user's home directory. + // Process lldbinit files before handling any options from the command line. SBCommandReturnObject result; + sb_interpreter.SourceInitFileInGlobalDirectory(result); + if (m_option_data.m_debug_mode) { + result.PutError(m_debugger.GetErrorFile()); + result.PutOutput(m_debugger.GetOutputFile()); + } + sb_interpreter.SourceInitFileInHomeDirectory(result, m_option_data.m_repl); if (m_option_data.m_debug_mode) { result.PutError(m_debugger.GetErrorFile()); @@ -663,31 +671,30 @@ void sigint_handler(int signo) { _exit(signo); } -void sigtstp_handler(int signo) { +#ifndef _WIN32 +static void sigtstp_handler(int signo) { if (g_driver != nullptr) g_driver->GetDebugger().SaveInputTerminalState(); + // Unblock the signal and remove our handler. + sigset_t set; + sigemptyset(&set); + sigaddset(&set, signo); + pthread_sigmask(SIG_UNBLOCK, &set, nullptr); signal(signo, SIG_DFL); - kill(getpid(), signo); + + // Now re-raise the signal. We will immediately suspend... + raise(signo); + // ... and resume after a SIGCONT. + + // Now undo the modifications. + pthread_sigmask(SIG_BLOCK, &set, nullptr); signal(signo, sigtstp_handler); -} -void sigcont_handler(int signo) { if (g_driver != nullptr) g_driver->GetDebugger().RestoreInputTerminalState(); - - signal(signo, SIG_DFL); - kill(getpid(), signo); - signal(signo, sigcont_handler); -} - -void reproducer_handler(void *finalize_cmd) { - if (SBReproducer::Generate()) { - int result = std::system(static_cast<const char *>(finalize_cmd)); - (void)result; - fflush(stdout); - } } +#endif static void printHelp(LLDBOptTable &table, llvm::StringRef tool_name) { std::string usage_str = tool_name.str() + " [options]"; @@ -822,11 +829,10 @@ int main(int argc, char const *argv[]) { SBHostOS::ThreadCreated("<lldb.driver.main-thread>"); signal(SIGINT, sigint_handler); -#if !defined(_MSC_VER) +#if !defined(_WIN32) signal(SIGPIPE, SIG_IGN); signal(SIGWINCH, sigwinch_handler); signal(SIGTSTP, sigtstp_handler); - signal(SIGCONT, sigcont_handler); #endif int exit_code = 0; diff --git a/contrib/llvm-project/lldb/tools/lldb-server/LLDBServerUtilities.cpp b/contrib/llvm-project/lldb/tools/lldb-server/LLDBServerUtilities.cpp index a427af4800f7..c3a8df19e969 100644 --- a/contrib/llvm-project/lldb/tools/lldb-server/LLDBServerUtilities.cpp +++ b/contrib/llvm-project/lldb/tools/lldb-server/LLDBServerUtilities.cpp @@ -18,21 +18,37 @@ using namespace lldb; using namespace lldb_private::lldb_server; +using namespace lldb_private; using namespace llvm; -static std::shared_ptr<raw_ostream> GetLogStream(StringRef log_file) { +class TestLogHandler : public LogHandler { +public: + TestLogHandler(std::shared_ptr<llvm::raw_ostream> stream_sp) + : m_stream_sp(stream_sp) {} + + void Emit(llvm::StringRef message) override { + (*m_stream_sp) << message; + m_stream_sp->flush(); + } + +private: + std::shared_ptr<raw_ostream> m_stream_sp; +}; + +static std::shared_ptr<TestLogHandler> 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>( + auto stream_sp = std::make_shared<raw_fd_ostream>( log_file, EC, sys::fs::OF_TextWithCRLF | sys::fs::OF_Append); if (!EC) - return stream_sp; + return std::make_shared<TestLogHandler>(stream_sp); errs() << llvm::formatv( "Failed to open log file `{0}`: {1}\nWill log to stderr instead.\n", log_file, EC.message()); } // No need to delete the stderr stream. - return std::shared_ptr<raw_ostream>(&errs(), [](raw_ostream *) {}); + return std::make_shared<TestLogHandler>( + std::shared_ptr<raw_ostream>(&errs(), [](raw_ostream *) {})); } bool LLDBServerUtilities::SetupLogging(const std::string &log_file, 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 7648a0bb668d..eca66cfc4967 100644 --- a/contrib/llvm-project/lldb/tools/lldb-server/lldb-gdbserver.cpp +++ b/contrib/llvm-project/lldb/tools/lldb-server/lldb-gdbserver.cpp @@ -27,7 +27,7 @@ #include "lldb/Host/Socket.h" #include "lldb/Host/common/NativeProcessProtocol.h" #include "lldb/Target/Process.h" -#include "lldb/Utility/Logging.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Status.h" #include "llvm/ADT/StringRef.h" #include "llvm/Option/ArgList.h" @@ -95,7 +95,7 @@ static int g_sighup_received_count = 0; static void sighup_handler(MainLoopBase &mainloop) { ++g_sighup_received_count; - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "lldb-server:%s swallowing SIGHUP (receive count=%d)", __FUNCTION__, g_sighup_received_count); 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 9e07f4c8debd..1a969eec8db8 100644 --- a/contrib/llvm-project/lldb/tools/lldb-server/lldb-platform.cpp +++ b/contrib/llvm-project/lldb/tools/lldb-server/lldb-platform.cpp @@ -77,10 +77,9 @@ static void signal_handler(int signo) { case SIGHUP: // Use SIGINT first, if that does not work, use SIGHUP as a last resort. // And we should not call exit() here because it results in the global - // destructors - // to be invoked and wreaking havoc on the threads still running. - Host::SystemLog(Host::eSystemLogWarning, - "SIGHUP received, exiting lldb-server...\n"); + // destructors to be invoked and wreaking havoc on the threads still + // running. + llvm::errs() << "SIGHUP received, exiting lldb-server...\n"; abort(); break; } |